Add NetworkPkg (P.UDK2010.UP3.Network.P1)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10986 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
310
NetworkPkg/IpSecDxe/ComponentName.c
Normal file
310
NetworkPkg/IpSecDxe/ComponentName.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/** @file
|
||||
UEFI Component Name(2) protocol implementation for IPsec driver.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "IpSecImpl.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the driver.
|
||||
|
||||
This function retrieves the user-readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user-readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user-readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user-readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle, OPTIONAL
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gIpSecComponentName = {
|
||||
IpSecComponentNameGetDriverName,
|
||||
IpSecComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
//
|
||||
// EFI Component Name 2 Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIpSecComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IpSecComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IpSecComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecDriverNameTable[] = {
|
||||
{
|
||||
"eng;en",
|
||||
L"IpSec Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the driver.
|
||||
|
||||
This function retrieves the user-readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user-readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This, and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mIpSecDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN) (This == &gIpSecComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user-readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user-readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle, OPTIONAL
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
2928
NetworkPkg/IpSecDxe/IpSecConfigImpl.c
Normal file
2928
NetworkPkg/IpSecDxe/IpSecConfigImpl.c
Normal file
File diff suppressed because it is too large
Load Diff
952
NetworkPkg/IpSecDxe/IpSecConfigImpl.h
Normal file
952
NetworkPkg/IpSecDxe/IpSecConfigImpl.h
Normal file
@@ -0,0 +1,952 @@
|
||||
/** @file
|
||||
Definitions related to IPSEC_CONFIG_PROTOCOL implementations.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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 _IPSEC_CONFIG_IMPL_H_
|
||||
#define _IPSEC_CONFIG_IMPL_H_
|
||||
|
||||
#include <Protocol/IpSec.h>
|
||||
#include <Protocol/IpSecConfig.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include "IpSecImpl.h"
|
||||
|
||||
#define EFI_IPSEC_ANY_PROTOCOL 0xFFFF
|
||||
#define EFI_IPSEC_ANY_PORT 0
|
||||
|
||||
#define IPSEC_VAR_ITEM_HEADER_LOGO_BIT 0x80
|
||||
#define IPSEC_VAR_ITEM_HEADER_CONTENT_BIT 0x7F
|
||||
|
||||
#define IPSECCONFIG_VARIABLE_NAME L"IpSecConfig"
|
||||
#define IPSECCONFIG_STATUS_NAME L"IpSecStatus"
|
||||
|
||||
#define SIZE_OF_SPD_SELECTOR(x) (UINTN) (sizeof (EFI_IPSEC_SPD_SELECTOR) \
|
||||
+ sizeof (EFI_IP_ADDRESS_INFO) * ((x)->LocalAddressCount + (x)->RemoteAddressCount))
|
||||
|
||||
#define FIX_REF_BUF_ADDR(addr, base) addr = (VOID *) ((UINTN) (addr) - (UINTN) (base))
|
||||
#define UNFIX_REF_BUF_ADDR(addr, base) addr = (VOID *) ((UINTN) (addr) + (UINTN) (base))
|
||||
|
||||
//
|
||||
// The data structure used to store the genernall information of IPsec configuration.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 VariableCount; // the total number of the IPsecConfig variables.
|
||||
UINT32 VariableSize; // The total size of all IpsecConfig variables.
|
||||
UINT32 SingleVariableSize; // The max size of single variable
|
||||
} IP_SEC_VARIABLE_INFO;
|
||||
|
||||
typedef struct {
|
||||
EFI_IPSEC_CONFIG_SELECTOR *Selector;
|
||||
VOID *Data;
|
||||
LIST_ENTRY List;
|
||||
} IPSEC_COMMON_POLICY_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
UINT8 *Ptr;
|
||||
UINTN Size;
|
||||
UINTN Capacity;
|
||||
} IPSEC_VARIABLE_BUFFER;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT16 Size;
|
||||
} IPSEC_VAR_ITEM_HEADER;
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
The prototype of Copy Source Selector to the Destination Selector.
|
||||
|
||||
@param[in out] DstSel Pointer of Destination Selector. It would be
|
||||
SPD Selector, or SAD Selector or PAD Selector.
|
||||
@param[in] SrcSel Pointer of Source Selector. It would be
|
||||
SPD Selector, or SAD Selector or PAD Selector.
|
||||
@param[in out] Size The size of the Destination Selector. If it
|
||||
is not NULL and its value is less than the size of
|
||||
Source Selector, the value of Source Selector's
|
||||
size will be passed to the caller by this parameter.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER If the Destination or Source Selector is NULL.
|
||||
@retval EFI_BUFFER_TOO_SMALL If the input Size is less than size of Source Selector.
|
||||
@retval EFI_SUCCESS Copy Source Selector to the Destination
|
||||
Selector successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*IPSEC_DUPLICATE_SELECTOR) (
|
||||
IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,
|
||||
IN OUT UINTN *Size
|
||||
);
|
||||
|
||||
/**
|
||||
It is prototype of compare two Selectors. The Selector would be SPD Selector,
|
||||
or SAD Selector, or PAD selector.
|
||||
|
||||
@param[in] Selector1 Pointer of the first Selector.
|
||||
@param[in] Selector2 Pointer of the second Selector.
|
||||
|
||||
@retval TRUE These two Selectors have the same value in certain fields.
|
||||
@retval FALSE Not all fields have the same value in these two Selectors.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(*IPSEC_COMPARE_SELECTOR) (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
|
||||
);
|
||||
|
||||
/**
|
||||
The prototype of a function to check if the Selector is Zero by its certain fields.
|
||||
|
||||
@param[in] Selector Pointer of the Selector.
|
||||
|
||||
@retval TRUE If the Selector is Zero.
|
||||
@retval FALSE If the Selector is not Zero.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(*IPSEC_IS_ZERO_SELECTOR) (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector
|
||||
);
|
||||
|
||||
/**
|
||||
The prototype of a function to fix the value of particular members of the Selector.
|
||||
|
||||
@param[in] Selector Pointer of Selector.
|
||||
@param[in] Data Pointer of Data.
|
||||
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(*IPSEC_FIX_POLICY_ENTRY) (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
It is prototype function to define a routine function by the caller of IpSecVisitConfigData().
|
||||
|
||||
@param[in] Type A specified IPSEC_CONFIG_DATA_TYPE.
|
||||
@param[in] Selector Points to EFI_IPSEC_CONFIG_SELECTOR to be copied
|
||||
to the buffer.
|
||||
@param[in] Data Points to data to be copied to the buffer. The
|
||||
Data type is related to the Type.
|
||||
@param[in] SelectorSize The size of the Selector.
|
||||
@param[in] DataSize The size of the Data.
|
||||
@param[in out] Buffer The buffer to store the Selector and Data.
|
||||
|
||||
@retval EFI_SUCCESS Copied the Selector and Data to a buffer successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*IPSEC_COPY_POLICY_ENTRY) (
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE Type,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN UINTN SelectorSize,
|
||||
IN UINTN DataSize,
|
||||
IN OUT VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Set the security policy information for the EFI IPsec driver.
|
||||
|
||||
The IPsec configuration data has a unique selector/identifier separately to
|
||||
identify a data entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector on operated
|
||||
configuration data specified by DataType.
|
||||
A NULL Selector causes the entire specified-type
|
||||
configuration information to be flushed.
|
||||
@param[in] Data The data buffer to be set.
|
||||
@param[in] Context Pointer to one entry selector that describes
|
||||
the expected position the new data entry will
|
||||
be added. If Context is NULL, the new entry will
|
||||
be appended to the end of the database.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Certain Parameters are not correct. The Parameter
|
||||
requiring a check depends on the Selector type.
|
||||
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*IPSEC_SET_POLICY_ENTRY) (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN VOID *Context OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
A prototype function definition to lookup the data entry from IPsec. Return the configuration
|
||||
value of the specified Entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector that is an identifier
|
||||
of the entry.
|
||||
@param[in, out] DataSize On output, the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the IPsec
|
||||
configuration data. The type of the data buffer
|
||||
is associated with the DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_INVALID_PARAMETER Data is NULL and *DataSize is not zero.
|
||||
@retval EFI_NOT_FOUND The configuration data specified by Selector is not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been
|
||||
updated with the size needed to complete the request.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*IPSEC_GET_POLICY_ENTRY) (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN OUT UINTN *DataSize,
|
||||
IN VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Compare two SPD Selectors.
|
||||
|
||||
Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/
|
||||
NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the
|
||||
Local Addresses and remote Addresses.
|
||||
|
||||
@param[in] Selector1 Pointer of the first SPD Selector.
|
||||
@param[in] Selector2 Pointer of the second SPD Selector.
|
||||
|
||||
@retval TRUE These two Selectors have the same value in above fields.
|
||||
@retval FALSE Not all of the above fields have the same value in these two Selectors.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CompareSpdSelector (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Visit all IPsec Configurations of specified Type and call the caller defined
|
||||
interface.
|
||||
|
||||
@param[in] DataType The specified IPsec Config Data Type.
|
||||
@param[in] Routine The function caller defined.
|
||||
@param[in] Context The data passed to the Routine.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS This function complete successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecVisitConfigData (
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN IPSEC_COPY_POLICY_ENTRY Routine,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
This function is the subfunction of the EFIIpSecConfigSetData.
|
||||
|
||||
This function call IpSecSetVaraible to set the IPsec Configuration into the firmware.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS Saved the configration successfully.
|
||||
@retval Others Other errors were found while obtaining the variable.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecConfigSave (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize IPsecConfig protocol
|
||||
|
||||
@param[in, out] Private Pointer to IPSEC_PRIVATE_DATA. After this function finish,
|
||||
the pointer of IPsecConfig Protocol implementation will copy
|
||||
into its IPsecConfig member.
|
||||
|
||||
@retval EFI_SUCCESS Initialized the IPsecConfig Protocol successfully.
|
||||
@retval Others Initializing the IPsecConfig Protocol failed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecConfigInitialize (
|
||||
IN OUT IPSEC_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
Calculate the entire size of EFI_IPSEC_SPD_DATA, which includes the buffer size pointed
|
||||
by the pointer members.
|
||||
|
||||
@param[in] SpdData Pointer to a specified EFI_IPSEC_SPD_DATA.
|
||||
|
||||
@return The entire size of the specified EFI_IPSEC_SPD_DATA.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetSizeOfEfiSpdData (
|
||||
IN EFI_IPSEC_SPD_DATA *SpdData
|
||||
);
|
||||
|
||||
/**
|
||||
Calculate the a entire size of IPSEC_SPD_DATA, which includes the buffer size pointed
|
||||
by the pointer members and the buffer size used by Sa List.
|
||||
|
||||
@param[in] SpdData Pointer to the specified IPSEC_SPD_DATA.
|
||||
|
||||
@return The entire size of IPSEC_SPD_DATA.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetSizeOfSpdData (
|
||||
IN IPSEC_SPD_DATA *SpdData
|
||||
);
|
||||
|
||||
/**
|
||||
Copy Source Process Policy to the Destination Process Policy.
|
||||
|
||||
@param[in] Dst Pointer to the Source Process Policy.
|
||||
@param[in] Src Pointer to the Destination Process Policy.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDuplicateProcessPolicy (
|
||||
IN EFI_IPSEC_PROCESS_POLICY *Dst,
|
||||
IN EFI_IPSEC_PROCESS_POLICY *Src
|
||||
);
|
||||
|
||||
/**
|
||||
Compare two SPD Selectors.
|
||||
|
||||
Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/
|
||||
NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the
|
||||
Local Addresses and remote Addresses.
|
||||
|
||||
@param[in] Selector1 Pointer of the first SPD Selector.
|
||||
@param[in] Selector2 Pointer of the second SPD Selector.
|
||||
|
||||
@retval TRUE This two Selector have the same value in above fields.
|
||||
@retval FALSE Not all of the above fields have the same value in these two Selectors.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CompareSpdSelector (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
|
||||
);
|
||||
|
||||
/**
|
||||
Compare two SA IDs.
|
||||
|
||||
@param[in] Selector1 Pointer of the first SA ID.
|
||||
@param[in] Selector2 Pointer of the second SA ID.
|
||||
|
||||
@retval TRUE This two Selectors have the same SA ID.
|
||||
@retval FALSE This two Selecotrs don't have the same SA ID.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CompareSaId (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
|
||||
);
|
||||
|
||||
/**
|
||||
Compare two PAD IDs.
|
||||
|
||||
@param[in] Selector1 Pointer of the first PAD ID.
|
||||
@param[in] Selector2 Pointer of the second PAD ID.
|
||||
|
||||
@retval TRUE This two Selectors have the same PAD ID.
|
||||
@retval FALSE This two Selecotrs don't have the same PAD ID.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
ComparePadId (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
|
||||
);
|
||||
|
||||
/**
|
||||
Check if the SPD Selector is Zero by its LocalAddressCount and RemoteAddressCount
|
||||
fields.
|
||||
|
||||
@param[in] Selector Pointer of the SPD Selector.
|
||||
|
||||
@retval TRUE If the SPD Selector is Zero.
|
||||
@retval FALSE If the SPD Selector is not Zero.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsZeroSpdSelector (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector
|
||||
);
|
||||
|
||||
/**
|
||||
Check if the SA ID is Zero by its DestAddress.
|
||||
|
||||
@param[in] Selector Pointer of the SA ID.
|
||||
|
||||
@retval TRUE If the SA ID is Zero.
|
||||
@retval FALSE If the SA ID is not Zero.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsZeroSaId (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector
|
||||
);
|
||||
|
||||
/**
|
||||
Check if the PAD ID is Zero.
|
||||
|
||||
@param[in] Selector Pointer of the PAD ID.
|
||||
|
||||
@retval TRUE If the PAD ID is Zero.
|
||||
@retval FALSE If the PAD ID is not Zero.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsZeroPadId (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector
|
||||
);
|
||||
|
||||
/**
|
||||
Copy Source SPD Selector to the Destination SPD Selector.
|
||||
|
||||
@param[in, out] DstSel Pointer of Destination SPD Selector.
|
||||
@param[in] SrcSel Pointer of Source SPD Selector.
|
||||
@param[in, out] Size The size of the Destination SPD Selector. If
|
||||
it is not NULL and its value is less than the
|
||||
size of Source SPD Selector, the value of
|
||||
Source SPD Selector's size will be passed to
|
||||
the caller by this parameter.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER If the Destination or Source SPD Selector is NULL.
|
||||
@retval EFI_BUFFER_TOO_SMALL If the input Size is less than size of Source SPD Selector.
|
||||
@retval EFI_SUCCESS Copy Source SPD Selector to the Destination SPD
|
||||
Selector successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DuplicateSpdSelector (
|
||||
IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,
|
||||
IN OUT UINTN *Size
|
||||
);
|
||||
|
||||
/**
|
||||
Copy Source SA ID to the Destination SA ID.
|
||||
|
||||
@param[in, out] DstSel Pointer of the Destination SA ID.
|
||||
@param[in] SrcSel Pointer of the Source SA ID.
|
||||
@param[in, out] Size The size of the Destination SA ID. If it
|
||||
not NULL, and its value is less than the size of
|
||||
Source SA ID, the value of Source SA ID's size
|
||||
will be passed to the caller by this parameter.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER If the Destination or Source SA ID is NULL.
|
||||
@retval EFI_BUFFER_TOO_SMALL If the input Size less than size of source SA ID.
|
||||
@retval EFI_SUCCESS Copied Source SA ID to the Destination SA ID successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DuplicateSaId (
|
||||
IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,
|
||||
IN OUT UINTN *Size
|
||||
);
|
||||
|
||||
/**
|
||||
Copy Source PAD ID to the Destination PAD ID.
|
||||
|
||||
@param[in, out] DstSel Pointer of Destination PAD ID.
|
||||
@param[in] SrcSel Pointer of Source PAD ID.
|
||||
@param[in, out] Size The size of the Destination PAD ID. If it
|
||||
not NULL, and its value less than the size of
|
||||
Source PAD ID, the value of Source PAD ID's size
|
||||
will be passed to the caller by this parameter.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER If the Destination or Source PAD ID is NULL.
|
||||
@retval EFI_BUFFER_TOO_SMALL If the input Size less than size of source PAD ID.
|
||||
@retval EFI_SUCCESS Copied Source PAD ID to the Destination PAD ID successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DuplicatePadId (
|
||||
IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,
|
||||
IN OUT UINTN *Size
|
||||
);
|
||||
|
||||
/**
|
||||
Fix the value of some members of the SPD Selector.
|
||||
|
||||
This function is called by IpSecCopyPolicyEntry(), which copies the Policy
|
||||
Entry into the Variable. Since some members in SPD Selector are pointers,
|
||||
a physical address to relative address conversion is required before copying
|
||||
this SPD entry into the variable.
|
||||
|
||||
@param[in] Selector Pointer of SPD Selector.
|
||||
@param[in, out] Data Pointer of SPD Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
FixSpdEntry (
|
||||
IN EFI_IPSEC_SPD_SELECTOR *Selector,
|
||||
IN OUT EFI_IPSEC_SPD_DATA *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Fix the value of some members of SA ID.
|
||||
|
||||
This function is called by IpSecCopyPolicyEntry(), which copies the Policy
|
||||
Entry into the Variable. Since some members in SA ID are pointers,
|
||||
a physical address to relative address conversion is required before copying
|
||||
this SAD into the variable.
|
||||
|
||||
@param[in] SaId Pointer of SA ID.
|
||||
@param[in, out] Data Pointer of SA Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
FixSadEntry (
|
||||
IN EFI_IPSEC_SA_ID *SaId,
|
||||
IN OUT EFI_IPSEC_SA_DATA *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Fix the value of some members of PAD ID.
|
||||
|
||||
This function is called by IpSecCopyPolicyEntry(), which copy the Policy
|
||||
Entry into the Variable. Since some members in PAD ID are pointers,
|
||||
a physical address to relative address conversion is required before copying
|
||||
this PAD into the variable.
|
||||
|
||||
@param[in] PadId Pointer of PAD ID.
|
||||
@param[in, out] Data Pointer of PAD Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
FixPadEntry (
|
||||
IN EFI_IPSEC_PAD_ID *PadId,
|
||||
IN OUT EFI_IPSEC_PAD_DATA *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Recover the value of some members of SPD Selector.
|
||||
|
||||
This function is corresponding to FixSpdEntry(). It recovers the value of members
|
||||
of SPD Selector which fix by the FixSpdEntry().
|
||||
|
||||
@param[in, out] Selector Pointer of SPD Selector.
|
||||
@param[in, out] Data Pointer of SPD Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UnfixSpdEntry (
|
||||
IN OUT EFI_IPSEC_SPD_SELECTOR *Selector,
|
||||
IN OUT EFI_IPSEC_SPD_DATA *Data
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Recover the value of some members of SA ID.
|
||||
|
||||
This function is corresponding to FixSadEntry(). It recovers the value of members
|
||||
of SAD ID which fix by the FixSadEntry().
|
||||
|
||||
@param[in, out] SaId Pointer of SAD ID
|
||||
@param[in, out] Data Pointer of SAD Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UnfixSadEntry (
|
||||
IN OUT EFI_IPSEC_SA_ID *SaId,
|
||||
IN OUT EFI_IPSEC_SA_DATA *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Recover the value of some members of PAD ID.
|
||||
|
||||
This function is corresponding to FixPadEntry(). It recovers the value of members
|
||||
of PAD ID which fix by the FixPadEntry().
|
||||
|
||||
@param[in] PadId Pointer of PAD ID
|
||||
@param[in, out] Data Pointer of PAD Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UnfixPadEntry (
|
||||
IN EFI_IPSEC_PAD_ID *PadId,
|
||||
IN OUT EFI_IPSEC_PAD_DATA *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Set the security policy information for the EFI IPsec driver.
|
||||
|
||||
The IPsec configuration data has a unique selector/identifier separately to
|
||||
identify a data entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector on operated
|
||||
configuration data specified by DataType.
|
||||
A NULL Selector causes the entire specified-type
|
||||
configuration information to be flushed.
|
||||
@param[in] Data The data buffer to be set. The structure
|
||||
of the data buffer should be EFI_IPSEC_SPD_DATA.
|
||||
@param[in] Context Pointer to one entry selector that describes
|
||||
the expected position the new data entry will
|
||||
be added. If Context is NULL,the new entry will
|
||||
be appended the end of database.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
|
||||
- Selector is not NULL and its LocalAddress
|
||||
is NULL or its RemoteAddress is NULL.
|
||||
- Data is not NULL, its Action is Protected,
|
||||
and its policy is NULL.
|
||||
- Data is not NULL and its Action is not protected
|
||||
and its policy is not NULL.
|
||||
- The Action of Data is Protected, its policy
|
||||
mode is Tunnel, and its tunnel option is NULL.
|
||||
- The Action of Data is protected, its policy
|
||||
mode is not Tunnel, and it tunnel option is not NULL.
|
||||
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetSpdEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN VOID *Context OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Set the security association information for the EFI IPsec driver.
|
||||
|
||||
The IPsec configuration data has a unique selector/identifier separately to
|
||||
identify a data entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector on operated
|
||||
configuration data specified by DataType.
|
||||
A NULL Selector causes the entire specified-type
|
||||
configuration information to be flushed.
|
||||
@param[in] Data The data buffer to be set. The structure
|
||||
of the data buffer should be EFI_IPSEC_SA_DATA.
|
||||
@param[in] Context Pointer to one entry selector which describes
|
||||
the expected position the new data entry will
|
||||
be added. If Context is NULL,the new entry will
|
||||
be appended to the end of database.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetSadEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN VOID *Context OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Set the peer authorization configuration information for the EFI IPsec driver.
|
||||
|
||||
The IPsec configuration data has a unique selector/identifier separately to
|
||||
identify a data entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector on operated
|
||||
configuration data specified by DataType.
|
||||
A NULL Selector causes the entire specified-type
|
||||
configuration information to be flushed.
|
||||
@param[in] Data The data buffer to be set. The structure
|
||||
of the data buffer should be EFI_IPSEC_PAD_DATA.
|
||||
@param[in] Context Pointer to one entry selector that describes
|
||||
the expected position where the new data entry will
|
||||
be added. If Context is NULL, the new entry will
|
||||
be appended the end of database.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetPadEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN VOID *Context OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This function looks up the data entry from IPsec SPD, and returns the configuration
|
||||
value of the specified SPD Entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector which is an identifier
|
||||
of the SPD entry.
|
||||
@param[in, out] DataSize On output the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the IPsec
|
||||
configuration data. The type of the data buffer
|
||||
is associated with the DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_INVALID_PARAMETER Data is NULL and *DataSize is not zero.
|
||||
@retval EFI_NOT_FOUND The configuration data specified by Selector is not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been
|
||||
updated with the size needed to complete the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetSpdEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
This function looks up the data entry from IPsec SAD and returns the configuration
|
||||
value of the specified SAD Entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector that is an identifier
|
||||
of the SAD entry.
|
||||
@param[in, out] DataSize On output, the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the IPsec
|
||||
configuration data. This type of the data buffer
|
||||
is associated with the DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_NOT_FOUND The configuration data specified by Selector is not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been
|
||||
updated with the size needed to complete the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetSadEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
This function looks up the data entry from IPsec PADand returns the configuration
|
||||
value of the specified PAD Entry.
|
||||
|
||||
@param[in] Selector Pointer to an entry selector that is an identifier
|
||||
of the PAD entry.
|
||||
@param[in, out] DataSize On output the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the IPsec
|
||||
configuration data. This type of the data buffer
|
||||
is associated with the DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_NOT_FOUND The configuration data specified by Selector is not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been
|
||||
updated with the size needed to complete the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetPadEntry (
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Return the configuration value for the EFI IPsec driver.
|
||||
|
||||
This function lookup the data entry from IPsec database or IKEv2 configuration
|
||||
information. The expected data type and unique identification are described in
|
||||
DataType and Selector parameters.
|
||||
|
||||
@param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
|
||||
@param[in] DataType The type of data to retrieve.
|
||||
@param[in] Selector Pointer to an entry selector that is an identifier of the IPsec
|
||||
configuration data entry.
|
||||
@param[in, out] DataSize On output the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the IPsec configuration data.
|
||||
The type of the data buffer is associated with the DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
|
||||
- This is NULL.
|
||||
- Selector is NULL.
|
||||
- DataSize is NULL.
|
||||
- Data is NULL and *DataSize is not zero
|
||||
@retval EFI_NOT_FOUND The configuration data specified by Selector is not found.
|
||||
@retval EFI_UNSUPPORTED The specified DataType is not supported.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been
|
||||
updated with the size needed to complete the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiIpSecConfigGetData (
|
||||
IN EFI_IPSEC_CONFIG_PROTOCOL *This,
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Set the security association, security policy and peer authorization configuration
|
||||
information for the EFI IPsec driver.
|
||||
|
||||
This function is used to set the IPsec configuration information of type DataType for
|
||||
the EFI IPsec driver.
|
||||
The IPsec configuration data has a unique selector/identifier separately to identify
|
||||
a data entry. The selector structure depends on DataType's definition.
|
||||
Using SetData() with a Data of NULL causes the IPsec configuration data entry identified
|
||||
by DataType and Selector to be deleted.
|
||||
|
||||
@param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
|
||||
@param[in] DataType The type of data to be set.
|
||||
@param[in] Selector Pointer to an entry selector on operated configuration data
|
||||
specified by DataType. A NULL Selector causes the entire
|
||||
specified-type configuration information to be flushed.
|
||||
@param[in] Data The data buffer to be set. The structure of the data buffer is
|
||||
associated with the DataType.
|
||||
@param[in] InsertBefore Pointer to one entry selector which describes the expected
|
||||
position the new data entry will be added. If InsertBefore is NULL,
|
||||
the new entry will be appended the end of database.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration entry data was set successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
|
||||
- This is NULL.
|
||||
@retval EFI_UNSUPPORTED The specified DataType is not supported.
|
||||
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiIpSecConfigSetData (
|
||||
IN EFI_IPSEC_CONFIG_PROTOCOL *This,
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
|
||||
IN VOID *Data,
|
||||
IN EFI_IPSEC_CONFIG_SELECTOR *InsertBefore OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Enumerates the current selector for IPsec configuration data entry.
|
||||
|
||||
This function is called multiple times to retrieve the entry Selector in IPsec
|
||||
configuration database. On each call to GetNextSelector(), the next entry
|
||||
Selector are retrieved into the output interface.
|
||||
|
||||
If the entire IPsec configuration database has been iterated, the error
|
||||
EFI_NOT_FOUND is returned.
|
||||
If the Selector buffer is too small for the next Selector copy, an
|
||||
EFI_BUFFER_TOO_SMALL error is returned, and SelectorSize is updated to reflect
|
||||
the size of buffer needed.
|
||||
|
||||
On the initial call to GetNextSelector() to start the IPsec configuration database
|
||||
search, a pointer to the buffer with all zero value is passed in Selector. Calls
|
||||
to SetData() between calls to GetNextSelector may produce unpredictable results.
|
||||
|
||||
@param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
|
||||
@param[in] DataType The type of IPsec configuration data to retrieve.
|
||||
@param[in, out] SelectorSize The size of the Selector buffer.
|
||||
@param[in, out] Selector On input, supplies the pointer to last Selector that was
|
||||
returned by GetNextSelector().
|
||||
On output, returns one copy of the current entry Selector
|
||||
of a given DataType.
|
||||
|
||||
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
|
||||
- This is NULL.
|
||||
- SelectorSize is NULL.
|
||||
- Selector is NULL.
|
||||
@retval EFI_NOT_FOUND The next configuration data entry was not found.
|
||||
@retval EFI_UNSUPPORTED The specified DataType is not supported.
|
||||
@retval EFI_BUFFER_TOO_SMALL The SelectorSize is too small for the result. This parameter
|
||||
has been updated with the size needed to complete the search
|
||||
request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiIpSecConfigGetNextSelector (
|
||||
IN EFI_IPSEC_CONFIG_PROTOCOL *This,
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN OUT UINTN *SelectorSize,
|
||||
IN OUT EFI_IPSEC_CONFIG_SELECTOR *Selector
|
||||
);
|
||||
|
||||
/**
|
||||
Register an event that is to be signaled whenever a configuration process on the
|
||||
specified IPsec configuration information is done.
|
||||
|
||||
The register function is not surpport now and always returns EFI_UNSUPPORTED.
|
||||
|
||||
@param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
|
||||
@param[in] DataType The type of data to be registered the event for.
|
||||
@param[in] Event The event to be registered.
|
||||
|
||||
@retval EFI_SUCCESS The event is registered successfully.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL, or Event is NULL.
|
||||
@retval EFI_ACCESS_DENIED The Event is already registered for the DataType.
|
||||
@retval EFI_UNSUPPORTED The notify registration unsupported, or the specified
|
||||
DataType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiIpSecConfigRegisterNotify (
|
||||
IN EFI_IPSEC_CONFIG_PROTOCOL *This,
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN EFI_EVENT Event
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Remove the specified event that was previously registered on the specified IPsec
|
||||
configuration data.
|
||||
|
||||
This function is not supported now and always returns EFI_UNSUPPORTED.
|
||||
|
||||
@param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
|
||||
@param[in] DataType The configuration data type to remove the registered event for.
|
||||
@param[in] Event The event to be unregistered.
|
||||
|
||||
@retval EFI_SUCCESS The event was removed successfully.
|
||||
@retval EFI_NOT_FOUND The Event specified by DataType could not be found in the
|
||||
database.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
|
||||
@retval EFI_UNSUPPORTED The notify registration unsupported or the specified
|
||||
DataType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiIpSecConfigUnregisterNotify (
|
||||
IN EFI_IPSEC_CONFIG_PROTOCOL *This,
|
||||
IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
|
||||
IN EFI_EVENT Event
|
||||
);
|
||||
|
||||
#endif
|
133
NetworkPkg/IpSecDxe/IpSecCryptIo.c
Normal file
133
NetworkPkg/IpSecDxe/IpSecCryptIo.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/** @file
|
||||
Common operation for Security.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "IpSecCryptIo.h"
|
||||
//
|
||||
// Alogrithm's informations for the Encrypt/Decrpt Alogrithm.
|
||||
//
|
||||
ENCRYPT_ALGORITHM mIpsecEncryptAlgorithmList[IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE] = {
|
||||
{EFI_IPSEC_EALG_NULL, 0, 0, 1, NULL, NULL, NULL, NULL},
|
||||
{(UINT8)-1, 0, 0, 0, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
//
|
||||
// Alogrithm's informations for the Authentication algorithm
|
||||
//
|
||||
AUTH_ALGORITHM mIpsecAuthAlgorithmList[IPSEC_AUTH_ALGORITHM_LIST_SIZE] = {
|
||||
{EFI_IPSEC_AALG_NONE, 0, 0, 0, NULL, NULL, NULL, NULL},
|
||||
{EFI_IPSEC_AALG_NULL, 0, 0, 0, NULL, NULL, NULL, NULL},
|
||||
{(UINT8)-1, 0, 0, 0, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Get the block size of encrypt alogrithm. The block size is based on the algorithm used.
|
||||
|
||||
@param[in] AlgorithmId The encrypt algorithm ID.
|
||||
|
||||
@return The value of block size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetEncryptBlockSize (
|
||||
IN UINT8 AlgorithmId
|
||||
)
|
||||
{
|
||||
UINT8 Index;
|
||||
|
||||
for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
|
||||
if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
|
||||
//
|
||||
// The BlockSize is same with IvSize.
|
||||
//
|
||||
return mIpsecEncryptAlgorithmList[Index].BlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
return (UINTN) -1;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the IV size of encrypt alogrithm. The IV size is based on the algorithm used.
|
||||
|
||||
@param[in] AlgorithmId The encrypt algorithm ID.
|
||||
|
||||
@return The value of IV size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetEncryptIvLength (
|
||||
IN UINT8 AlgorithmId
|
||||
)
|
||||
{
|
||||
UINT8 Index;
|
||||
|
||||
for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
|
||||
if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
|
||||
//
|
||||
// The BlockSize is same with IvSize.
|
||||
//
|
||||
return mIpsecEncryptAlgorithmList[Index].IvLength;
|
||||
}
|
||||
}
|
||||
|
||||
return (UINTN) -1;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the ICV size of Authenticaion alogrithm. The ICV size is based on the algorithm used.
|
||||
|
||||
@param[in] AuthAlgorithmId The Authentication algorithm ID.
|
||||
|
||||
@return The value of ICV size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetIcvLength (
|
||||
IN UINT8 AuthAlgorithmId
|
||||
)
|
||||
{
|
||||
UINT8 Index;
|
||||
for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {
|
||||
if (AuthAlgorithmId == mIpsecAuthAlgorithmList[Index].AlgorithmId) {
|
||||
return mIpsecAuthAlgorithmList[Index].IcvLength;
|
||||
}
|
||||
}
|
||||
return (UINTN) -1;
|
||||
}
|
||||
|
||||
/**
|
||||
Generate a random data for IV. If the IvSize is zero, not needed to create
|
||||
IV and return EFI_SUCCESS.
|
||||
|
||||
@param[in] IvBuffer The pointer of the IV buffer.
|
||||
@param[in] IvSize The IV size.
|
||||
|
||||
@retval EFI_SUCCESS Create a random data for IV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecGenerateIv (
|
||||
IN UINT8 *IvBuffer,
|
||||
IN UINTN IvSize
|
||||
)
|
||||
{
|
||||
if (IvSize != 0) {
|
||||
//
|
||||
//TODO: return CryptGenerateRandom (IvBuffer, IvSize);
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
322
NetworkPkg/IpSecDxe/IpSecCryptIo.h
Normal file
322
NetworkPkg/IpSecDxe/IpSecCryptIo.h
Normal file
@@ -0,0 +1,322 @@
|
||||
/** @file
|
||||
Definition related to the Security operation.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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 _EFI_IPSEC_CRYPTIO_H_
|
||||
#define _EFI_IPSEC_CRYPTIO_H_
|
||||
|
||||
#include <Protocol/IpSecConfig.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#define IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE 2
|
||||
#define IPSEC_AUTH_ALGORITHM_LIST_SIZE 3
|
||||
|
||||
/**
|
||||
Prototype of Hash GetContextSize.
|
||||
|
||||
Retrieves the size, in bytes, of the context buffer required.
|
||||
|
||||
@return The size, in bytes, of the context buffer required.
|
||||
|
||||
**/
|
||||
typedef
|
||||
UINTN
|
||||
(EFIAPI *CPL_HASH_GETCONTEXTSIZE) (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Prototype of Hash Operation Initiating.
|
||||
|
||||
Initialization with a new context.
|
||||
|
||||
|
||||
@param[in,out] Context Input Context.
|
||||
|
||||
@retval TRUE Initialization Successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *CPL_HASH_INIT) (
|
||||
IN OUT VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Prototype of HASH update.
|
||||
Hash update operation. Continue an Hash message digest operation, processing
|
||||
another message block, and updating the Hash context.
|
||||
|
||||
If Context is NULL, then ASSERT().
|
||||
If Data is NULL, then ASSERT().
|
||||
|
||||
@param[in,out] Context The Specified Context.
|
||||
@param[in,out] Data The Input Data to hash.
|
||||
@param[in] DataLength The length, in bytes, of Data.
|
||||
|
||||
@retval TRUE Update data successfully.
|
||||
@retval FALSE The Context has been finalized.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *CPL_HASH_UPDATE) (
|
||||
IN OUT VOID *Context,
|
||||
IN CONST VOID *Data,
|
||||
IN UINTN DataLength
|
||||
);
|
||||
|
||||
/**
|
||||
Prototype of Hash finallization.
|
||||
Terminate a Hash message digest operation and output the message digest.
|
||||
|
||||
If Context is NULL, then ASSERT().
|
||||
If HashValue is NULL, then ASSERT().
|
||||
|
||||
@param[in,out] Context The specified Context.
|
||||
@param[out] HashValue Pointer to a 16-byte message digest output buffer.
|
||||
|
||||
@retval TRUE Finalized successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *CPL_HASH_FINAL) (
|
||||
IN OUT VOID *Context,
|
||||
OUT UINT8 *HashValue
|
||||
);
|
||||
|
||||
/**
|
||||
Prototype of Cipher GetContextSize.
|
||||
|
||||
Retrieves the size, in bytes, of the context buffer required.
|
||||
|
||||
@return The size, in bytes, of the context buffer required.
|
||||
|
||||
**/
|
||||
typedef
|
||||
UINTN
|
||||
(EFIAPI *CPL_CIPHER_GETCONTEXTSIZE) (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Prototype of Cipher initiation.
|
||||
Intializes the user-supplied key as the specifed context (key materials) for both
|
||||
encryption and decryption operations.
|
||||
|
||||
If Context is NULL, then ASSERT().
|
||||
If Key is NULL, then generate random key for usage.
|
||||
|
||||
@param[in,out] Context The specified Context.
|
||||
@param[in] Key User-supplied TDES key (64/128/192 bits).
|
||||
@param[in] KeyBits Key length in bits.
|
||||
|
||||
@retval TRUE TDES Initialization was successful.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *CPL_CIPHER_INIT) (
|
||||
IN OUT VOID *Context,
|
||||
IN CONST UINT8 *Key,
|
||||
IN CONST UINTN KeyBits
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Prototype of Cipher encryption.
|
||||
Encrypts plaintext message with the specified cipher.
|
||||
|
||||
If Context is NULL, then ASSERT().
|
||||
if InData is NULL, then ASSERT().
|
||||
If Size of input data is not multiple of Cipher algorithm related block size,
|
||||
then ASSERT().
|
||||
|
||||
@param[in] Context The specified Context.
|
||||
@param[in] InData The input plaintext data to be encrypted.
|
||||
@param[out] OutData The resultant encrypted ciphertext.
|
||||
@param[in] DataLength Length of input data in bytes.
|
||||
|
||||
@retval TRUE Encryption successful.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *CPL_CIPHER_ENCRYPT) (
|
||||
IN VOID *Context,
|
||||
IN CONST UINT8 *InData,
|
||||
OUT UINT8 *OutData,
|
||||
IN CONST UINTN DataLength
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Prototype of Cipher decryption.
|
||||
Decrypts cipher message with specified cipher.
|
||||
|
||||
If Context is NULL, then ASSERT().
|
||||
if InData is NULL, then ASSERT().
|
||||
If Size of input data is not a multiple of a certaion block size , then ASSERT().
|
||||
|
||||
@param[in] Context The specified Context.
|
||||
@param[in] InData The input ciphertext data to be decrypted.
|
||||
@param[out] OutData The resultant decrypted plaintext.
|
||||
@param[in] DataLength Length of input data in bytes.
|
||||
|
||||
@retval TRUE Decryption successful.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *CPL_CIPHER_DECRYPT) (
|
||||
IN CONST VOID *Context,
|
||||
IN CONST UINT8 *InData,
|
||||
OUT UINT8 *OutData,
|
||||
IN CONST UINTN DataLength
|
||||
);
|
||||
|
||||
//
|
||||
// The struct used to store the informatino and operation of Cipher algorithm.
|
||||
//
|
||||
typedef struct _ENCRYPT_ALGORITHM {
|
||||
//
|
||||
// The ID of the Algorithm
|
||||
//
|
||||
UINT8 AlgorithmId;
|
||||
//
|
||||
// The Key length of the Algorithm
|
||||
//
|
||||
UINTN KeyLength;
|
||||
//
|
||||
// Iv Size of the Algorithm
|
||||
//
|
||||
UINTN IvLength;
|
||||
//
|
||||
// The Block Size of the Algorithm
|
||||
//
|
||||
UINTN BlockSize;
|
||||
//
|
||||
// The Function pointer of GetContextSize.
|
||||
//
|
||||
CPL_CIPHER_GETCONTEXTSIZE CipherGetContextSize;
|
||||
//
|
||||
// The Function pointer of Cipher intitiaion.
|
||||
//
|
||||
CPL_CIPHER_INIT CipherInitiate;
|
||||
//
|
||||
// The Function pointer of Cipher Encryption.
|
||||
//
|
||||
CPL_CIPHER_ENCRYPT CipherEncrypt;
|
||||
//
|
||||
// The Function pointer of Cipher Decrption.
|
||||
//
|
||||
CPL_CIPHER_DECRYPT CipherDecrypt;
|
||||
} ENCRYPT_ALGORITHM;
|
||||
|
||||
//
|
||||
// The struct used to store the informatino and operation of Autahentication algorithm.
|
||||
//
|
||||
typedef struct _AUTH_ALGORITHM {
|
||||
//
|
||||
// ID of the Algorithm
|
||||
//
|
||||
UINT8 AlgorithmId;
|
||||
//
|
||||
// The Key length of the Algorithm
|
||||
//
|
||||
UINTN KeyLength;
|
||||
//
|
||||
// The ICV length of the Algorithm
|
||||
//
|
||||
UINTN IcvLength;
|
||||
//
|
||||
// The block size of the Algorithm
|
||||
//
|
||||
UINTN BlockSize;
|
||||
//
|
||||
// The function pointer of GetContextSize.
|
||||
//
|
||||
CPL_HASH_GETCONTEXTSIZE HashGetContextSize;
|
||||
//
|
||||
// The function pointer of Initiatoion
|
||||
//
|
||||
CPL_HASH_INIT HashInitiate;
|
||||
//
|
||||
// The function pointer of Hash Update.
|
||||
//
|
||||
CPL_HASH_UPDATE HashUpdate;
|
||||
//
|
||||
// The fucntion pointer of Hash Final
|
||||
//
|
||||
CPL_HASH_FINAL HashFinal;
|
||||
} AUTH_ALGORITHM;
|
||||
|
||||
/**
|
||||
Get the IV size of encrypt alogrithm. IV size is different from different algorithm.
|
||||
|
||||
@param[in] AlgorithmId The encrypt algorithm ID.
|
||||
|
||||
@return The value of IV size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetEncryptIvLength (
|
||||
IN UINT8 AlgorithmId
|
||||
);
|
||||
|
||||
/**
|
||||
Get the block size of encrypt alogrithm. Block size is different from different algorithm.
|
||||
|
||||
@param[in] AlgorithmId The encrypt algorithm ID.
|
||||
|
||||
@return The value of block size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetEncryptBlockSize (
|
||||
IN UINT8 AlgorithmId
|
||||
);
|
||||
|
||||
/**
|
||||
Get the ICV size of Authenticaion alogrithm. ICV size is different from different algorithm.
|
||||
|
||||
@param[in] AuthAlgorithmId The Authentication algorithm ID.
|
||||
|
||||
@return The value of ICV size.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
IpSecGetIcvLength (
|
||||
IN UINT8 AuthAlgorithmId
|
||||
);
|
||||
|
||||
/**
|
||||
Generate a random data for IV. If the IvSize is zero, not needed to create
|
||||
IV and return EFI_SUCCESS.
|
||||
|
||||
@param[in] IvBuffer The pointer of the IV buffer.
|
||||
@param[in] IvSize The IV size.
|
||||
|
||||
@retval EFI_SUCCESS Create random data for IV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecGenerateIv (
|
||||
IN UINT8 *IvBuffer,
|
||||
IN UINTN IvSize
|
||||
);
|
||||
|
||||
#endif
|
||||
|
172
NetworkPkg/IpSecDxe/IpSecDebug.c
Normal file
172
NetworkPkg/IpSecDxe/IpSecDebug.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/** @file
|
||||
Interface of IPsec printing debug information.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "IpSecImpl.h"
|
||||
#include "IpSecDebug.h"
|
||||
|
||||
//
|
||||
// The print title for IKEv1 variety phase.
|
||||
//
|
||||
CHAR8 *mStateStr[] = {
|
||||
"IKEv1_MAIN_1",
|
||||
"IKEv1_MAIN_2",
|
||||
"IKEv1_MAIN_3",
|
||||
"IKEv1_MAIN_ESTABLISHED",
|
||||
"IKEv1_QUICK_1",
|
||||
"IKEv1_QUICK_2",
|
||||
"IKEv1_QUICK_ESTABLISHED"
|
||||
};
|
||||
//
|
||||
// The print title for IKEv1 variety Exchagne.
|
||||
//
|
||||
CHAR8 *mExchangeStr[] = {
|
||||
"IKEv1 Main Exchange",
|
||||
"IKEv1 Info Exchange",
|
||||
"IKEv1 Quick Exchange",
|
||||
"IKEv1 Unknown Exchange"
|
||||
};
|
||||
|
||||
//
|
||||
// The print title for IKEv1 variety Payload.
|
||||
//
|
||||
CHAR8 *mPayloadStr[] = {
|
||||
"IKEv1 None Payload",
|
||||
"IKEv1 SA Payload",
|
||||
"IKEv1 Proposal Payload",
|
||||
"IKEv1 Transform Payload",
|
||||
"IKEv1 KE Payload",
|
||||
"IKEv1 ID Payload",
|
||||
"IKEv1 Certificate Payload",
|
||||
"IKEv1 Certificate Request Payload",
|
||||
"IKEv1 Hash Payload",
|
||||
"IKEv1 Signature Payload",
|
||||
"IKEv1 Nonce Payload",
|
||||
"IKEv1 Notify Payload",
|
||||
"IKEv1 Delete Payload",
|
||||
"IKEv1 Vendor Payload"
|
||||
};
|
||||
|
||||
/**
|
||||
Print the IP address.
|
||||
|
||||
@param[in] Level Debug print error level. Pass to DEBUG().
|
||||
@param[in] Ip Point to a specified IP address.
|
||||
@param[in] IpVersion The IP Version.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpAddress (
|
||||
IN UINTN Level,
|
||||
IN EFI_IP_ADDRESS *Ip,
|
||||
IN UINT8 IpVersion
|
||||
)
|
||||
{
|
||||
if (IpVersion == IP_VERSION_6) {
|
||||
DEBUG (
|
||||
(Level,
|
||||
"%x%x:%x%x:%x%x:%x%x",
|
||||
Ip->v6.Addr[0],
|
||||
Ip->v6.Addr[1],
|
||||
Ip->v6.Addr[2],
|
||||
Ip->v6.Addr[3],
|
||||
Ip->v6.Addr[4],
|
||||
Ip->v6.Addr[5],
|
||||
Ip->v6.Addr[6],
|
||||
Ip->v6.Addr[7])
|
||||
);
|
||||
DEBUG (
|
||||
(Level,
|
||||
":%x%x:%x%x:%x%x:%x%x\n",
|
||||
Ip->v6.Addr[8],
|
||||
Ip->v6.Addr[9],
|
||||
Ip->v6.Addr[10],
|
||||
Ip->v6.Addr[11],
|
||||
Ip->v6.Addr[12],
|
||||
Ip->v6.Addr[13],
|
||||
Ip->v6.Addr[14],
|
||||
Ip->v6.Addr[15])
|
||||
);
|
||||
} else {
|
||||
DEBUG (
|
||||
(Level,
|
||||
"%d.%d.%d.%d\n",
|
||||
Ip->v4.Addr[0],
|
||||
Ip->v4.Addr[1],
|
||||
Ip->v4.Addr[2],
|
||||
Ip->v4.Addr[3])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Print IKEv1 Current states.
|
||||
|
||||
@param[in] Previous The Previous state of IKEv1.
|
||||
@param[in] Current The current state of IKEv1.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpState (
|
||||
IN UINT32 Previous,
|
||||
IN UINT32 Current
|
||||
)
|
||||
{
|
||||
if (Previous == Current) {
|
||||
DEBUG ((DEBUG_INFO, "\n****Current state is %a\n", mStateStr[Previous]));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "\n****Change state from %a to %a\n", mStateStr[Previous], mStateStr[Current]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Print the buffer in form of Hex.
|
||||
|
||||
@param[in] Title The strings to be printed before the data of the buffer.
|
||||
@param[in] Data Points to buffer to be printed.
|
||||
@param[in] DataSize The size of the buffer to be printed.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpBuf (
|
||||
IN CHAR8 *Title,
|
||||
IN UINT8 *Data,
|
||||
IN UINTN DataSize
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN DataIndex;
|
||||
UINTN BytesRemaining;
|
||||
UINTN BytesToPrint;
|
||||
|
||||
DataIndex = 0;
|
||||
BytesRemaining = DataSize;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "==%a %d bytes==\n", Title, DataSize));
|
||||
|
||||
while (BytesRemaining > 0) {
|
||||
|
||||
BytesToPrint = (BytesRemaining > IPSEC_DEBUG_BYTE_PER_LINE) ? IPSEC_DEBUG_BYTE_PER_LINE : BytesRemaining;
|
||||
|
||||
for (Index = 0; Index < BytesToPrint; Index++) {
|
||||
DEBUG ((DEBUG_INFO, " 0x%02x,", Data[DataIndex++]));
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "\n"));
|
||||
BytesRemaining -= BytesToPrint;
|
||||
}
|
||||
|
||||
}
|
102
NetworkPkg/IpSecDxe/IpSecDebug.h
Normal file
102
NetworkPkg/IpSecDxe/IpSecDebug.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/** @file
|
||||
The definition of functions and MACROs used for IPsec debug information print.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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 _EFI_IPSEC_DEBUG_H_
|
||||
#define _EFI_IPSEC_DEBUG_H_
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#define IPSEC_DUMP_ADDRESS(Level, Ip, Version) IpSecDumpAddress (Level, Ip, Version)
|
||||
#define IPSEC_DUMP_STATE(Previous, Current) IpSecDumpState (Previous, Current)
|
||||
#define IPSEC_DUMP_PACKET(Packet, Direction, IpVersion) IpSecDumpPacket (Packet, Direction, IpVersion)
|
||||
#define IPSEC_DUMP_PAYLOAD(IkePayload) IpSecDumpPayload (IkePayload)
|
||||
#define IPSEC_DUMP_BUF(Title, Data, DataSize) IpSecDumpBuf (Title, Data, DataSize)
|
||||
|
||||
#define IPSEC_DEBUG_BYTE_PER_LINE 8
|
||||
|
||||
|
||||
/**
|
||||
Print the IP address.
|
||||
|
||||
@param[in] Level Debug print error level. Pass to DEBUG().
|
||||
@param[in] Ip Point to specified IP address.
|
||||
@param[in] IpVersion The IP Version.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpAddress (
|
||||
IN UINTN Level,
|
||||
IN EFI_IP_ADDRESS *Ip,
|
||||
IN UINT8 IpVersion
|
||||
);
|
||||
|
||||
/**
|
||||
Print IKEv1 Current states.
|
||||
|
||||
@param[in] Previous The Previous state of IKEv1.
|
||||
@param[in] Current The current state of IKEv1.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpState (
|
||||
IN UINT32 Previous,
|
||||
IN UINT32 Current
|
||||
);
|
||||
|
||||
/**
|
||||
Print the Ike Packet.
|
||||
|
||||
@param[in] Packet Point to IKE packet to be printed.
|
||||
@param[in] Direction Point to the IKE packet is inbound or outbound.
|
||||
@param[in] IpVersion Specified IP Version.
|
||||
|
||||
**/
|
||||
/*
|
||||
VOID
|
||||
IpSecDumpPacket (
|
||||
IN IKE_PACKET *Packet,
|
||||
IN EFI_IPSEC_TRAFFIC_DIR Direction,
|
||||
IN UINT8 IpVersion
|
||||
);
|
||||
*/
|
||||
|
||||
/**
|
||||
Print the IKE Paylolad.
|
||||
|
||||
@param[in] IkePayload Points to the payload to be printed.
|
||||
|
||||
**/
|
||||
/*
|
||||
VOID
|
||||
IpSecDumpPayload (
|
||||
IN IKE_PAYLOAD *IkePayload
|
||||
);
|
||||
*/
|
||||
/**
|
||||
Print the buffer in form of Hex.
|
||||
|
||||
@param[in] Title The strings to be printed before the data of the buffer.
|
||||
@param[in] Data Points to the buffer to be printed.
|
||||
@param[in] DataSize The size of the buffer to be printed.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecDumpBuf (
|
||||
IN CHAR8 *Title,
|
||||
IN UINT8 *Data,
|
||||
IN UINTN DataSize
|
||||
);
|
||||
|
||||
#endif
|
282
NetworkPkg/IpSecDxe/IpSecDriver.c
Normal file
282
NetworkPkg/IpSecDxe/IpSecDriver.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/** @file
|
||||
Driver Binding Protocol for IPsec Driver.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/UdpIoLib.h>
|
||||
#include "IpSecConfigImpl.h"
|
||||
#include "IpSecDebug.h"
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to test.
|
||||
@param[in] RemainingDevicePath Optional parameter used to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCES This driver supports this device.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
//
|
||||
//TODO: Add Udp4Protocol and Udp6Protocol testing.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to bind driver to.
|
||||
@param[in] RemainingDevicePath Optional parameter used to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCES This driver is added to ControllerHandle
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
|
||||
Currently not implemented.
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
//
|
||||
//TODO: Add Udp4Io and Udp6Io creation for the IKE.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of a device to stop the driver on.
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
|
||||
children is zero, stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCES This driver removed ControllerHandle.
|
||||
@retval other This driver was not removed from this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
//
|
||||
//TODO: Add UdpIo4 and UdpIo6 destruction when the Udp driver unload or stop.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {
|
||||
IpSecDriverBindingSupported,
|
||||
IpSecDriverBindingStart,
|
||||
IpSecDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
|
||||
|
||||
@param[in] Event Event whose notification function is being invoked.
|
||||
@param[in] Context Pointer to the notification function's context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
IpSecCleanupAllSa (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
IPSEC_PRIVATE_DATA *Private;
|
||||
UINT8 Value;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Private = (IPSEC_PRIVATE_DATA *) Context;
|
||||
|
||||
//
|
||||
// Set the Status Variable
|
||||
//
|
||||
Value = IPSEC_STATUS_DISABLED;
|
||||
Status = gRT->SetVariable (
|
||||
IPSECCONFIG_STATUS_NAME,
|
||||
&gEfiIpSecConfigProtocolGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
||||
sizeof (Value),
|
||||
&Value
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Private->IpSec.DisabledFlag = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
This is the declaration of an EFI image entry point. This entry point is
|
||||
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
|
||||
both device drivers and bus drivers.
|
||||
|
||||
The entry point for IPsec driver which installs the driver binding,
|
||||
component name protocol, IPsec Config protcolon, and IPsec protocol in
|
||||
its ImageHandle.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The operation is failed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IpSecDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IPSEC_PRIVATE_DATA *Private;
|
||||
EFI_IPSEC_PROTOCOL *IpSec;
|
||||
|
||||
//
|
||||
// Check whether ipsec protocol has already been installed.
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &IpSec);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "_ModuleEntryPoint: IpSec has been already loaded\n"));
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID **) &mDpc);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Private = AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA));
|
||||
|
||||
if (Private == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to allocate private data\n"));
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Create disable event to cleanup all sa when ipsec disabled by user.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
IpSecCleanupAllSa,
|
||||
Private,
|
||||
&mIpSecInstance.DisabledEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to create disable event\n"));
|
||||
goto ON_FREE_PRIVATE;
|
||||
}
|
||||
|
||||
Private->Signature = IPSEC_PRIVATE_DATA_SIGNATURE;
|
||||
Private->ImageHandle = ImageHandle;
|
||||
CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC_PROTOCOL));
|
||||
|
||||
//
|
||||
// Initilize Private's members. Thess members is used for IKE.
|
||||
//
|
||||
InitializeListHead (&Private->Udp4List);
|
||||
InitializeListHead (&Private->Udp6List);
|
||||
InitializeListHead (&Private->Ikev1SessionList);
|
||||
InitializeListHead (&Private->Ikev1EstablishedList);
|
||||
InitializeListHead (&Private->Ikev2SessionList);
|
||||
InitializeListHead (&Private->Ikev2EstablishedList);
|
||||
|
||||
//
|
||||
// Initialize the ipsec config data and restore it from variable.
|
||||
//
|
||||
Status = IpSecConfigInitialize (Private);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
|
||||
goto ON_CLOSE_EVENT;
|
||||
}
|
||||
//
|
||||
// Install ipsec protocol which is used by ip driver to process ipsec header.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Private->Handle,
|
||||
&gEfiIpSecProtocolGuid,
|
||||
&Private->IpSec,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_UNINSTALL_CONFIG;
|
||||
}
|
||||
|
||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gIpSecDriverBinding,
|
||||
ImageHandle,
|
||||
&gIpSecComponentName,
|
||||
&gIpSecComponentName2
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_UNINSTALL_CONFIG;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
ON_UNINSTALL_CONFIG:
|
||||
gBS->UninstallProtocolInterface (
|
||||
Private->Handle,
|
||||
&gEfiIpSecConfigProtocolGuid,
|
||||
&Private->IpSecConfig
|
||||
);
|
||||
ON_CLOSE_EVENT:
|
||||
gBS->CloseEvent (mIpSecInstance.DisabledEvent);
|
||||
mIpSecInstance.DisabledEvent = NULL;
|
||||
ON_FREE_PRIVATE:
|
||||
FreePool (Private);
|
||||
ON_EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
63
NetworkPkg/IpSecDxe/IpSecDxe.inf
Normal file
63
NetworkPkg/IpSecDxe/IpSecDxe.inf
Normal file
@@ -0,0 +1,63 @@
|
||||
## @file
|
||||
# Component description file for IpSec module.
|
||||
#
|
||||
# Copyright (c) 2009 - 2010, 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = IpSecDxe
|
||||
FILE_GUID = EE8367C0-A1D6-4565-8F89-EF628547B722
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = IpSecDriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
IpSecConfigImpl.c
|
||||
IpSecConfigImpl.h
|
||||
IpSecCryptIo.h
|
||||
IpSecCryptIo.c
|
||||
IpSecDebug.h
|
||||
ComponentName.c
|
||||
IpSecImpl.c
|
||||
IpSecDebug.c
|
||||
IpSecSaEngine.c
|
||||
IpSecDriver.c
|
||||
IpSecImpl.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
DpcLib
|
||||
NetLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ConfigProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIpSecConfigProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiIpSecProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
856
NetworkPkg/IpSecDxe/IpSecImpl.c
Normal file
856
NetworkPkg/IpSecDxe/IpSecImpl.c
Normal file
@@ -0,0 +1,856 @@
|
||||
/** @file
|
||||
The implementation of IPsec Protocol
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "IpSecConfigImpl.h"
|
||||
|
||||
EFI_IPSEC_PROTOCOL mIpSecInstance = { IpSecProcess, NULL, TRUE };
|
||||
|
||||
extern LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];
|
||||
|
||||
/**
|
||||
Check if the specified Address is the Valid Address Range.
|
||||
|
||||
This function checks if the bytes after prefixed length are all Zero in this
|
||||
Address. This Address is supposed to point to a range address, meaning it only
|
||||
gives the correct prefixed address.
|
||||
|
||||
@param[in] IpVersion The IP version.
|
||||
@param[in] Address Points to EFI_IP_ADDRESS to be checked.
|
||||
@param[in] PrefixLength The PrefixeLength of this address.
|
||||
|
||||
@retval TRUE The address is a vaild address range.
|
||||
@retval FALSE The address is not a vaild address range.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IpSecValidAddressRange (
|
||||
IN UINT8 IpVersion,
|
||||
IN EFI_IP_ADDRESS *Address,
|
||||
IN UINT8 PrefixLength
|
||||
)
|
||||
{
|
||||
UINT8 Div;
|
||||
UINT8 Mod;
|
||||
UINT8 Mask;
|
||||
UINT8 AddrLen;
|
||||
UINT8 *Addr;
|
||||
EFI_IP_ADDRESS ZeroAddr;
|
||||
|
||||
if (PrefixLength == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
AddrLen = (UINT8) ((IpVersion == IP_VERSION_4) ? 32 : 128);
|
||||
|
||||
if (AddrLen <= PrefixLength) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Div = (UINT8) (PrefixLength / 8);
|
||||
Mod = (UINT8) (PrefixLength % 8);
|
||||
Addr = (UINT8 *) Address;
|
||||
ZeroMem (&ZeroAddr, sizeof (EFI_IP_ADDRESS));
|
||||
|
||||
//
|
||||
// Check whether the mod part of host scope is zero or not.
|
||||
//
|
||||
if (Mod > 0) {
|
||||
Mask = (UINT8) (0xFF << (8 - Mod));
|
||||
|
||||
if ((Addr[Div] | Mask) != Mask) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Div++;
|
||||
}
|
||||
//
|
||||
// Check whether the div part of host scope is zero or not.
|
||||
//
|
||||
if (CompareMem (
|
||||
&Addr[Div],
|
||||
&ZeroAddr,
|
||||
sizeof (EFI_IP_ADDRESS) - Div
|
||||
) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Extrct the Address Range from a Address.
|
||||
|
||||
This function keep the prefix address and zero other part address.
|
||||
|
||||
@param[in] Address Point to a specified address.
|
||||
@param[in] PrefixLength The prefix length.
|
||||
@param[out] Range Contain the return Address Range.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IpSecExtractAddressRange (
|
||||
IN EFI_IP_ADDRESS *Address,
|
||||
IN UINT8 PrefixLength,
|
||||
OUT EFI_IP_ADDRESS *Range
|
||||
)
|
||||
{
|
||||
UINT8 Div;
|
||||
UINT8 Mod;
|
||||
UINT8 Mask;
|
||||
UINT8 *Addr;
|
||||
|
||||
if (PrefixLength == 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
Div = (UINT8) (PrefixLength / 8);
|
||||
Mod = (UINT8) (PrefixLength % 8);
|
||||
Addr = (UINT8 *) Range;
|
||||
|
||||
CopyMem (Range, Address, sizeof (EFI_IP_ADDRESS));
|
||||
|
||||
//
|
||||
// Zero the mod part of host scope.
|
||||
//
|
||||
if (Mod > 0) {
|
||||
Mask = (UINT8) (0xFF << (8 - Mod));
|
||||
Addr[Div] = (UINT8) (Addr[Div] & Mask);
|
||||
Div++;
|
||||
}
|
||||
//
|
||||
// Zero the div part of host scope.
|
||||
//
|
||||
ZeroMem (&Addr[Div], sizeof (EFI_IP_ADDRESS) - Div);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if the IP Address in the address range of AddressInfos specified.
|
||||
|
||||
@param[in] IpVersion The IP version.
|
||||
@param[in] IpAddr Point 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
|
||||
)
|
||||
{
|
||||
EFI_IP_ADDRESS Range;
|
||||
UINT32 Index;
|
||||
BOOLEAN IsMatch;
|
||||
|
||||
IsMatch = FALSE;
|
||||
|
||||
for (Index = 0; Index < AddressCount; Index++) {
|
||||
//
|
||||
// Check whether the target address is in the address range
|
||||
// if it's a valid range of address.
|
||||
//
|
||||
if (IpSecValidAddressRange (
|
||||
IpVersion,
|
||||
&AddressInfo[Index].Address,
|
||||
AddressInfo[Index].PrefixLength
|
||||
)) {
|
||||
//
|
||||
// Get the range of the target address belongs to.
|
||||
//
|
||||
ZeroMem (&Range, sizeof (EFI_IP_ADDRESS));
|
||||
IpSecExtractAddressRange (
|
||||
IpAddr,
|
||||
AddressInfo[Index].PrefixLength,
|
||||
&Range
|
||||
);
|
||||
|
||||
if (CompareMem (
|
||||
&Range,
|
||||
&AddressInfo[Index].Address,
|
||||
sizeof (EFI_IP_ADDRESS)
|
||||
) == 0) {
|
||||
//
|
||||
// The target address is in the address range.
|
||||
//
|
||||
IsMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CompareMem (
|
||||
IpAddr,
|
||||
&AddressInfo[Index].Address,
|
||||
sizeof (EFI_IP_ADDRESS)
|
||||
) == 0) {
|
||||
//
|
||||
// The target address is exact same as the address.
|
||||
//
|
||||
IsMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the specified Protocol and Prot is supported by the specified SPD Entry.
|
||||
|
||||
This function is the subfunction of IPsecLookUpSpdEntry() that is used to
|
||||
check if the sent/received IKE packet has the related SPD entry support.
|
||||
|
||||
@param[in] Protocol The Protocol to be checked.
|
||||
@param[in] IpPayload Point to IP Payload to be check.
|
||||
@param[in] SpdProtocol The Protocol supported by SPD.
|
||||
@param[in] SpdLocalPort The Local Port in SPD.
|
||||
@param[in] SpdRemotePort The Remote Port in SPD.
|
||||
@param[in] IsOutbound Flag to indicate the is for IKE Packet sending or recieving.
|
||||
|
||||
@retval TRUE The Protocol and Port are supported by the SPD Entry.
|
||||
@retval FALSE The Protocol and Port are not supported by the SPD Entry.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IpSecMatchNextLayerProtocol (
|
||||
IN UINT8 Protocol,
|
||||
IN UINT8 *IpPayload,
|
||||
IN UINT16 SpdProtocol,
|
||||
IN UINT16 SpdLocalPort,
|
||||
IN UINT16 SpdRemotePort,
|
||||
IN BOOLEAN IsOutbound
|
||||
)
|
||||
{
|
||||
BOOLEAN IsMatch;
|
||||
|
||||
if (SpdProtocol == EFI_IPSEC_ANY_PROTOCOL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IsMatch = FALSE;
|
||||
|
||||
if (SpdProtocol == Protocol) {
|
||||
switch (Protocol) {
|
||||
case EFI_IP_PROTO_UDP:
|
||||
case EFI_IP_PROTO_TCP:
|
||||
//
|
||||
// For udp and tcp, (0, 0) means no need to check local and remote
|
||||
// port. The payload is passed from upper level, which means it should
|
||||
// be in network order.
|
||||
//
|
||||
IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);
|
||||
IsMatch = (BOOLEAN) (IsMatch ||
|
||||
(IsOutbound &&
|
||||
(BOOLEAN)(
|
||||
NTOHS (((EFI_UDP_HEADER *) IpPayload)->SrcPort) == SpdLocalPort &&
|
||||
NTOHS (((EFI_UDP_HEADER *) IpPayload)->DstPort) == SpdRemotePort
|
||||
)
|
||||
));
|
||||
|
||||
IsMatch = (BOOLEAN) (IsMatch ||
|
||||
(!IsOutbound &&
|
||||
(BOOLEAN)(
|
||||
NTOHS (((EFI_UDP_HEADER *) IpPayload)->DstPort) == SpdLocalPort &&
|
||||
NTOHS (((EFI_UDP_HEADER *) IpPayload)->SrcPort) == SpdRemotePort
|
||||
)
|
||||
));
|
||||
break;
|
||||
|
||||
case EFI_IP_PROTO_ICMP:
|
||||
//
|
||||
// For icmpv4, type code is replaced with local port and remote port,
|
||||
// and (0, 0) means no need to check.
|
||||
//
|
||||
IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);
|
||||
IsMatch = (BOOLEAN) (IsMatch ||
|
||||
(BOOLEAN) (((IP4_ICMP_HEAD *) IpPayload)->Type == SpdLocalPort &&
|
||||
((IP4_ICMP_HEAD *) IpPayload)->Code == SpdRemotePort
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case IP6_ICMP:
|
||||
//
|
||||
// For icmpv6, type code is replaced with local port and remote port,
|
||||
// and (0, 0) means no need to check.
|
||||
//
|
||||
IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);
|
||||
|
||||
IsMatch = (BOOLEAN) (IsMatch ||
|
||||
(BOOLEAN) (((IP6_ICMP_HEAD *) IpPayload)->Type == SpdLocalPort &&
|
||||
((IP6_ICMP_HEAD *) IpPayload)->Code == SpdRemotePort
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
IsMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the SAD through a specified SPD's SAD list.
|
||||
|
||||
@param[in] SadList SAD list related to a specified SPD entry.
|
||||
@param[in] DestAddress The destination address used to find the SAD entry.
|
||||
|
||||
@return The pointer to a certain SAD entry.
|
||||
|
||||
**/
|
||||
IPSEC_SAD_ENTRY *
|
||||
IpSecLookupSadBySpd (
|
||||
IN LIST_ENTRY *SadList,
|
||||
IN EFI_IP_ADDRESS *DestAddress
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *Entry;
|
||||
IPSEC_SAD_ENTRY *SadEntry;
|
||||
|
||||
for (Entry = SadList->ForwardLink; Entry != SadList; Entry = Entry->ForwardLink) {
|
||||
|
||||
SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry);
|
||||
//
|
||||
// Find the right sad entry which contains the appointed dest address.
|
||||
//
|
||||
if (CompareMem (
|
||||
&SadEntry->Id->DestAddress,
|
||||
DestAddress,
|
||||
sizeof (EFI_IP_ADDRESS)
|
||||
) == 0) {
|
||||
return SadEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@return the pointer to a certain SAD entry.
|
||||
|
||||
**/
|
||||
IPSEC_SAD_ENTRY *
|
||||
IpSecLookupSadBySpi (
|
||||
IN UINT32 Spi,
|
||||
IN EFI_IP_ADDRESS *DestAddress
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *Entry;
|
||||
LIST_ENTRY *SadList;
|
||||
IPSEC_SAD_ENTRY *SadEntry;
|
||||
|
||||
SadList = &mConfigData[IPsecConfigDataTypeSad];
|
||||
|
||||
for (Entry = SadList->ForwardLink; Entry != SadList; Entry = Entry->ForwardLink) {
|
||||
|
||||
SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);
|
||||
//
|
||||
// Find the right sad entry which contain the appointed spi and dest addr.
|
||||
//
|
||||
if (SadEntry->Id->Spi == Spi && CompareMem (
|
||||
&SadEntry->Id->DestAddress,
|
||||
DestAddress,
|
||||
sizeof (EFI_IP_ADDRESS)
|
||||
) == 0) {
|
||||
|
||||
return SadEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
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_DEVICE_ERROR GC_TODO: Add description for return value.
|
||||
@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
|
||||
)
|
||||
{
|
||||
IPSEC_SAD_ENTRY *Entry;
|
||||
IPSEC_SAD_DATA *Data;
|
||||
EFI_IP_ADDRESS DestIp;
|
||||
UINT32 SeqNum32;
|
||||
|
||||
*SadEntry = NULL;
|
||||
//
|
||||
// Parse the destination address from ip header.
|
||||
//
|
||||
ZeroMem (&DestIp, sizeof (EFI_IP_ADDRESS));
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
CopyMem (
|
||||
&DestIp,
|
||||
&((IP4_HEAD *) IpHead)->Dst,
|
||||
sizeof (IP4_ADDR)
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
&DestIp,
|
||||
&((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
|
||||
sizeof (EFI_IP_ADDRESS)
|
||||
);
|
||||
}
|
||||
//
|
||||
// Find the sad entry in the spd.sas list according to the dest address.
|
||||
//
|
||||
Entry = IpSecLookupSadBySpd (&SpdEntry->Data->Sas, &DestIp);
|
||||
|
||||
if (Entry == NULL) {
|
||||
|
||||
if (OldLastHead != IP6_ICMP ||
|
||||
(OldLastHead == IP6_ICMP && *IpPayload == ICMP_V6_ECHO_REQUEST)
|
||||
) {
|
||||
//
|
||||
// TODO: Start ike negotiation process except the request packet of ping.
|
||||
//
|
||||
//IkeNegotiate (UdpService, SpdEntry, &DestIp);
|
||||
}
|
||||
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
Data = Entry->Data;
|
||||
|
||||
if (!Data->ManualSet) {
|
||||
if (Data->ESNEnabled) {
|
||||
//
|
||||
// Validate the 64bit sn number if 64bit sn enabled.
|
||||
//
|
||||
if (Data->SequenceNumber + 1 < Data->SequenceNumber) {
|
||||
//
|
||||
// TODO: Re-negotiate SA
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Validate the 32bit sn number if 64bit sn disabled.
|
||||
//
|
||||
SeqNum32 = (UINT32) Data->SequenceNumber;
|
||||
if (SeqNum32 + 1 < SeqNum32) {
|
||||
//
|
||||
// TODO: Re-negotiate SA
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*SadEntry = Entry;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Find a PAD entry according to a remote IP address.
|
||||
|
||||
@param[in] IpVersion The version of IP.
|
||||
@param[in] IpAddr Points to remote IP address.
|
||||
|
||||
@return the pointer of related PAD entry.
|
||||
|
||||
**/
|
||||
IPSEC_PAD_ENTRY *
|
||||
IpSecLookupPadEntry (
|
||||
IN UINT8 IpVersion,
|
||||
IN EFI_IP_ADDRESS *IpAddr
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *PadList;
|
||||
LIST_ENTRY *Entry;
|
||||
EFI_IP_ADDRESS_INFO *IpAddrInfo;
|
||||
IPSEC_PAD_ENTRY *PadEntry;
|
||||
|
||||
PadList = &mConfigData[IPsecConfigDataTypePad];
|
||||
|
||||
for (Entry = PadList->ForwardLink; Entry != PadList; Entry = Entry->ForwardLink) {
|
||||
|
||||
PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);
|
||||
IpAddrInfo = &PadEntry->Id->Id.IpAddress;
|
||||
//
|
||||
// Find the right pad entry which contain the appointed dest addr.
|
||||
//
|
||||
if (IpSecMatchIpAddress (IpVersion, IpAddr, IpAddrInfo, 1)) {
|
||||
return PadEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@retval EFI_IPSEC_ACTION The support action of SPD entry.
|
||||
@retval -1 If the input packet header doesn't match the SpdEntry.
|
||||
|
||||
**/
|
||||
EFI_IPSEC_ACTION
|
||||
IpSecLookupSpdEntry (
|
||||
IN IPSEC_SPD_ENTRY *SpdEntry,
|
||||
IN UINT8 IpVersion,
|
||||
IN VOID *IpHead,
|
||||
IN UINT8 *IpPayload,
|
||||
IN UINT8 Protocol,
|
||||
IN BOOLEAN IsOutbound
|
||||
)
|
||||
{
|
||||
EFI_IPSEC_SPD_SELECTOR *SpdSel;
|
||||
IP4_HEAD *Ip4;
|
||||
EFI_IP6_HEADER *Ip6;
|
||||
EFI_IP_ADDRESS SrcAddr;
|
||||
EFI_IP_ADDRESS DstAddr;
|
||||
BOOLEAN SpdMatch;
|
||||
|
||||
ASSERT (SpdEntry != NULL);
|
||||
SpdSel = SpdEntry->Selector;
|
||||
Ip4 = (IP4_HEAD *) IpHead;
|
||||
Ip6 = (EFI_IP6_HEADER *) IpHead;
|
||||
|
||||
ZeroMem (&SrcAddr, sizeof (EFI_IP_ADDRESS));
|
||||
ZeroMem (&DstAddr, sizeof (EFI_IP_ADDRESS));
|
||||
|
||||
//
|
||||
// Parse the source and destination address from ip header.
|
||||
//
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
CopyMem (&SrcAddr, &Ip4->Src, sizeof (IP4_ADDR));
|
||||
CopyMem (&DstAddr, &Ip4->Dst, sizeof (IP4_ADDR));
|
||||
} else {
|
||||
CopyMem (&SrcAddr, &Ip6->SourceAddress, sizeof (EFI_IPv6_ADDRESS));
|
||||
CopyMem (&DstAddr, &Ip6->DestinationAddress, sizeof (EFI_IPv6_ADDRESS));
|
||||
}
|
||||
//
|
||||
// Check the local and remote addresses for outbound traffic
|
||||
//
|
||||
SpdMatch = (BOOLEAN)(IsOutbound &&
|
||||
IpSecMatchIpAddress (
|
||||
IpVersion,
|
||||
&SrcAddr,
|
||||
SpdSel->LocalAddress,
|
||||
SpdSel->LocalAddressCount
|
||||
) &&
|
||||
IpSecMatchIpAddress (
|
||||
IpVersion,
|
||||
&DstAddr,
|
||||
SpdSel->RemoteAddress,
|
||||
SpdSel->RemoteAddressCount
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Check the local and remote addresses for inbound traffic
|
||||
//
|
||||
SpdMatch = (BOOLEAN) (SpdMatch ||
|
||||
(!IsOutbound &&
|
||||
IpSecMatchIpAddress (
|
||||
IpVersion,
|
||||
&DstAddr,
|
||||
SpdSel->LocalAddress,
|
||||
SpdSel->LocalAddressCount
|
||||
) &&
|
||||
IpSecMatchIpAddress (
|
||||
IpVersion,
|
||||
&SrcAddr,
|
||||
SpdSel->RemoteAddress,
|
||||
SpdSel->RemoteAddressCount
|
||||
)
|
||||
));
|
||||
|
||||
//
|
||||
// Check the next layer protocol and local and remote ports.
|
||||
//
|
||||
SpdMatch = (BOOLEAN) (SpdMatch &&
|
||||
IpSecMatchNextLayerProtocol (
|
||||
Protocol,
|
||||
IpPayload,
|
||||
SpdSel->NextLayerProtocol,
|
||||
SpdSel->LocalPort,
|
||||
SpdSel->RemotePort,
|
||||
IsOutbound
|
||||
)
|
||||
);
|
||||
|
||||
if (SpdMatch) {
|
||||
//
|
||||
// Find the right spd entry if match the 5 key elements.
|
||||
//
|
||||
return SpdEntry->Data->Action;
|
||||
}
|
||||
|
||||
return (EFI_IPSEC_ACTION) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
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_IPSEC_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] LastHead The protocol of the next layer to be processed by IPsec.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer.
|
||||
@param[in] OptionsLength Length of the options buffer.
|
||||
@param[in, out] FragmentTable Pointer to a list of fragments.
|
||||
@param[in] 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_IPSEC_PROTOCOL *This,
|
||||
IN EFI_HANDLE NicHandle,
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
IN UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer,
|
||||
IN UINT32 OptionsLength,
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection,
|
||||
OUT EFI_EVENT *RecycleSignal
|
||||
)
|
||||
{
|
||||
IPSEC_PRIVATE_DATA *Private;
|
||||
IPSEC_SPD_ENTRY *SpdEntry;
|
||||
IPSEC_SAD_ENTRY *SadEntry;
|
||||
LIST_ENTRY *SpdList;
|
||||
LIST_ENTRY *Entry;
|
||||
EFI_IPSEC_ACTION Action;
|
||||
EFI_STATUS Status;
|
||||
UINT8 *IpPayload;
|
||||
UINT8 OldLastHead;
|
||||
BOOLEAN IsOutbound;
|
||||
|
||||
Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (This);
|
||||
IpPayload = (*FragmentTable)[0].FragmentBuffer;
|
||||
IsOutbound = (BOOLEAN) ((TrafficDirection == EfiIPsecOutBound) ? TRUE : FALSE);
|
||||
OldLastHead = *LastHead;
|
||||
*RecycleSignal = NULL;
|
||||
|
||||
if (!IsOutbound) {
|
||||
//
|
||||
// For inbound traffic, process the ipsec header of the packet.
|
||||
//
|
||||
Status = IpSecProtectInboundPacket (
|
||||
IpVersion,
|
||||
IpHead,
|
||||
LastHead,
|
||||
OptionsBuffer,
|
||||
OptionsLength,
|
||||
FragmentTable,
|
||||
FragmentCount,
|
||||
&SpdEntry,
|
||||
RecycleSignal
|
||||
);
|
||||
|
||||
if (Status == EFI_ACCESS_DENIED) {
|
||||
//
|
||||
// The packet is denied to access.
|
||||
//
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (Status == EFI_SUCCESS) {
|
||||
//
|
||||
// Check the spd entry if the packet is accessible.
|
||||
//
|
||||
if (SpdEntry == NULL) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
Action = IpSecLookupSpdEntry (
|
||||
SpdEntry,
|
||||
IpVersion,
|
||||
IpHead,
|
||||
IpPayload,
|
||||
*LastHead,
|
||||
IsOutbound
|
||||
);
|
||||
|
||||
if (Action != EfiIPsecActionProtect) {
|
||||
//
|
||||
// Discard the packet if the spd entry is not protect.
|
||||
//
|
||||
gBS->SignalEvent (*RecycleSignal);
|
||||
*RecycleSignal = NULL;
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
SpdList = &mConfigData[IPsecConfigDataTypeSpd];
|
||||
|
||||
for (Entry = SpdList->ForwardLink; Entry != SpdList; Entry = Entry->ForwardLink) {
|
||||
//
|
||||
// For outbound and non-ipsec Inbound traffic: check the spd entry.
|
||||
//
|
||||
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
|
||||
Action = IpSecLookupSpdEntry (
|
||||
SpdEntry,
|
||||
IpVersion,
|
||||
IpHead,
|
||||
IpPayload,
|
||||
OldLastHead,
|
||||
IsOutbound
|
||||
);
|
||||
|
||||
switch (Action) {
|
||||
|
||||
case EfiIPsecActionProtect:
|
||||
|
||||
if (IsOutbound) {
|
||||
//
|
||||
// For outbound traffic, lookup the sad entry.
|
||||
//
|
||||
Status = IpSecLookupSadEntry (
|
||||
Private,
|
||||
NicHandle,
|
||||
IpVersion,
|
||||
IpHead,
|
||||
IpPayload,
|
||||
OldLastHead,
|
||||
SpdEntry,
|
||||
&SadEntry
|
||||
);
|
||||
|
||||
if (SadEntry != NULL) {
|
||||
//
|
||||
// Process the packet by the found sad entry.
|
||||
//
|
||||
Status = IpSecProtectOutboundPacket (
|
||||
IpVersion,
|
||||
IpHead,
|
||||
LastHead,
|
||||
OptionsBuffer,
|
||||
OptionsLength,
|
||||
FragmentTable,
|
||||
FragmentCount,
|
||||
SadEntry,
|
||||
RecycleSignal
|
||||
);
|
||||
|
||||
} else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {
|
||||
//
|
||||
// TODO: if no need return not ready to upper layer, change here.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
} else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {
|
||||
//
|
||||
// For inbound icmpv6 traffic except ping request, accept the packet
|
||||
// although no sad entry associated with protect spd entry.
|
||||
//
|
||||
IpSecLookupSadEntry (
|
||||
Private,
|
||||
NicHandle,
|
||||
IpVersion,
|
||||
IpHead,
|
||||
IpPayload,
|
||||
OldLastHead,
|
||||
SpdEntry,
|
||||
&SadEntry
|
||||
);
|
||||
if (SadEntry == NULL) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
goto ON_EXIT;
|
||||
|
||||
case EfiIPsecActionBypass:
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
|
||||
case EfiIPsecActionDiscard:
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
//
|
||||
// Discard the packet if no spd entry match.
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
313
NetworkPkg/IpSecDxe/IpSecImpl.h
Normal file
313
NetworkPkg/IpSecDxe/IpSecImpl.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/** @file
|
||||
The definitions related to IPsec protocol implementation.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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_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;
|
||||
BOOLEAN ESNEnabled; // Extended (64-bit) SN enabled
|
||||
BOOLEAN ManualSet;
|
||||
} 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 _IPSEC_PRIVATE_DATA {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Handle; // Virtual handle to install private prtocol
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_IPSEC_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] LastHead The Last Header in IP header on return.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@param[in, out] FragmentTable Pointer to a list of fragments in the form of IPsec
|
||||
protected on input, and without IPsec protected
|
||||
on return.
|
||||
@param[in] FragmentCount Number of fragments.
|
||||
@param[out] SpdEntry Pointer to contain the address of SPD entry on return.
|
||||
@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
|
||||
IpSecProtectInboundPacket (
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
IN UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
OUT IPSEC_SPD_ENTRY **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] LastHead The Last Header in IP header.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@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] 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 UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN 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
|
||||
);
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@return The pointer to a certain SAD entry.
|
||||
|
||||
**/
|
||||
IPSEC_SAD_ENTRY *
|
||||
IpSecLookupSadBySpi (
|
||||
IN UINT32 Spi,
|
||||
IN EFI_IP_ADDRESS *DestAddress
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
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_IPSEC_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] LastHead The protocol of the next layer to be processed by IPsec.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer.
|
||||
@param[in] OptionsLength Length of the options buffer.
|
||||
@param[in, out] FragmentTable Pointer to a list of fragments.
|
||||
@param[in] 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_IPSEC_PROTOCOL *This,
|
||||
IN EFI_HANDLE NicHandle,
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
IN UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer,
|
||||
IN UINT32 OptionsLength,
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection,
|
||||
OUT EFI_EVENT *RecycleSignal
|
||||
);
|
||||
|
||||
extern EFI_DPC_PROTOCOL *mDpc;
|
||||
extern EFI_IPSEC_PROTOCOL mIpSecInstance;
|
||||
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gIpSecComponentName2;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gIpSecComponentName;
|
||||
|
||||
|
||||
#endif
|
934
NetworkPkg/IpSecDxe/IpSecSaEngine.c
Normal file
934
NetworkPkg/IpSecDxe/IpSecSaEngine.c
Normal file
@@ -0,0 +1,934 @@
|
||||
/** @file
|
||||
IPsec inbound and outbound traffic processing.
|
||||
|
||||
Copyright (c) 2009 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "IpSecImpl.h"
|
||||
#include "IpSecDebug.h"
|
||||
#include "IpSecCryptIo.h"
|
||||
|
||||
extern LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];
|
||||
|
||||
/**
|
||||
The call back function of NetbufFromExt.
|
||||
|
||||
@param[in] Arg The argument passed from the caller.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
IpSecOnRecyclePacket (
|
||||
IN VOID *Arg
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
This is a Notification function. It is called when the related IP6_TXTOKEN_WRAP
|
||||
is released.
|
||||
|
||||
@param[in] Event The related event.
|
||||
@param[in] Context The data passed by the caller.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
IpSecRecycleCallback (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
IPSEC_RECYCLE_CONTEXT *RecycleContext;
|
||||
|
||||
RecycleContext = (IPSEC_RECYCLE_CONTEXT *) Context;
|
||||
|
||||
if (RecycleContext->FragmentTable != NULL) {
|
||||
FreePool (RecycleContext->FragmentTable);
|
||||
}
|
||||
|
||||
if (RecycleContext->PayloadBuffer != NULL) {
|
||||
FreePool (RecycleContext->PayloadBuffer);
|
||||
}
|
||||
|
||||
FreePool (RecycleContext);
|
||||
gBS->CloseEvent (Event);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the extension header of IP. The return length only doesn't contain
|
||||
the fixed IP header length.
|
||||
|
||||
@param[in] IpHead Points to an IP head to be calculated.
|
||||
@param[in] LastHead Points to the last header of the IP header.
|
||||
|
||||
@return The length of the extension header.
|
||||
|
||||
**/
|
||||
UINT16
|
||||
IpSecGetPlainExtHeadSize (
|
||||
IN VOID *IpHead,
|
||||
IN UINT8 *LastHead
|
||||
)
|
||||
{
|
||||
UINT16 Size;
|
||||
|
||||
Size = (UINT16) (LastHead - (UINT8 *) IpHead);
|
||||
|
||||
if (Size > sizeof (EFI_IP6_HEADER)) {
|
||||
//
|
||||
// * (LastHead+1) point the last header's length but not include the first
|
||||
// 8 octers, so this formluation add 8 at the end.
|
||||
//
|
||||
Size = (UINT16) (Size - sizeof (EFI_IP6_HEADER) + *(LastHead + 1) + 8);
|
||||
} else {
|
||||
Size = 0;
|
||||
}
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
/**
|
||||
Authenticate the IpSec Payload and store the result in the IcvBuffer.
|
||||
|
||||
@param[in] BufferToAuth The buffer to be Authenticated.
|
||||
@param[in] AuthSize The size of the buffer to be Authenticated.
|
||||
@param[in, out] IcvBuffer The buffer to store the ICV.
|
||||
@param[in] IcvSize The size of ICV.
|
||||
@param[in] Key The Key passed to the CryptLib to generate a
|
||||
CRYPT_HANDLE.
|
||||
@param[in] AuthAlgId The Authentication Algorithm ID.
|
||||
|
||||
@retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
|
||||
@retval EFI_SUCCESS Authenticated the payload successfully.
|
||||
@retval otherwise Authentication of the payload failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecAuthPayload (
|
||||
IN UINT8 *BufferToAuth,
|
||||
IN UINTN AuthSize,
|
||||
IN OUT UINT8 *IcvBuffer,
|
||||
IN UINTN IcvSize,
|
||||
IN VOID *Key,
|
||||
IN UINT8 AuthAlgId
|
||||
)
|
||||
{
|
||||
switch (AuthAlgId) {
|
||||
case EFI_IPSEC_AALG_NONE :
|
||||
case EFI_IPSEC_AALG_NULL :
|
||||
return EFI_SUCCESS;
|
||||
|
||||
default:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Verify if the Authentication payload is correct.
|
||||
|
||||
@param[in] EspBuffer Points to the ESP wrapped buffer.
|
||||
@param[in] EspSize The size of the ESP wrapped buffer.
|
||||
@param[in] SadEntry The related SAD entry to store the authentication
|
||||
algorithm key.
|
||||
@param[in] IcvSize The length of ICV.
|
||||
|
||||
@retval EFI_SUCCESS The authentication data is correct.
|
||||
@retval EFI_ACCESS_DENIED The authentication data is not correct.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecEspAuthVerifyPayload (
|
||||
IN UINT8 *EspBuffer,
|
||||
IN UINTN EspSize,
|
||||
IN IPSEC_SAD_ENTRY *SadEntry,
|
||||
IN UINTN *IcvSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN AuthSize;
|
||||
UINT8 IcvBuffer[12];
|
||||
|
||||
//
|
||||
// Calculate the size of authentication payload.
|
||||
//
|
||||
*IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
|
||||
AuthSize = EspSize - *IcvSize;
|
||||
|
||||
//
|
||||
// Calculate the icv buffer and size of the payload.
|
||||
//
|
||||
Status = IpSecAuthPayload (
|
||||
EspBuffer,
|
||||
AuthSize,
|
||||
IcvBuffer,
|
||||
*IcvSize,
|
||||
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
|
||||
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Compare the calculated icv and the appended original icv.
|
||||
//
|
||||
if (CompareMem (EspBuffer + AuthSize, IcvBuffer, *IcvSize) == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_ERROR, "Error auth verify payload\n"));
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/**
|
||||
ESP Decrypt the payload.
|
||||
|
||||
@param[in, out] PayloadBuffer Pointer to the buffer containing the ESP wrapped;
|
||||
to be decrypted on input, and plaintext on return. The
|
||||
number of bytes of data to be decrypted is
|
||||
specified by EncryptSize.
|
||||
@param[in] EncryptSize The size of the PayloadBuffer as input.
|
||||
@param[in] SadEntry The related SAD entry.
|
||||
@param[in] IvSize The size of IV.
|
||||
@param[out] PlainPayloadSize Contains the return value of decrypted size.
|
||||
@param[out] PaddingSize Contains the return value of Padding size.
|
||||
@param[out] NextHeader Contains the return value of the last protocol header
|
||||
of the IP packet.
|
||||
|
||||
@retval EFI_UNSUPPORTED The Algorithm pointed to by the SAD entry is not supported.
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecEspDecryptPayload (
|
||||
IN OUT UINT8 *PayloadBuffer,
|
||||
IN UINTN EncryptSize,
|
||||
IN IPSEC_SAD_ENTRY *SadEntry,
|
||||
IN UINTN *IvSize,
|
||||
OUT UINTN *PlainPayloadSize,
|
||||
OUT UINTN *PaddingSize,
|
||||
OUT UINT8 *NextHeader
|
||||
)
|
||||
{
|
||||
EFI_ESP_TAIL *EspTail;
|
||||
|
||||
switch (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId) {
|
||||
case EFI_IPSEC_EALG_NULL:
|
||||
EspTail = (EFI_ESP_TAIL *) (PayloadBuffer + EncryptSize - sizeof (EFI_ESP_TAIL));
|
||||
*PaddingSize = EspTail->PaddingLength;
|
||||
*NextHeader = EspTail->NextHeader;
|
||||
*PlainPayloadSize = EncryptSize - EspTail->PaddingLength - sizeof (EFI_ESP_TAIL);
|
||||
break;
|
||||
|
||||
case EFI_IPSEC_EALG_3DESCBC:
|
||||
case EFI_IPSEC_EALG_AESCBC:
|
||||
//
|
||||
// TODO: support these algorithm
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
default :
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
ESP Encrypt the payload.
|
||||
|
||||
@param[in, out] BufferToEncrypt Pointer to the buffer containing plaintext to be
|
||||
encrypted on input, and ciphertext on return. The
|
||||
number of bytes of data to be encrypted is
|
||||
specified by EncryptSize.
|
||||
@param[in, out] EncryptSize The size of the plaintext on input, and the size of the
|
||||
ciphertext on return.
|
||||
@param[in] IvBuffer Points to IV data.
|
||||
@param[in] IvSize Size of IV.
|
||||
@param[in] SadEntry Related SAD entry.
|
||||
|
||||
@retval EFI_UNSUPPORTED The Algorithm pointed by SAD entry is not supported.
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecEspEncryptPayload (
|
||||
IN OUT UINT8 *BufferToEncrypt,
|
||||
IN OUT UINTN EncryptSize,
|
||||
IN UINT8 *IvBuffer,
|
||||
IN UINTN IvSize,
|
||||
IN IPSEC_SAD_ENTRY *SadEntry
|
||||
)
|
||||
{
|
||||
switch (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId) {
|
||||
case EFI_IPSEC_EALG_NULL:
|
||||
return EFI_SUCCESS;
|
||||
|
||||
case EFI_IPSEC_EALG_3DESCBC:
|
||||
case EFI_IPSEC_EALG_AESCBC:
|
||||
//
|
||||
// TODO: support these algorithms
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
default :
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The actual entry to relative function processes the inbound traffic of ESP header.
|
||||
|
||||
This function is the subfunction of IpSecProtectInboundPacket(). It checks the
|
||||
received packet security property and trim the ESP header and then returns without
|
||||
an IPsec protected IP Header and FramgmentTable.
|
||||
|
||||
@param[in] IpVersion The version of IP.
|
||||
@param[in, out] IpHead Points to the IP header containing the ESP header
|
||||
to be trimed on input, and without ESP header
|
||||
on return.
|
||||
@param[out] LastHead The Last Header in IP header on return.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@param[in, out] FragmentTable Pointer to a list of fragments in the form of IPsec
|
||||
protected on input, and without IPsec protected
|
||||
on return.
|
||||
@param[in] 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_ACCESS_DENIED One or more following conditions is TRUE:
|
||||
- ESP header was not found.
|
||||
- The related SAD entry was not found.
|
||||
- The related SAD entry does not support the ESP protocol.
|
||||
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecEspInboundPacket (
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
OUT UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
OUT IPSEC_SPD_ENTRY **SpdEntry,
|
||||
OUT EFI_EVENT *RecycleEvent
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
NET_BUF *Payload;
|
||||
UINTN EspSize;
|
||||
UINTN IvSize;
|
||||
UINTN PlainPayloadSize;
|
||||
UINTN PaddingSize;
|
||||
UINTN IcvSize;
|
||||
UINT8 *ProcessBuffer;
|
||||
EFI_IP_ADDRESS DestIp;
|
||||
EFI_ESP_HEADER *EspHeader;
|
||||
EFI_ESP_TAIL *EspTail;
|
||||
EFI_IPSEC_SA_ID *SaId;
|
||||
IPSEC_SAD_DATA *SadData;
|
||||
IPSEC_SAD_ENTRY *SadEntry;
|
||||
IPSEC_RECYCLE_CONTEXT *RecycleContext;
|
||||
UINT32 Spi;
|
||||
UINT8 NextHeader;
|
||||
UINT16 IpSecHeadSize;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Payload = NULL;
|
||||
ProcessBuffer = NULL;
|
||||
RecycleContext = NULL;
|
||||
*RecycleEvent = NULL;
|
||||
PlainPayloadSize = 0;
|
||||
NextHeader = 0;
|
||||
//
|
||||
// Build netbuf from fragment table first.
|
||||
//
|
||||
Payload = NetbufFromExt (
|
||||
(NET_FRAGMENT *) *FragmentTable,
|
||||
*FragmentCount,
|
||||
0,
|
||||
sizeof (EFI_ESP_HEADER),
|
||||
IpSecOnRecyclePacket,
|
||||
NULL
|
||||
);
|
||||
if (Payload == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Get the esp size and eso header from netbuf.
|
||||
//
|
||||
EspSize = Payload->TotalSize;
|
||||
EspHeader = (EFI_ESP_HEADER *) NetbufGetByte (Payload, 0, NULL);
|
||||
if (EspHeader == NULL) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Parse destination address from ip header.
|
||||
//
|
||||
ZeroMem (&DestIp, sizeof (EFI_IP_ADDRESS));
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
CopyMem (
|
||||
&DestIp,
|
||||
&((IP4_HEAD *) IpHead)->Dst,
|
||||
sizeof (IP4_ADDR)
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
&DestIp,
|
||||
&((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
|
||||
sizeof (EFI_IPv6_ADDRESS)
|
||||
);
|
||||
}
|
||||
//
|
||||
// Lookup sad entry according to the spi and dest address.
|
||||
//
|
||||
Spi = NTOHL (EspHeader->Spi);
|
||||
SadEntry = IpSecLookupSadBySpi (Spi, &DestIp);
|
||||
if (SadEntry == NULL) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
SaId = SadEntry->Id;
|
||||
SadData = SadEntry->Data;
|
||||
|
||||
//
|
||||
// Only support esp protocol currently.
|
||||
//
|
||||
if (SaId->Proto != EfiIPsecESP) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (!SadData->ManualSet) {
|
||||
//
|
||||
// TODO: Check sa lifetime and sequence number
|
||||
//
|
||||
}
|
||||
//
|
||||
// Allocate buffer for decryption and authentication by esp.
|
||||
//
|
||||
ProcessBuffer = AllocateZeroPool (EspSize);
|
||||
if (ProcessBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
NetbufCopy (Payload, 0, (UINT32) EspSize, ProcessBuffer);
|
||||
|
||||
//
|
||||
// Authenticate the esp wrapped buffer by the sad entry if has auth key.
|
||||
//
|
||||
IcvSize = 0;
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
|
||||
Status = IpSecEspAuthVerifyPayload (
|
||||
ProcessBuffer,
|
||||
EspSize,
|
||||
SadEntry,
|
||||
&IcvSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Decrypt the payload by the sad entry if has decrypt key.
|
||||
//
|
||||
IvSize = 0;
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
|
||||
Status = IpSecEspDecryptPayload (
|
||||
ProcessBuffer + sizeof (EFI_ESP_HEADER),
|
||||
EspSize - sizeof (EFI_ESP_HEADER) - IcvSize,
|
||||
SadEntry,
|
||||
&IvSize,
|
||||
&PlainPayloadSize,
|
||||
&PaddingSize,
|
||||
&NextHeader
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
} else {
|
||||
EspTail = (EFI_ESP_TAIL *) (ProcessBuffer + EspSize - IcvSize - sizeof (EFI_ESP_TAIL));
|
||||
PaddingSize = EspTail->PaddingLength;
|
||||
NextHeader = EspTail->NextHeader;
|
||||
PlainPayloadSize = EspSize - sizeof (EFI_ESP_HEADER) - IvSize - IcvSize - sizeof (EFI_ESP_TAIL) - PaddingSize;
|
||||
}
|
||||
//
|
||||
// TODO: handle anti-replay window
|
||||
//
|
||||
//
|
||||
// Decryption and authentication with esp has been done, so it's time to
|
||||
// reload the new packet, create recycle event and fixup ip header.
|
||||
//
|
||||
RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
|
||||
if (RecycleContext == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
IpSecRecycleCallback,
|
||||
RecycleContext,
|
||||
RecycleEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// TODO: Who take responsible to handle the original fragment table?
|
||||
//
|
||||
*FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
|
||||
if (*FragmentTable == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
RecycleContext->PayloadBuffer = ProcessBuffer;
|
||||
RecycleContext->FragmentTable = *FragmentTable;
|
||||
(*FragmentTable)[0].FragmentBuffer = ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize;
|
||||
(*FragmentTable)[0].FragmentLength = (UINT32) PlainPayloadSize;
|
||||
*FragmentCount = 1;
|
||||
|
||||
//
|
||||
// Update the total length field in ip header since processed by esp.
|
||||
//
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) (((IP4_HEAD *) IpHead)->HeadLen + PlainPayloadSize));
|
||||
} else {
|
||||
IpSecHeadSize = IpSecGetPlainExtHeadSize (IpHead, LastHead);
|
||||
((EFI_IP6_HEADER *) IpHead)->PayloadLength = HTONS ((UINT16)(IpSecHeadSize + PlainPayloadSize));
|
||||
}
|
||||
//
|
||||
// Update the next layer field in ip header since esp header inserted.
|
||||
//
|
||||
*LastHead = NextHeader;
|
||||
|
||||
//
|
||||
// Update the spd association of the sad entry.
|
||||
//
|
||||
*SpdEntry = SadData->SpdEntry;
|
||||
|
||||
ON_EXIT:
|
||||
if (Payload != NULL) {
|
||||
NetbufFree (Payload);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (ProcessBuffer != NULL) {
|
||||
FreePool (ProcessBuffer);
|
||||
}
|
||||
|
||||
if (RecycleContext != NULL) {
|
||||
FreePool (RecycleContext);
|
||||
}
|
||||
|
||||
if (*RecycleEvent != NULL) {
|
||||
gBS->CloseEvent (*RecycleEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
The actual entry to the relative function processes the output traffic using the ESP protocol.
|
||||
|
||||
This function is the subfunction of IpSecProtectOutboundPacket(). It protected
|
||||
the sending packet by encrypting its payload and inserting ESP 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 Points to IP header containing the orginal IP header
|
||||
to be processed on input, and inserted ESP header
|
||||
on return.
|
||||
@param[in] LastHead The Last Header in IP header.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@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] FragmentCount The number of fragments.
|
||||
@param[in] SadEntry The related SAD entry.
|
||||
@param[out] RecycleEvent The event for recycling of resources.
|
||||
|
||||
@retval EFI_SUCCESS The operation was successful.
|
||||
@retval EFI_OUT_OF_RESOURCES The required system resources can't be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecEspOutboundPacket (
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
IN UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
IN IPSEC_SAD_ENTRY *SadEntry,
|
||||
OUT EFI_EVENT *RecycleEvent
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_IPSEC_SA_ID *SaId;
|
||||
IPSEC_SAD_DATA *SadData;
|
||||
IPSEC_RECYCLE_CONTEXT *RecycleContext;
|
||||
UINT8 *ProcessBuffer;
|
||||
UINTN BytesCopied;
|
||||
INTN EncryptBlockSize;// Size of encryption block, 4 bytes aligned and >= 4
|
||||
UINTN EspSize; // Total size of esp wrapped ip payload
|
||||
UINTN IvSize; // Size of IV, optional, might be 0
|
||||
UINTN PlainPayloadSize;// Original IP payload size
|
||||
UINTN PaddingSize; // Size of padding
|
||||
UINTN EncryptSize; // Size of data to be encrypted, start after IV and
|
||||
// stop before ICV
|
||||
UINTN IcvSize; // Size of ICV, optional, might be 0
|
||||
UINT8 *RestOfPayload; // Start of Payload after IV
|
||||
UINT8 *Padding; // Start address of padding
|
||||
EFI_ESP_HEADER *EspHeader; // Start address of ESP frame
|
||||
EFI_ESP_TAIL *EspTail; // Address behind padding
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
SaId = SadEntry->Id;
|
||||
SadData = SadEntry->Data;
|
||||
ProcessBuffer = NULL;
|
||||
RecycleContext = NULL;
|
||||
*RecycleEvent = NULL;
|
||||
|
||||
if (!SadData->ManualSet &&
|
||||
SadData->AlgoInfo.EspAlgoInfo.EncKey == NULL &&
|
||||
SadData->AlgoInfo.EspAlgoInfo.AuthKey == NULL
|
||||
) {
|
||||
//
|
||||
// Invalid manual sad entry configuration.
|
||||
//
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Calculate enctrypt block size, need iv by default and 4 bytes alignment.
|
||||
//
|
||||
EncryptBlockSize = 4;
|
||||
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
|
||||
EncryptBlockSize = IpSecGetEncryptBlockSize (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
|
||||
|
||||
if (EncryptBlockSize < 0 || (EncryptBlockSize != 1 && EncryptBlockSize % 4 != 0)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Calculate the plain payload size accroding to the fragment table.
|
||||
//
|
||||
PlainPayloadSize = 0;
|
||||
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||
PlainPayloadSize += (*FragmentTable)[Index].FragmentLength;
|
||||
}
|
||||
//
|
||||
// Calculate icv size, optional by default and 4 bytes alignment.
|
||||
//
|
||||
IcvSize = 0;
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
|
||||
IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
|
||||
if (IcvSize % 4 != 0) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Calcuate the total size of esp wrapped ip payload.
|
||||
//
|
||||
IvSize = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
|
||||
EncryptSize = (PlainPayloadSize + sizeof (EFI_ESP_TAIL) + EncryptBlockSize - 1) / EncryptBlockSize * EncryptBlockSize;
|
||||
PaddingSize = EncryptSize - PlainPayloadSize - sizeof (EFI_ESP_TAIL);
|
||||
EspSize = sizeof (EFI_ESP_HEADER) + IvSize + EncryptSize + IcvSize;
|
||||
|
||||
ProcessBuffer = AllocateZeroPool (EspSize);
|
||||
if (ProcessBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Calculate esp header and esp tail including header, payload and padding.
|
||||
//
|
||||
EspHeader = (EFI_ESP_HEADER *) ProcessBuffer;
|
||||
RestOfPayload = (UINT8 *) (EspHeader + 1) + IvSize;
|
||||
Padding = RestOfPayload + PlainPayloadSize;
|
||||
EspTail = (EFI_ESP_TAIL *) (Padding + PaddingSize);
|
||||
|
||||
//
|
||||
// Fill the sn and spi fields in esp header.
|
||||
//
|
||||
EspHeader->SequenceNumber = HTONL ((UINT32) SadData->SequenceNumber + 1);
|
||||
EspHeader->Spi = HTONL (SaId->Spi);
|
||||
|
||||
//
|
||||
// Copy the rest of payload (after iv) from the original fragment buffer.
|
||||
//
|
||||
BytesCopied = 0;
|
||||
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||
CopyMem (
|
||||
(RestOfPayload + BytesCopied),
|
||||
(*FragmentTable)[Index].FragmentBuffer,
|
||||
(*FragmentTable)[Index].FragmentLength
|
||||
);
|
||||
BytesCopied += (*FragmentTable)[Index].FragmentLength;
|
||||
}
|
||||
//
|
||||
// Fill the padding buffer by natural number sequence.
|
||||
//
|
||||
for (Index = 0; Index < PaddingSize; Index++) {
|
||||
Padding[Index] = (UINT8) (Index + 1);
|
||||
}
|
||||
//
|
||||
// Fill the padding length and next header fields in esp tail.
|
||||
//
|
||||
EspTail->PaddingLength = (UINT8) PaddingSize;
|
||||
EspTail->NextHeader = *LastHead;
|
||||
|
||||
//
|
||||
// Generate iv at random by crypt library.
|
||||
//
|
||||
Status = IpSecGenerateIv (
|
||||
(UINT8 *) (EspHeader + 1),
|
||||
IvSize
|
||||
);
|
||||
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Encrypt the payload (after iv) by the sad entry if has encrypt key.
|
||||
//
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
|
||||
Status = IpSecEspEncryptPayload (
|
||||
RestOfPayload,
|
||||
EncryptSize,
|
||||
(UINT8 *) (EspHeader + 1),
|
||||
IvSize,
|
||||
SadEntry
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Authenticate the esp wrapped buffer by the sad entry if has auth key.
|
||||
//
|
||||
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
|
||||
Status = IpSecAuthPayload (
|
||||
ProcessBuffer,
|
||||
EspSize - IcvSize,
|
||||
ProcessBuffer + EspSize - IcvSize,
|
||||
IcvSize,
|
||||
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
|
||||
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Encryption and authentication with esp has been done, so it's time to
|
||||
// reload the new packet, create recycle event and fixup ip header.
|
||||
//
|
||||
RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
|
||||
if (RecycleContext == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
IpSecRecycleCallback,
|
||||
RecycleContext,
|
||||
RecycleEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// TODO: Who take responsible to handle the original fragment table?
|
||||
//
|
||||
*FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
|
||||
if (*FragmentTable == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
RecycleContext->FragmentTable = *FragmentTable;
|
||||
RecycleContext->PayloadBuffer = ProcessBuffer;
|
||||
(*FragmentTable)[0].FragmentBuffer = ProcessBuffer;
|
||||
(*FragmentTable)[0].FragmentLength = (UINT32) EspSize;
|
||||
*FragmentCount = 1;
|
||||
|
||||
//
|
||||
// Update the total length field in ip header since processed by esp.
|
||||
//
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) (((IP4_HEAD *) IpHead)->HeadLen + EspSize));
|
||||
} else {
|
||||
((EFI_IP6_HEADER *) IpHead)->PayloadLength = (UINT16) (IpSecGetPlainExtHeadSize (IpHead, LastHead) + EspSize);
|
||||
}
|
||||
//
|
||||
// Update the next layer field in ip header since esp header inserted.
|
||||
//
|
||||
*LastHead = IPSEC_ESP_PROTOCOL;
|
||||
|
||||
//
|
||||
// Increase the sn number in sad entry according to rfc4303.
|
||||
//
|
||||
SadData->SequenceNumber++;
|
||||
|
||||
ON_EXIT:
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (ProcessBuffer != NULL) {
|
||||
FreePool (ProcessBuffer);
|
||||
}
|
||||
|
||||
if (RecycleContext != NULL) {
|
||||
FreePool (RecycleContext);
|
||||
}
|
||||
|
||||
if (*RecycleEvent != NULL) {
|
||||
gBS->CloseEvent (*RecycleEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
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] LastHead The Last Header in IP header on return.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@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] 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 UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
OUT IPSEC_SPD_ENTRY **SpdEntry,
|
||||
OUT EFI_EVENT *RecycleEvent
|
||||
)
|
||||
{
|
||||
if (*LastHead == IPSEC_ESP_PROTOCOL) {
|
||||
//
|
||||
// Process the esp ipsec header of the inbound traffic.
|
||||
//
|
||||
return IpSecEspInboundPacket (
|
||||
IpVersion,
|
||||
IpHead,
|
||||
LastHead,
|
||||
OptionsBuffer,
|
||||
OptionsLength,
|
||||
FragmentTable,
|
||||
FragmentCount,
|
||||
SpdEntry,
|
||||
RecycleEvent
|
||||
);
|
||||
}
|
||||
//
|
||||
// The other protocols are not supported.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
This function 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 returns the IpHeader and IPsec protected Fragmentable.
|
||||
|
||||
@param[in] IpVersion The version of IP.
|
||||
@param[in, out] IpHead Points to IP header containing the orginal IP header
|
||||
to be processed on input, and inserted ESP/AH header
|
||||
on return.
|
||||
@param[in] LastHead The Last Header in the IP header.
|
||||
@param[in] OptionsBuffer Pointer to the options buffer. It is optional.
|
||||
@param[in] OptionsLength Length of the options buffer. It is optional.
|
||||
@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] FragmentCount The number of fragments.
|
||||
@param[in] SadEntry The related SAD entry.
|
||||
@param[out] RecycleEvent The event for recycling of resources.
|
||||
|
||||
@retval EFI_SUCCESS The operation was successful.
|
||||
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IpSecProtectOutboundPacket (
|
||||
IN UINT8 IpVersion,
|
||||
IN OUT VOID *IpHead,
|
||||
IN UINT8 *LastHead,
|
||||
IN VOID *OptionsBuffer, OPTIONAL
|
||||
IN UINT32 OptionsLength, OPTIONAL
|
||||
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
|
||||
IN UINT32 *FragmentCount,
|
||||
IN IPSEC_SAD_ENTRY *SadEntry,
|
||||
OUT EFI_EVENT *RecycleEvent
|
||||
)
|
||||
{
|
||||
if (SadEntry->Id->Proto == EfiIPsecESP) {
|
||||
//
|
||||
// Process the esp ipsec header of the outbound traffic.
|
||||
//
|
||||
return IpSecEspOutboundPacket (
|
||||
IpVersion,
|
||||
IpHead,
|
||||
LastHead,
|
||||
OptionsBuffer,
|
||||
OptionsLength,
|
||||
FragmentTable,
|
||||
FragmentCount,
|
||||
SadEntry,
|
||||
RecycleEvent
|
||||
);
|
||||
}
|
||||
//
|
||||
// The other protocols are not supported.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
Reference in New Issue
Block a user