IN UINT8 NextHeader,\r
IN UINT32 Len\r
);\r
+\r
+/**\r
+ The function frees the net buffer which allocated by the IP protocol. It releases \r
+ only the net buffer and doesn't call the external free function. \r
+\r
+ This function should be called after finishing the process of mIpSec->ProcessExt() \r
+ for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new \r
+ buffer for the ESP, so there needs a function to free the old net buffer.\r
+\r
+ @param[in] Nbuf The network buffer to be freed.\r
+\r
+**/\r
+VOID\r
+NetIpSecNetbufFree (\r
+ NET_BUF *Nbuf\r
+ );\r
#endif\r
return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));\r
}\r
\r
+/**\r
+ The function frees the net buffer which allocated by the IP protocol. It releases \r
+ only the net buffer and doesn't call the external free function. \r
+\r
+ This function should be called after finishing the process of mIpSec->ProcessExt() \r
+ for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new \r
+ buffer for the ESP, so there needs a function to free the old net buffer.\r
+\r
+ @param[in] Nbuf The network buffer to be freed.\r
+\r
+**/\r
+VOID\r
+NetIpSecNetbufFree (\r
+ NET_BUF *Nbuf\r
+ )\r
+{\r
+ NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
+ ASSERT (Nbuf->RefCnt > 0);\r
+\r
+ Nbuf->RefCnt--;\r
+\r
+ if (Nbuf->RefCnt == 0) {\r
+ \r
+ //\r
+ // Update Vector only when NBuf is to be released. That is,\r
+ // all the sharing of Nbuf increse Vector's RefCnt by one\r
+ //\r
+ NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);\r
+ ASSERT (Nbuf->Vector->RefCnt > 0);\r
+\r
+ Nbuf->Vector->RefCnt--;\r
+\r
+ if (Nbuf->Vector->RefCnt > 0) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // If NET_VECTOR_OWN_FIRST is set, release the first block since it is \r
+ // allocated by us\r
+ //\r
+ if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {\r
+ FreePool (Nbuf->Vector->Block[0].Bulk);\r
+ }\r
+ FreePool (Nbuf->Vector);\r
+ FreePool (Nbuf); \r
+ } \r
+}\r
+\r
\r
#include "Ip4Impl.h"\r
\r
-EFI_IPSEC_PROTOCOL *mIpSec = NULL;\r
+EFI_IPSEC2_PROTOCOL *mIpSec = NULL;\r
\r
/**\r
Gets the current operational settings for this instance of the EFI IPv4 Protocol driver.\r
IN VOID *Context\r
);\r
\r
-extern EFI_IPSEC_PROTOCOL *mIpSec;\r
+extern EFI_IPSEC2_PROTOCOL *mIpSec;\r
\r
#endif\r
outbound IP packets. The process routine handls the packet with following\r
actions: bypass the packet, discard the packet, or protect the packet. \r
\r
- @param[in] IpSb The IP4 service instance\r
- @param[in] Head The The caller supplied IP4 header.\r
- @param[in, out] Netbuf The IP4 packet to be processed by IPsec\r
- @param[in] Options The caller supplied options\r
- @param[in] OptionsLen The length of the option\r
+ @param[in] IpSb The IP4 service instance.\r
+ @param[in, out] Head The The caller supplied IP4 header.\r
+ @param[in, out] Netbuf The IP4 packet to be processed by IPsec.\r
+ @param[in, out] Options The caller supplied options.\r
+ @param[in, out] OptionsLen The length of the option.\r
@param[in] Direction The directionality in an SPD entry, \r
- EfiIPsecInBound or EfiIPsecOutBound\r
- @param[in] Context The token's wrap\r
+ EfiIPsecInBound or EfiIPsecOutBound.\r
+ @param[in] Context The token's wrap.\r
\r
@retval EFI_SUCCESS The IPsec protocol is not available or disabled.\r
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.\r
**/\r
EFI_STATUS\r
Ip4IpSecProcessPacket (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_HEAD *Head,\r
- IN OUT NET_BUF **Netbuf,\r
- IN UINT8 *Options,\r
- IN UINT32 OptionsLen,\r
- IN EFI_IPSEC_TRAFFIC_DIR Direction,\r
- IN VOID *Context\r
+ IN IP4_SERVICE *IpSb,\r
+ IN OUT IP4_HEAD **Head,\r
+ IN OUT NET_BUF **Netbuf,\r
+ IN OUT UINT8 **Options,\r
+ IN OUT UINT32 *OptionsLen,\r
+ IN EFI_IPSEC_TRAFFIC_DIR Direction,\r
+ IN VOID *Context\r
)\r
{\r
NET_FRAGMENT *FragmentTable;\r
+ NET_FRAGMENT *OriginalFragmentTable;\r
UINT32 FragmentCount;\r
+ UINT32 OriginalFragmentCount;\r
EFI_EVENT RecycleEvent;\r
NET_BUF *Packet;\r
IP4_TXTOKEN_WRAP *TxWrap;\r
IP4_IPSEC_WRAP *IpSecWrap;\r
EFI_STATUS Status;\r
+ IP4_HEAD ZeroHead;\r
\r
Status = EFI_SUCCESS;\r
Packet = *Netbuf;\r
FragmentTable = NULL;\r
TxWrap = (IP4_TXTOKEN_WRAP *) Context; \r
FragmentCount = Packet->BlockOpNum;\r
+\r
+ ZeroMem (&ZeroHead, sizeof (IP4_HEAD));\r
\r
if (mIpSec == NULL) {\r
gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec);\r
}\r
\r
Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);\r
+ \r
+ //\r
+ // Record the original FragmentTable and count.\r
+ //\r
+ OriginalFragmentTable = FragmentTable;\r
+ OriginalFragmentCount = FragmentCount;\r
\r
if (EFI_ERROR (Status)) {\r
FreePool (FragmentTable);\r
//\r
// Convert host byte order to network byte order\r
//\r
- Ip4NtohHead (Head);\r
+ Ip4NtohHead (*Head);\r
\r
- Status = mIpSec->Process (\r
+ Status = mIpSec->ProcessExt (\r
mIpSec,\r
IpSb->Controller,\r
IP_VERSION_4,\r
- (VOID *) Head,\r
- &Head->Protocol,\r
- NULL,\r
- 0,\r
+ (VOID *) (*Head),\r
+ &(*Head)->Protocol,\r
+ Options,\r
+ OptionsLen,\r
(EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable),\r
&FragmentCount,\r
Direction,\r
//\r
// Convert back to host byte order\r
//\r
- Ip4NtohHead (Head);\r
+ Ip4NtohHead (*Head);\r
\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
}\r
\r
+ if (OriginalFragmentTable == FragmentTable && OriginalFragmentCount == FragmentCount) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
if (Direction == EfiIPsecOutBound && TxWrap != NULL) {\r
\r
TxWrap->IpSecRecycleSignal = RecycleEvent;\r
goto ON_EXIT;\r
}\r
\r
+ //\r
+ // Free orginal Netbuf.\r
+ //\r
+ NetIpSecNetbufFree (*Netbuf);\r
*Netbuf = TxWrap->Packet;\r
\r
} else {\r
goto ON_EXIT;\r
}\r
\r
- if (Direction == EfiIPsecInBound) {\r
- Ip4PrependHead (Packet, Head, Options, OptionsLen);\r
+ if (Direction == EfiIPsecInBound && 0 != CompareMem (*Head, &ZeroHead, sizeof (IP4_HEAD))) {\r
+ Ip4PrependHead (Packet, *Head, *Options, *OptionsLen);\r
Ip4NtohHead (Packet->Ip.Ip4);\r
- NetbufTrim (Packet, (Head->HeadLen << 2), TRUE);\r
+ NetbufTrim (Packet, ((*Head)->HeadLen << 2), TRUE);\r
\r
CopyMem (\r
IP4_GET_CLIP_INFO (Packet),\r
sizeof (IP4_CLIP_INFO)\r
);\r
}\r
-\r
*Netbuf = Packet;\r
}\r
\r
}\r
\r
/**\r
- The IP4 input routine. It is called by the IP4_INTERFACE when a\r
- IP4 fragment is received from MNP.\r
+ Pre-process the IPv4 packet. First validates the IPv4 packet, and\r
+ then reassembles packet if it is necessary.\r
+ \r
+ @param[in] IpSb Pointer to IP4_SERVICE.\r
+ @param[in, out] Packet Pointer to the Packet to be processed.\r
+ @param[in] Head Pointer to the IP4_HEAD.\r
+ @param[in] Option Pointer to a buffer which contains the IPv4 option.\r
+ @param[in] OptionLen The length of Option in bytes.\r
+ @param[in] Flag The link layer flag for the packet received, such\r
+ as multicast.\r
\r
- @param[in] Ip4Instance The IP4 child that request the receive, most like\r
- it is NULL.\r
- @param[in] Packet The IP4 packet received.\r
- @param[in] IoStatus The return status of receive request.\r
- @param[in] Flag The link layer flag for the packet received, such\r
- as multicast.\r
- @param[in] Context The IP4 service instance that own the MNP.\r
+ @retval EFI_SEUCCESS The recieved packet is in well form.\r
+ @retval EFI_INVAILD_PARAMETER The recieved packet is malformed. \r
\r
**/\r
-VOID\r
-Ip4AccpetFrame (\r
- IN IP4_PROTOCOL *Ip4Instance,\r
- IN NET_BUF *Packet,\r
- IN EFI_STATUS IoStatus,\r
- IN UINT32 Flag,\r
- IN VOID *Context\r
- )\r
+EFI_STATUS\r
+Ip4PreProcessPacket (\r
+ IN IP4_SERVICE *IpSb,\r
+ IN OUT NET_BUF **Packet,\r
+ IN IP4_HEAD *Head,\r
+ IN UINT8 *Option,\r
+ IN UINT32 OptionLen, \r
+ IN UINT32 Flag\r
+ ) \r
{\r
- IP4_SERVICE *IpSb;\r
IP4_CLIP_INFO *Info;\r
- IP4_HEAD *Head;\r
UINT32 HeadLen;\r
- UINT32 OptionLen;\r
UINT32 TotalLen;\r
UINT16 Checksum;\r
- EFI_STATUS Status;\r
-\r
- IpSb = (IP4_SERVICE *) Context;\r
-\r
- if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {\r
- goto DROP;\r
- }\r
\r
//\r
// Check that the IP4 header is correctly formatted\r
//\r
- if (Packet->TotalSize < IP4_MIN_HEADLEN) {\r
- goto RESTART;\r
+ if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
-\r
- Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+ \r
HeadLen = (Head->HeadLen << 2);\r
TotalLen = NTOHS (Head->TotalLen);\r
\r
//\r
// Mnp may deliver frame trailer sequence up, trim it off.\r
//\r
- if (TotalLen < Packet->TotalSize) {\r
- NetbufTrim (Packet, Packet->TotalSize - TotalLen, FALSE);\r
+ if (TotalLen < (*Packet)->TotalSize) {\r
+ NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);\r
}\r
\r
if ((Head->Ver != 4) || (HeadLen < IP4_MIN_HEADLEN) ||\r
- (TotalLen < HeadLen) || (TotalLen != Packet->TotalSize)) {\r
- goto RESTART;\r
+ (TotalLen < HeadLen) || (TotalLen != (*Packet)->TotalSize)) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) Head, HeadLen));\r
\r
if ((Head->Checksum != 0) && (Checksum != 0)) {\r
- goto RESTART;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Convert the IP header to host byte order, then get the per packet info.\r
//\r
- Packet->Ip.Ip4 = Ip4NtohHead (Head);\r
+ (*Packet)->Ip.Ip4 = Ip4NtohHead (Head);\r
\r
- Info = IP4_GET_CLIP_INFO (Packet);\r
+ Info = IP4_GET_CLIP_INFO (*Packet);\r
Info->LinkFlag = Flag;\r
Info->CastType = Ip4GetHostCast (IpSb, Head->Dst, Head->Src);\r
Info->Start = (Head->Fragment & IP4_HEAD_OFFSET_MASK) << 3;\r
// The packet is destinated to us if the CastType is non-zero.\r
//\r
if ((Info->CastType == 0) || (Info->End > IP4_MAX_PACKET_SIZE)) {\r
- goto RESTART;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Validate the options. Don't call the Ip4OptionIsValid if\r
// there is no option to save some CPU process.\r
//\r
- OptionLen = HeadLen - IP4_MIN_HEADLEN;\r
-\r
- if ((OptionLen > 0) && !Ip4OptionIsValid ((UINT8 *) (Head + 1), OptionLen, TRUE)) {\r
- goto RESTART;\r
+ \r
+ if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Trim the head off, after this point, the packet is headless.\r
// and Packet->TotalLen == Info->Length.\r
//\r
- NetbufTrim (Packet, HeadLen, TRUE);\r
+ NetbufTrim (*Packet, HeadLen, TRUE);\r
\r
//\r
// Reassemble the packet if this is a fragment. The packet is a\r
// need to send a type 4 destination unreache ICMP message here.\r
//\r
if ((Head->Fragment & IP4_HEAD_DF_MASK) != 0) {\r
- goto RESTART;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// The length of all but the last fragments is in the unit of 8 bytes.\r
//\r
if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) && (Info->Length % 8 != 0)) {\r
- goto RESTART;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
- Packet = Ip4Reassemble (&IpSb->Assemble, Packet);\r
+ *Packet = Ip4Reassemble (&IpSb->Assemble, *Packet);\r
\r
//\r
// Packet assembly isn't complete, start receive more packet.\r
//\r
- if (Packet == NULL) {\r
- goto RESTART;\r
+ if (*Packet == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
}\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ The IP4 input routine. It is called by the IP4_INTERFACE when a\r
+ IP4 fragment is received from MNP.\r
+\r
+ @param[in] Ip4Instance The IP4 child that request the receive, most like\r
+ it is NULL.\r
+ @param[in] Packet The IP4 packet received.\r
+ @param[in] IoStatus The return status of receive request.\r
+ @param[in] Flag The link layer flag for the packet received, such\r
+ as multicast.\r
+ @param[in] Context The IP4 service instance that own the MNP.\r
+\r
+**/\r
+VOID\r
+Ip4AccpetFrame (\r
+ IN IP4_PROTOCOL *Ip4Instance,\r
+ IN NET_BUF *Packet,\r
+ IN EFI_STATUS IoStatus,\r
+ IN UINT32 Flag,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ IP4_SERVICE *IpSb;\r
+ IP4_HEAD *Head;\r
+ EFI_STATUS Status;\r
+ IP4_HEAD ZeroHead;\r
+ UINT8 *Option;\r
+ UINT32 OptionLen;\r
+ \r
+ IpSb = (IP4_SERVICE *) Context;\r
+ Option = NULL;\r
+\r
+ if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {\r
+ goto DROP;\r
+ }\r
+\r
+ Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); \r
+ OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;\r
+ if (OptionLen > 0) {\r
+ Option = (UINT8 *) (Head + 1);\r
+ }\r
+\r
+ //\r
+ // Validate packet format and reassemble packet if it is necessary.\r
+ //\r
+ Status = Ip4PreProcessPacket (\r
+ IpSb, \r
+ &Packet, \r
+ Head, \r
+ Option,\r
+ OptionLen, \r
+ Flag\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto RESTART;\r
+ }\r
\r
//\r
// After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,\r
//\r
Status = Ip4IpSecProcessPacket (\r
IpSb, \r
- Head, \r
+ &Head, \r
&Packet, \r
- NULL,\r
- 0, \r
+ &Option,\r
+ &OptionLen, \r
EfiIPsecInBound,\r
NULL\r
);\r
\r
- if (EFI_ERROR(Status)) {\r
+ if (EFI_ERROR (Status)) {\r
goto RESTART;\r
}\r
+ \r
+ //\r
+ // If the packet is protected by tunnel mode, parse the inner Ip Packet.\r
+ //\r
+ ZeroMem (&ZeroHead, sizeof (IP4_HEAD));\r
+ if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) {\r
// Packet may have been changed. Head, HeadLen, TotalLen, and\r
// info must be reloaded bofore use. The ownership of the packet\r
// is transfered to the packet process logic.\r
//\r
+ Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+ Status = Ip4PreProcessPacket (\r
+ IpSb, \r
+ &Packet, \r
+ Head, \r
+ Option,\r
+ OptionLen, \r
+ Flag\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto RESTART;\r
+ }\r
+ }\r
Head = Packet->Ip.Ip4;\r
IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;\r
\r
outbound IP packets. The process routine handls the packet with following\r
actions: bypass the packet, discard the packet, or protect the packet. \r
\r
- @param[in] IpSb The IP4 service instance\r
- @param[in] Head The The caller supplied IP4 header.\r
- @param[in, out] Netbuf The IP4 packet to be processed by IPsec\r
- @param[in] Options The caller supplied options\r
- @param[in] OptionsLen The length of the option\r
+ @param[in] IpSb The IP4 service instance.\r
+ @param[in, out] Head The The caller supplied IP4 header.\r
+ @param[in, out] Netbuf The IP4 packet to be processed by IPsec.\r
+ @param[in, out] Options The caller supplied options.\r
+ @param[in, out] OptionsLen The length of the option.\r
@param[in] Direction The directionality in an SPD entry, \r
- EfiIPsecInBound or EfiIPsecOutBound\r
- @param[in] Context The token's wrap\r
+ EfiIPsecInBound or EfiIPsecOutBound.\r
+ @param[in] Context The token's wrap.\r
\r
@retval EFI_SUCCESS The IPsec protocol is not available or disabled.\r
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.\r
**/\r
EFI_STATUS\r
Ip4IpSecProcessPacket (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_HEAD *Head,\r
- IN OUT NET_BUF **Netbuf,\r
- IN UINT8 *Options,\r
- IN UINT32 OptionsLen,\r
- IN EFI_IPSEC_TRAFFIC_DIR Direction,\r
- IN VOID *Context\r
+ IN IP4_SERVICE *IpSb,\r
+ IN OUT IP4_HEAD **Head,\r
+ IN OUT NET_BUF **Netbuf,\r
+ IN OUT UINT8 **Options,\r
+ IN OUT UINT32 *OptionsLen,\r
+ IN EFI_IPSEC_TRAFFIC_DIR Direction,\r
+ IN VOID *Context\r
);\r
\r
#endif\r
Head->Src = IpIf->Ip;\r
}\r
\r
+ //\r
+ // Before IPsec process, prepared the IP head.\r
+ //\r
+ HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
+ Head->HeadLen = (UINT8) HeadLen >> 2;\r
+ Head->Id = mIp4Id++;\r
+ Head->Ver = 4;\r
+ \r
+ //\r
+ // Call IPsec process.\r
+ //\r
+ Status = Ip4IpSecProcessPacket (\r
+ IpSb, \r
+ &Head, \r
+ &Packet, \r
+ &Option, \r
+ &OptLen, \r
+ EfiIPsecOutBound,\r
+ Context\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
//\r
// Route the packet unless overrided, that is, GateWay isn't zero.\r
//\r
}\r
}\r
\r
- //\r
- // TODO: currently Option/OptLen are not included into encryption scope.\r
- //\r
- Status = Ip4IpSecProcessPacket (\r
- IpSb, \r
- Head, \r
- &Packet, \r
- Option, \r
- OptLen, \r
- EfiIPsecOutBound,\r
- Context\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
//\r
// OK, selected the source and route, fragment the packet then send\r
// them. Tag each fragment other than the first one as spawn from it.\r
//\r
- Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);\r
- HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
- Head->Id = mIp4Id++;\r
+ Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD); \r
\r
if (Packet->TotalSize + HeadLen > Mtu) {\r
//\r
/** @file\r
EFI IPSEC Protocol Definition\r
The EFI_IPSEC_PROTOCOL is used to abstract the ability to deal with the individual\r
- packets sent and received by the host and provide packet-level security for IP datagram.\r
+ packets sent and received by the host and provide packet-level security for IP \r
+ datagram.\r
+ The EFI_IPSEC2_PROTOCOL is used to abstract the ability to deal with the individual\r
+ packets sent and received by the host and provide packet-level security for IP \r
+ datagram. In addition, it supports the Option (extension header) processing in \r
+ IPsec which doesn't support in EFI_IPSEC_PROTOCOL. It is also recommended to \r
+ use EFI_IPSEC2_PROTOCOL instead of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel \r
+ Mode.\r
\r
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 } \\r
}\r
\r
+#define EFI_IPSEC2_PROTOCOL_GUID \\r
+ { \\r
+ 0xa3979e64, 0xace8, 0x4ddc, {0xbc, 0x7, 0x4d, 0x66, 0xb8, 0xfd, 0x9, 0x77 } \\r
+ }\r
+\r
typedef struct _EFI_IPSEC_PROTOCOL EFI_IPSEC_PROTOCOL;\r
+typedef struct _EFI_IPSEC2_PROTOCOL EFI_IPSEC2_PROTOCOL;\r
\r
///\r
/// EFI_IPSEC_FRAGMENT_DATA \r
BOOLEAN DisabledFlag; ///< State of the interface.\r
};\r
\r
-extern EFI_GUID gEfiIpSecProtocolGuid;\r
+/**\r
+ Handles IPsec processing for both inbound and outbound IP packets. Compare with \r
+ Process() in EFI_IPSEC_PROTOCOL, this interface has the capability to process \r
+ Option(Extension Header). \r
+\r
+ The EFI_IPSEC2_PROCESS process routine handles each inbound or outbound packet.\r
+ The behavior is that it can perform one of the following actions: \r
+ bypass the packet, discard the packet, or protect the packet. \r
+\r
+ @param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance.\r
+ @param[in] NicHandle Instance of the network interface. \r
+ @param[in] IpVer IP version.IPv4 or IPv6.\r
+ @param[in, out] IpHead Pointer to the IP Header it is either \r
+ the EFI_IP4_HEADER or EFI_IP6_HEADER.\r
+ On input, it contains the IP header. \r
+ On output, 1) in tunnel mode and the \r
+ traffic direction is inbound, the buffer \r
+ will be reset to zero by IPsec; 2) in \r
+ tunnel mode and the traffic direction \r
+ is outbound, the buffer will reset to \r
+ be the tunnel IP header.3) in transport \r
+ mode, the related fielders (like payload \r
+ length, Next header) in IP header will \r
+ be modified according to the condition.\r
+ @param[in, out] LastHead For IP4, it is the next protocol in IP\r
+ header. For IP6 it is the Next Header \r
+ of the last extension header.\r
+ @param[in, out] OptionsBuffer On input, it contains the options \r
+ (extensions header) to be processed by \r
+ IPsec. On output, 1) in tunnel mode and\r
+ the traffic direction is outbound, it \r
+ will be set to NULL, and that means this \r
+ contents was wrapped after inner header \r
+ and should not be concatenated after \r
+ tunnel header again; 2) in transport \r
+ mode and the traffic direction is inbound, \r
+ if there are IP options (extension headers) \r
+ protected by IPsec, IPsec will concatenate \r
+ the those options after the input options \r
+ (extension headers); 3) on other situations, \r
+ the output of contents of OptionsBuffer \r
+ might be same with input's. The caller \r
+ should take the responsibility to free \r
+ the buffer both on input and on output.\r
+ @param[in, out] OptionsLength On input, the input length of the options \r
+ buffer. On output, the output length of \r
+ the options buffer.\r
+ @param[in, out] FragmentTable Pointer to a list of fragments. On input, \r
+ these fragments contain the IP payload. \r
+ On output, 1) in tunnel mode and the traffic \r
+ direction is inbound, the fragments contain \r
+ the whole IP payload which is from the \r
+ IP inner header to the last byte of the \r
+ packet; 2) in tunnel mode and the traffic \r
+ direction is the outbound, the fragments \r
+ contains the whole encapsulated payload \r
+ which encapsulates the whole IP payload \r
+ between the encapsulated header and \r
+ encapsulated trailer fields. 3) in transport \r
+ mode and the traffic direction is inbound, \r
+ the fragments contains the IP payload \r
+ which is from the next layer protocol to \r
+ the last byte of the packet; 4) in transport \r
+ mode and the traffic direction is outbound, \r
+ the fragments contains the whole encapsulated \r
+ payload which encapsulates the next layer \r
+ protocol information between the encapsulated \r
+ header and encapsulated trailer fields.\r
+ @param[in, out] FragmentCount Number of fragments.\r
+ @param[in] TrafficDirection Traffic direction.\r
+ @param[out] RecycleSignal Event for recycling of resources.\r
+\r
+ @retval EFI_SUCCESS The packet was processed by IPsec successfully.\r
+ @retval EFI_ACCESS_DENIED The packet was discarded.\r
+ @retval EFI_NOT_READY The IKE negotiation is invoked and the packet \r
+ was discarded.\r
+ @retval EFI_INVALID_PARAMETER One or more of following are TRUE:\r
+ If OptionsBuffer is NULL;\r
+ If OptionsLength is NULL;\r
+ If FragmentTable is NULL;\r
+ If FragmentCount is NULL.\r
+\r
+**/\r
+typedef \r
+EFI_STATUS\r
+(EFIAPI *EFI_IPSEC_PROCESSEXT) ( \r
+ IN EFI_IPSEC2_PROTOCOL *This, \r
+ IN EFI_HANDLE NicHandle, \r
+ IN UINT8 IpVer, \r
+ IN OUT VOID *IpHead, \r
+ IN OUT UINT8 *LastHead, \r
+ IN OUT VOID **OptionsBuffer, \r
+ IN OUT UINT32 *OptionsLength, \r
+ IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, \r
+ IN OUT UINT32 *FragmentCount, \r
+ IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection, \r
+ OUT EFI_EVENT *RecycleSignal\r
+ );\r
\r
+/// \r
+/// EFI_IPSEC2_PROTOCOL\r
+/// supports the Option (extension header) processing in IPsec which doesn't support\r
+/// in EFI_IPSEC_PROTOCOL. It is also recommended to use EFI_IPSEC2_PROTOCOL instead\r
+/// of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel Mode.\r
+/// provides the ability for securing IP communications by authenticating and/or\r
+/// encrypting each IP packet in a data stream.\r
+///\r
+struct _EFI_IPSEC2_PROTOCOL { \r
+EFI_IPSEC_PROCESSEXT ProcessExt;\r
+EFI_EVENT DisabledEvent; \r
+BOOLEAN DisabledFlag; \r
+};\r
+\r
+extern EFI_GUID gEfiIpSecProtocolGuid;\r
+extern EFI_GUID gEfiIpSec2ProtocolGuid;\r
#endif\r
UINT8 EncAlgoId;\r
} EFI_IPSEC_PROCESS_POLICY;\r
\r
-///\r
-/// IPsec Authentication Algorithm Definition\r
-/// The number value definition is aligned to IANA assignment\r
-///\r
-#define EFI_IPSEC_AALG_NONE 0x00\r
-#define EFI_IPSEC_AALG_MD5HMAC 0x02\r
-#define EFI_IPSEC_AALG_SHA1HMAC 0x03\r
-#define EFI_IPSEC_AALG_SHA2_256HMAC 0x05\r
-#define EFI_IPSEC_AALG_SHA2_384HMAC 0x06\r
-#define EFI_IPSEC_AALG_SHA2_512HMAC 0x07\r
-#define EFI_IPSEC_AALG_AES_XCBC_MAC 0x09\r
-#define EFI_IPSEC_AALG_NULL 0xFB\r
-\r
-///\r
-/// IPsec Encryption Algorithm Definition\r
-/// The number value definition is aligned to IANA assignment\r
-///\r
-#define EFI_IPSEC_EALG_NONE 0x00\r
-#define EFI_IPSEC_EALG_DESCBC 0x02\r
-#define EFI_IPSEC_EALG_3DESCBC 0x03\r
-#define EFI_IPSEC_EALG_CASTCBC 0x06\r
-#define EFI_IPSEC_EALG_BLOWFISHCBC 0x07\r
-#define EFI_IPSEC_EALG_NULL 0x0B\r
-#define EFI_IPSEC_EALG_AESCBC 0x0C\r
-#define EFI_IPSEC_EALG_AESCTR 0x0D\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV8 0x0E\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV12 0x0F\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV16 0x10\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV8 0x12\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV12 0x13\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV16 0x14\r
-\r
///\r
/// EFI_IPSEC_SA_ID\r
/// A triplet to identify an SA, consisting of the following members.\r
BOOLEAN ManualSet;\r
} EFI_IPSEC_SA_DATA;\r
\r
+///\r
+/// EFI_IPSEC_SA_DATA2\r
+///\r
+typedef struct _EFI_IPSEC_SA_DATA2 { \r
+ ///\r
+ /// IPsec mode: tunnel or transport\r
+ ///\r
+ EFI_IPSEC_MODE Mode; \r
+ ///\r
+ /// Sequence Number Counter. A 64-bit counter used to generate the sequence \r
+ /// number field in AH or ESP headers. \r
+ ///\r
+ UINT64 SNCount; \r
+ ///\r
+ /// Anti-Replay Window. A 64-bit counter and a bit-map used to determine \r
+ /// whether an inbound AH or ESP packet is a replay.\r
+ ///\r
+ UINT8 AntiReplayWindows; \r
+ ///\r
+ /// AH/ESP cryptographic algorithm, key and parameters.\r
+ ///\r
+ EFI_IPSEC_ALGO_INFO AlgoInfo; \r
+ ///\r
+ /// Lifetime of this SA.\r
+ ///\r
+ EFI_IPSEC_SA_LIFETIME SaLifetime; \r
+ ///\r
+ /// Any observed path MTU and aging variables. The Path MTU processing is \r
+ /// defined in section 8 of RFC 4301.\r
+ ///\r
+ UINT32 PathMTU; \r
+ ///\r
+ /// Link to one SPD entry\r
+ ///\r
+ EFI_IPSEC_SPD_SELECTOR *SpdSelector; \r
+ ///\r
+ /// Indication of whether it's manually set or negotiated automatically. \r
+ /// If ManualSet is FALSE, the corresponding SA entry is inserted through IKE \r
+ /// protocol negotiation\r
+ ///\r
+ BOOLEAN ManualSet;\r
+ ///\r
+ /// The tunnel header IP source address.\r
+ ///\r
+ EFI_IP_ADDRESS TunnelSourceAddress;\r
+ ///\r
+ /// The tunnel header IP destination address.\r
+ ///\r
+ EFI_IP_ADDRESS TunnelDestinationAddress;\r
+} EFI_IPSEC_SA_DATA2; \r
+\r
+\r
///\r
/// EFI_IPSEC_PAD_ID\r
/// specifies the identifier for PAD entry, which is also used for SPD lookup.\r