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