/** @file | |
The definitions related to IPsec protocol implementation. | |
Copyright (c) 2009 - 2011, 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. | |
**/ | |
#ifndef _IP_SEC_IMPL_H_ | |
#define _IP_SEC_IMPL_H_ | |
#include <Uefi.h> | |
#include <Library/UefiLib.h> | |
#include <Library/NetLib.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <Protocol/IpSec.h> | |
#include <Protocol/IpSecConfig.h> | |
#include <Protocol/Dpc.h> | |
#include <Protocol/ComponentName.h> | |
#include <Protocol/ComponentName2.h> | |
typedef struct _IPSEC_PRIVATE_DATA IPSEC_PRIVATE_DATA; | |
typedef struct _IPSEC_SPD_ENTRY IPSEC_SPD_ENTRY; | |
typedef struct _IPSEC_PAD_ENTRY IPSEC_PAD_ENTRY; | |
typedef struct _IPSEC_SPD_DATA IPSEC_SPD_DATA; | |
#define IPSEC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I', 'P', 'S', 'E') | |
#define IPSEC_PRIVATE_DATA_FROM_IPSEC(a) CR (a, IPSEC_PRIVATE_DATA, IpSec, IPSEC_PRIVATE_DATA_SIGNATURE) | |
#define IPSEC_PRIVATE_DATA_FROM_UDP4LIST(a) CR (a, IPSEC_PRIVATE_DATA, Udp4List, IPSEC_PRIVATE_DATA_SIGNATURE) | |
#define IPSEC_PRIVATE_DATA_FROM_UDP6LIST(a) CR (a, IPSEC_PRIVATE_DATA, Udp6List, IPSEC_PRIVATE_DATA_SIGNATURE) | |
#define IPSEC_UDP_SERVICE_FROM_LIST(a) BASE_CR (a, IKE_UDP_SERVICE, List) | |
#define IPSEC_SPD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_SPD_ENTRY, List) | |
#define IPSEC_SAD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_SAD_ENTRY, List) | |
#define IPSEC_PAD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_PAD_ENTRY, List) | |
#define IPSEC_SAD_ENTRY_FROM_SPD(a) BASE_CR (a, IPSEC_SAD_ENTRY, BySpd) | |
#define IPSEC_STATUS_DISABLED 0 | |
#define IPSEC_STATUS_ENABLED 1 | |
#define IPSEC_ESP_PROTOCOL 50 | |
#define IPSEC_AH_PROTOCOL 51 | |
#define IPSEC_DEFAULT_VARIABLE_SIZE 0x100 | |
// | |
// Internal Structure Definition | |
// | |
#pragma pack(1) | |
typedef struct _EFI_AH_HEADER { | |
UINT8 NextHeader; | |
UINT8 PayloadLen; | |
UINT16 Reserved; | |
UINT32 Spi; | |
UINT32 SequenceNumber; | |
} EFI_AH_HEADER; | |
typedef struct _EFI_ESP_HEADER { | |
UINT32 Spi; | |
UINT32 SequenceNumber; | |
} EFI_ESP_HEADER; | |
typedef struct _EFI_ESP_TAIL { | |
UINT8 PaddingLength; | |
UINT8 NextHeader; | |
} EFI_ESP_TAIL; | |
#pragma pack() | |
struct _IPSEC_SPD_DATA { | |
CHAR16 Name[100]; | |
UINT32 PackageFlag; | |
EFI_IPSEC_TRAFFIC_DIR TrafficDirection; | |
EFI_IPSEC_ACTION Action; | |
EFI_IPSEC_PROCESS_POLICY *ProcessingPolicy; | |
LIST_ENTRY Sas; | |
}; | |
struct _IPSEC_SPD_ENTRY { | |
EFI_IPSEC_SPD_SELECTOR *Selector; | |
IPSEC_SPD_DATA *Data; | |
LIST_ENTRY List; | |
}; | |
typedef struct _IPSEC_SAD_DATA { | |
EFI_IPSEC_MODE Mode; | |
UINT64 SequenceNumber; | |
UINT8 AntiReplayWindowSize; | |
UINT64 AntiReplayBitmap[4]; // bitmap for received packet | |
EFI_IPSEC_ALGO_INFO AlgoInfo; | |
EFI_IPSEC_SA_LIFETIME SaLifetime; | |
UINT32 PathMTU; | |
IPSEC_SPD_ENTRY *SpdEntry; | |
EFI_IPSEC_SPD_SELECTOR *SpdSelector; | |
BOOLEAN ESNEnabled; // Extended (64-bit) SN enabled | |
BOOLEAN ManualSet; | |
EFI_IP_ADDRESS TunnelDestAddress; | |
EFI_IP_ADDRESS TunnelSourceAddress; | |
} IPSEC_SAD_DATA; | |
typedef struct _IPSEC_SAD_ENTRY { | |
EFI_IPSEC_SA_ID *Id; | |
IPSEC_SAD_DATA *Data; | |
LIST_ENTRY List; | |
LIST_ENTRY BySpd; // Linked on IPSEC_SPD_DATA.Sas | |
} IPSEC_SAD_ENTRY; | |
struct _IPSEC_PAD_ENTRY { | |
EFI_IPSEC_PAD_ID *Id; | |
EFI_IPSEC_PAD_DATA *Data; | |
LIST_ENTRY List; | |
}; | |
typedef struct _IPSEC_RECYCLE_CONTEXT { | |
EFI_IPSEC_FRAGMENT_DATA *FragmentTable; | |
UINT8 *PayloadBuffer; | |
} IPSEC_RECYCLE_CONTEXT; | |
// | |
// Struct used to store the Hash and its data. | |
// | |
typedef struct { | |
UINTN DataSize; | |
UINT8 *Data; | |
} HASH_DATA_FRAGMENT; | |
struct _IPSEC_PRIVATE_DATA { | |
UINT32 Signature; | |
EFI_HANDLE Handle; // Virtual handle to install private prtocol | |
EFI_HANDLE ImageHandle; | |
EFI_IPSEC2_PROTOCOL IpSec; | |
EFI_IPSEC_CONFIG_PROTOCOL IpSecConfig; | |
BOOLEAN SetBySelf; | |
LIST_ENTRY Udp4List; | |
UINTN Udp4Num; | |
LIST_ENTRY Udp6List; | |
UINTN Udp6Num; | |
LIST_ENTRY Ikev1SessionList; | |
LIST_ENTRY Ikev1EstablishedList; | |
LIST_ENTRY Ikev2SessionList; | |
LIST_ENTRY Ikev2EstablishedList; | |
BOOLEAN IsIPsecDisabling; | |
}; | |
/** | |
This function processes the inbound traffic with IPsec. | |
It checks the received packet security property, trims the ESP/AH header, and then | |
returns without an IPsec protected IP Header and FragmentTable. | |
@param[in] IpVersion The version of IP. | |
@param[in, out] IpHead Points to IP header containing the ESP/AH header | |
to be trimed on input, and without ESP/AH header | |
on return. | |
@param[in, out] LastHead The Last Header in IP header on return. | |
@param[in, out] OptionsBuffer Pointer to the options buffer. | |
@param[in, out] OptionsLength Length of the options buffer. | |
@param[in, out] FragmentTable Pointer to a list of fragments in form of IPsec | |
protected on input, and without IPsec protected | |
on return. | |
@param[in, out] FragmentCount The number of fragments. | |
@param[out] SpdEntry Pointer to contain the address of SPD entry on return. | |
@param[out] RecycleEvent The event for recycling of resources. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_UNSUPPORTED The IPSEC protocol is not supported. | |
**/ | |
EFI_STATUS | |
IpSecProtectInboundPacket ( | |
IN UINT8 IpVersion, | |
IN OUT VOID *IpHead, | |
IN OUT UINT8 *LastHead, | |
IN OUT VOID **OptionsBuffer, | |
IN OUT UINT32 *OptionsLength, | |
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, | |
IN OUT UINT32 *FragmentCount, | |
OUT EFI_IPSEC_SPD_SELECTOR **SpdEntry, | |
OUT EFI_EVENT *RecycleEvent | |
); | |
/** | |
This fucntion processes the output traffic with IPsec. | |
It protected the sending packet by encrypting it payload and inserting ESP/AH header | |
in the orginal IP header, then return the IpHeader and IPsec protected Fragmentable. | |
@param[in] IpVersion The version of IP. | |
@param[in, out] IpHead Point to IP header containing the orginal IP header | |
to be processed on input, and inserted ESP/AH header | |
on return. | |
@param[in, out] LastHead The Last Header in IP header. | |
@param[in, out] OptionsBuffer Pointer to the options buffer. | |
@param[in, out] OptionsLength Length of the options buffer. | |
@param[in, out] FragmentTable Pointer to a list of fragments to be protected by | |
IPsec on input, and with IPsec protected | |
on return. | |
@param[in, out] FragmentCount Number of fragments. | |
@param[in] SadEntry Related SAD entry. | |
@param[out] RecycleEvent Event for recycling of resources. | |
@retval EFI_SUCCESS The operation is successful. | |
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported. | |
**/ | |
EFI_STATUS | |
IpSecProtectOutboundPacket ( | |
IN UINT8 IpVersion, | |
IN OUT VOID *IpHead, | |
IN OUT UINT8 *LastHead, | |
IN OUT VOID **OptionsBuffer, | |
IN OUT UINT32 *OptionsLength, | |
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, | |
IN OUT UINT32 *FragmentCount, | |
IN IPSEC_SAD_ENTRY *SadEntry, | |
OUT EFI_EVENT *RecycleEvent | |
); | |
/** | |
Check if the IP Address in the address range of AddressInfos specified. | |
@param[in] IpVersion The IP version. | |
@param[in] IpAddr Points to EFI_IP_ADDRESS to be check. | |
@param[in] AddressInfo A list of EFI_IP_ADDRESS_INFO that is used to check | |
the IP Address is matched. | |
@param[in] AddressCount The total numbers of the AddressInfo. | |
@retval TRUE If the Specified IP Address is in the range of the AddressInfos specified. | |
@retval FALSE If the Specified IP Address is not in the range of the AddressInfos specified. | |
**/ | |
BOOLEAN | |
IpSecMatchIpAddress ( | |
IN UINT8 IpVersion, | |
IN EFI_IP_ADDRESS *IpAddr, | |
IN EFI_IP_ADDRESS_INFO *AddressInfo, | |
IN UINT32 AddressCount | |
); | |
/** | |
Find a PAD entry according to remote IP address. | |
@param[in] IpVersion The version of IP. | |
@param[in] IpAddr Point to remote IP address. | |
@return The pointer of related PAD entry. | |
**/ | |
IPSEC_PAD_ENTRY * | |
IpSecLookupPadEntry ( | |
IN UINT8 IpVersion, | |
IN EFI_IP_ADDRESS *IpAddr | |
); | |
/** | |
Check if the specified IP packet can be serviced by this SPD entry. | |
@param[in] SpdEntry Point to SPD entry. | |
@param[in] IpVersion Version of IP. | |
@param[in] IpHead Point to IP header. | |
@param[in] IpPayload Point to IP payload. | |
@param[in] Protocol The Last protocol of IP packet. | |
@param[in] IsOutbound Traffic direction. | |
@param[out] Action The support action of SPD entry. | |
@retval EFI_SUCCESS Find the related SPD. | |
@retval EFI_NOT_FOUND Not find the related SPD entry; | |
**/ | |
EFI_STATUS | |
IpSecLookupSpdEntry ( | |
IN IPSEC_SPD_ENTRY *SpdEntry, | |
IN UINT8 IpVersion, | |
IN VOID *IpHead, | |
IN UINT8 *IpPayload, | |
IN UINT8 Protocol, | |
IN BOOLEAN IsOutbound, | |
OUT EFI_IPSEC_ACTION *Action | |
); | |
/** | |
Look up if there is existing SAD entry for specified IP packet sending. | |
This function is called by the IPsecProcess when there is some IP packet needed to | |
send out. This function checks if there is an existing SAD entry that can be serviced | |
to this IP packet sending. If no existing SAD entry could be used, this | |
function will invoke an IPsec Key Exchange Negotiation. | |
@param[in] Private Points to private data. | |
@param[in] NicHandle Points to a NIC handle. | |
@param[in] IpVersion The version of IP. | |
@param[in] IpHead The IP Header of packet to be sent out. | |
@param[in] IpPayload The IP Payload to be sent out. | |
@param[in] OldLastHead The Last protocol of the IP packet. | |
@param[in] SpdEntry Points to a related SPD entry. | |
@param[out] SadEntry Contains the Point of a related SAD entry. | |
@retval EFI_DEVICE_ERROR One of following conditions is TRUE: | |
- If don't find related UDP service. | |
- Sequence Number is used up. | |
- Extension Sequence Number is used up. | |
@retval EFI_NOT_READY No existing SAD entry could be used. | |
@retval EFI_SUCCESS Find the related SAD entry. | |
**/ | |
EFI_STATUS | |
IpSecLookupSadEntry ( | |
IN IPSEC_PRIVATE_DATA *Private, | |
IN EFI_HANDLE NicHandle, | |
IN UINT8 IpVersion, | |
IN VOID *IpHead, | |
IN UINT8 *IpPayload, | |
IN UINT8 OldLastHead, | |
IN IPSEC_SPD_ENTRY *SpdEntry, | |
OUT IPSEC_SAD_ENTRY **SadEntry | |
); | |
/** | |
Find the SAD through whole SAD list. | |
@param[in] Spi The SPI used to search the SAD entry. | |
@param[in] DestAddress The destination used to search the SAD entry. | |
@param[in] IpVersion The IP version. Ip4 or Ip6. | |
@return The pointer to a certain SAD entry. | |
**/ | |
IPSEC_SAD_ENTRY * | |
IpSecLookupSadBySpi ( | |
IN UINT32 Spi, | |
IN EFI_IP_ADDRESS *DestAddress, | |
IN UINT8 IpVersion | |
) | |
; | |
/** | |
Handles IPsec packet processing for inbound and outbound IP packets. | |
The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet. | |
The behavior is that it can perform one of the following actions: | |
bypass the packet, discard the packet, or protect the packet. | |
@param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance. | |
@param[in] NicHandle Instance of the network interface. | |
@param[in] IpVersion IPV4 or IPV6. | |
@param[in, out] IpHead Pointer to the IP Header. | |
@param[in, out] LastHead The protocol of the next layer to be processed by IPsec. | |
@param[in, out] OptionsBuffer Pointer to the options buffer. | |
@param[in, out] OptionsLength Length of the options buffer. | |
@param[in, out] FragmentTable Pointer to a list of fragments. | |
@param[in, out] FragmentCount Number of fragments. | |
@param[in] TrafficDirection Traffic direction. | |
@param[out] RecycleSignal Event for recycling of resources. | |
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same. | |
@retval EFI_SUCCESS The packet was protected. | |
@retval EFI_ACCESS_DENIED The packet was discarded. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
IpSecProcess ( | |
IN EFI_IPSEC2_PROTOCOL *This, | |
IN EFI_HANDLE NicHandle, | |
IN UINT8 IpVersion, | |
IN OUT VOID *IpHead, | |
IN OUT UINT8 *LastHead, | |
IN OUT VOID **OptionsBuffer, | |
IN OUT UINT32 *OptionsLength, | |
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, | |
IN OUT UINT32 *FragmentCount, | |
IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection, | |
OUT EFI_EVENT *RecycleSignal | |
); | |
extern EFI_DPC_PROTOCOL *mDpc; | |
extern EFI_IPSEC2_PROTOCOL mIpSecInstance; | |
extern EFI_COMPONENT_NAME2_PROTOCOL gIpSecComponentName2; | |
extern EFI_COMPONENT_NAME_PROTOCOL gIpSecComponentName; | |
#endif |