NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
v3: * Typo fix and code refine. * Rename the internal macros and function: TLS_INSTANCE_FROM_PROTOCOL_THIS -> TLS_INSTANCE_FROM_PROTOCOL TLS_INSTANCE_FROM_CONFIGURATION_THIS -> TLS_INSTANCE_FROM_CONFIGURATION TlsEcryptPacket -> TlsEncryptPacket v2: * Refine the TlsEcryptPacket/TlsDecryptPacket function according the community feedback. This patch is the implementation of EFI TLS Service Binding Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol Interfaces. Cc: Ye Ting <ting.ye@intel.com> Cc: Fu Siyuan <siyuan.fu@intel.com> Cc: Zhang Lubo <lubo.zhang@intel.com> Cc: Long Qin <qin.long@intel.com> Cc: Thomas Palmer <thomas.palmer@hpe.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com>
This commit is contained in:
152
NetworkPkg/TlsDxe/TlsConfigProtocol.c
Normal file
152
NetworkPkg/TlsDxe/TlsConfigProtocol.c
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/** @file
|
||||||
|
Implementation of EFI TLS Configuration Protocol Interfaces.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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 "TlsImpl.h"
|
||||||
|
|
||||||
|
EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = {
|
||||||
|
TlsConfigurationSetData,
|
||||||
|
TlsConfigurationGetData
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set TLS configuration data.
|
||||||
|
|
||||||
|
The SetData() function sets TLS configuration to non-volatile storage or volatile
|
||||||
|
storage.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
|
||||||
|
@param[in] DataType Configuration data type.
|
||||||
|
@param[in] Data Pointer to configuration data.
|
||||||
|
@param[in] DataSize Total size of configuration data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS configuration data is set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
Data is NULL.
|
||||||
|
DataSize is 0.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsConfigurationSetData (
|
||||||
|
IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_CONFIG_DATA_TYPE DataType,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
if (This == NULL || Data == NULL || DataSize == 0) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_CONFIGURATION (This);
|
||||||
|
|
||||||
|
switch (DataType) {
|
||||||
|
case EfiTlsConfigDataTypeCACertificate:
|
||||||
|
Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeHostPublicCert:
|
||||||
|
Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeHostPrivateKey:
|
||||||
|
Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeCertRevocationList:
|
||||||
|
Status = TlsSetCertRevocationList (Data, DataSize);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get TLS configuration data.
|
||||||
|
|
||||||
|
The GetData() function gets TLS configuration.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
|
||||||
|
@param[in] DataType Configuration data type.
|
||||||
|
@param[in, out] Data Pointer to configuration data.
|
||||||
|
@param[in, out] DataSize Total size of configuration data. On input, it means
|
||||||
|
the size of Data buffer. On output, it means the size
|
||||||
|
of copied Data buffer if EFI_SUCCESS, and means the
|
||||||
|
size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS configuration data is got successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
DataSize is NULL.
|
||||||
|
Data is NULL if *DataSize is not zero.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_NOT_FOUND The TLS configuration data is not found.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsConfigurationGetData (
|
||||||
|
IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_CONFIG_DATA_TYPE DataType,
|
||||||
|
IN OUT VOID *Data, OPTIONAL
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_CONFIGURATION (This);
|
||||||
|
|
||||||
|
switch (DataType) {
|
||||||
|
case EfiTlsConfigDataTypeCACertificate:
|
||||||
|
Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeHostPublicCert:
|
||||||
|
Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeHostPrivateKey:
|
||||||
|
Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsConfigDataTypeCertRevocationList:
|
||||||
|
Status = TlsGetCertRevocationList (Data, DataSize);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
496
NetworkPkg/TlsDxe/TlsDriver.c
Normal file
496
NetworkPkg/TlsDxe/TlsDriver.c
Normal file
@@ -0,0 +1,496 @@
|
|||||||
|
/** @file
|
||||||
|
The Driver Binding and Service Binding Protocol for TlsDxe driver.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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 "TlsImpl.h"
|
||||||
|
|
||||||
|
EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
|
||||||
|
TlsServiceBindingCreateChild,
|
||||||
|
TlsServiceBindingDestroyChild
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release all the resources used by the TLS instance.
|
||||||
|
|
||||||
|
@param[in] Instance The TLS instance data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
TlsCleanInstance (
|
||||||
|
IN TLS_INSTANCE *Instance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Instance != NULL) {
|
||||||
|
if (Instance->TlsConn != NULL) {
|
||||||
|
TlsFree (Instance->TlsConn);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (Instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create the TLS instance and initialize it.
|
||||||
|
|
||||||
|
@param[in] Service The pointer to the TLS service.
|
||||||
|
@param[out] Instance The pointer to the TLS instance.
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||||
|
@retval EFI_SUCCESS The TLS instance is created.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsCreateInstance (
|
||||||
|
IN TLS_SERVICE *Service,
|
||||||
|
OUT TLS_INSTANCE **Instance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TLS_INSTANCE *TlsInstance;
|
||||||
|
|
||||||
|
*Instance = NULL;
|
||||||
|
|
||||||
|
TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
|
||||||
|
if (TlsInstance == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
|
||||||
|
InitializeListHead (&TlsInstance->Link);
|
||||||
|
TlsInstance->InDestroy = FALSE;
|
||||||
|
TlsInstance->Service = Service;
|
||||||
|
|
||||||
|
CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
|
||||||
|
CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
|
||||||
|
|
||||||
|
TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
|
||||||
|
|
||||||
|
*Instance = TlsInstance;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release all the resources used by the TLS service binding instance.
|
||||||
|
|
||||||
|
@param[in] Service The TLS service data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
TlsCleanService (
|
||||||
|
IN TLS_SERVICE *Service
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Service != NULL) {
|
||||||
|
if (Service->TlsCtx != NULL) {
|
||||||
|
TlsCtxFree (Service->TlsCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (Service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create then initialize a TLS service.
|
||||||
|
|
||||||
|
@param[in] Image ImageHandle of the TLS driver
|
||||||
|
@param[out] Service The service for TLS driver
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
|
||||||
|
@retval EFI_SUCCESS The service is created for the driver.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsCreateService (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
OUT TLS_SERVICE **Service
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TLS_SERVICE *TlsService;
|
||||||
|
|
||||||
|
ASSERT (Service != NULL);
|
||||||
|
|
||||||
|
*Service = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate a TLS Service Data
|
||||||
|
//
|
||||||
|
TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
|
||||||
|
if (TlsService == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize TLS Service Data
|
||||||
|
//
|
||||||
|
TlsService->Signature = TLS_SERVICE_SIGNATURE;
|
||||||
|
CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
|
||||||
|
TlsService->TlsChildrenNum = 0;
|
||||||
|
InitializeListHead (&TlsService->TlsChildrenList);
|
||||||
|
TlsService->ImageHandle = Image;
|
||||||
|
|
||||||
|
*Service = TlsService;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Unloads an image.
|
||||||
|
|
||||||
|
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The image has been unloaded.
|
||||||
|
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsUnload (
|
||||||
|
IN EFI_HANDLE ImageHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN HandleNum;
|
||||||
|
EFI_HANDLE *HandleBuffer;
|
||||||
|
UINT32 Index;
|
||||||
|
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||||
|
TLS_SERVICE *TlsService;
|
||||||
|
|
||||||
|
HandleBuffer = NULL;
|
||||||
|
ServiceBinding = NULL;
|
||||||
|
TlsService = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate all the handles with Tls service binding protocol.
|
||||||
|
//
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiTlsServiceBindingProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&HandleNum,
|
||||||
|
&HandleBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < HandleNum; Index++) {
|
||||||
|
//
|
||||||
|
// Firstly, find ServiceBinding interface
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
HandleBuffer[Index],
|
||||||
|
&gEfiTlsServiceBindingProtocolGuid,
|
||||||
|
(VOID **) &ServiceBinding,
|
||||||
|
ImageHandle,
|
||||||
|
NULL,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Then, uninstall ServiceBinding interface
|
||||||
|
//
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
HandleBuffer[Index],
|
||||||
|
&gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsCleanService (TlsService);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HandleBuffer != NULL) {
|
||||||
|
FreePool (HandleBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
||||||
|
|
||||||
|
@param ImageHandle The firmware allocated handle for the UEFI image.
|
||||||
|
@param SystemTable A pointer to the EFI System Table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval Others An unexpected error occurred.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsDriverEntryPoint (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
TLS_SERVICE *TlsService;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create TLS Service
|
||||||
|
//
|
||||||
|
Status = TlsCreateService (ImageHandle, &TlsService);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT (TlsService != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializes the OpenSSL library.
|
||||||
|
//
|
||||||
|
TlsInitialize ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a new SSL_CTX object as framework to establish TLS/SSL enabled
|
||||||
|
// connections. TLS 1.0 is used as the default version.
|
||||||
|
//
|
||||||
|
TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
|
||||||
|
if (TlsService->TlsCtx == NULL) {
|
||||||
|
FreePool (TlsService);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install the TlsServiceBinding Protocol onto Handle
|
||||||
|
//
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&TlsService->Handle,
|
||||||
|
&gEfiTlsServiceBindingProtocolGuid,
|
||||||
|
&TlsService->ServiceBinding,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_CLEAN_SERVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
ON_CLEAN_SERVICE:
|
||||||
|
TlsCleanService (TlsService);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a child handle and installs a protocol.
|
||||||
|
|
||||||
|
The CreateChild() function installs a protocol on ChildHandle.
|
||||||
|
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||||
|
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||||
|
@param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||||
|
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||||
|
then the protocol is added to the existing UEFI handle.
|
||||||
|
|
||||||
|
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||||
|
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||||
|
the child.
|
||||||
|
@retval other The child handle was not created.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsServiceBindingCreateChild (
|
||||||
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE *ChildHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TLS_SERVICE *TlsService;
|
||||||
|
TLS_INSTANCE *TlsInstance;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsService = TLS_SERVICE_FROM_THIS (This);
|
||||||
|
|
||||||
|
Status = TlsCreateInstance (TlsService, &TlsInstance);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT (TlsInstance != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a new TLS connection object.
|
||||||
|
//
|
||||||
|
TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
|
||||||
|
if (TlsInstance->TlsConn == NULL) {
|
||||||
|
Status = EFI_ABORTED;
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set default ConnectionEnd to EfiTlsClient
|
||||||
|
//
|
||||||
|
Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install TLS protocol and configuration protocol onto ChildHandle
|
||||||
|
//
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
ChildHandle,
|
||||||
|
&gEfiTlsProtocolGuid,
|
||||||
|
&TlsInstance->Tls,
|
||||||
|
&gEfiTlsConfigurationProtocolGuid,
|
||||||
|
&TlsInstance->TlsConfig,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsInstance->ChildHandle = *ChildHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add it to the TLS service's child list.
|
||||||
|
//
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
|
||||||
|
TlsService->TlsChildrenNum++;
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
ON_ERROR:
|
||||||
|
TlsCleanInstance (TlsInstance);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroys a child handle with a protocol installed on it.
|
||||||
|
|
||||||
|
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||||
|
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||||
|
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||||
|
|
||||||
|
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||||
|
@param ChildHandle Handle of the child to destroy.
|
||||||
|
|
||||||
|
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||||
|
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||||
|
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||||
|
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||||
|
because its services are being used.
|
||||||
|
@retval other The child handle was not destroyed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsServiceBindingDestroyChild (
|
||||||
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ChildHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TLS_SERVICE *TlsService;
|
||||||
|
TLS_INSTANCE *TlsInstance;
|
||||||
|
|
||||||
|
EFI_TLS_PROTOCOL *Tls;
|
||||||
|
EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsService = TLS_SERVICE_FROM_THIS (This);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find TLS protocol interface installed in ChildHandle
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ChildHandle,
|
||||||
|
&gEfiTlsProtocolGuid,
|
||||||
|
(VOID **) &Tls,
|
||||||
|
TlsService->ImageHandle,
|
||||||
|
NULL,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find TLS configuration protocol interface installed in ChildHandle
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ChildHandle,
|
||||||
|
&gEfiTlsConfigurationProtocolGuid,
|
||||||
|
(VOID **) &TlsConfig,
|
||||||
|
TlsService->ImageHandle,
|
||||||
|
NULL,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls);
|
||||||
|
|
||||||
|
if (TlsInstance->Service != TlsService) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TlsInstance->InDestroy) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
TlsInstance->InDestroy = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
|
||||||
|
//
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ChildHandle,
|
||||||
|
&gEfiTlsProtocolGuid,
|
||||||
|
Tls,
|
||||||
|
&gEfiTlsConfigurationProtocolGuid,
|
||||||
|
TlsConfig,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveEntryList (&TlsInstance->Link);
|
||||||
|
TlsService->TlsChildrenNum--;
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
TlsCleanInstance (TlsInstance);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
237
NetworkPkg/TlsDxe/TlsDriver.h
Normal file
237
NetworkPkg/TlsDxe/TlsDriver.h
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
/** @file
|
||||||
|
Header file of the Driver Binding and Service Binding Protocol for TlsDxe driver.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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_TLS_DRIVER_H__
|
||||||
|
#define __EFI_TLS_DRIVER_H__
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Driver Protocols
|
||||||
|
//
|
||||||
|
#include <Protocol/ServiceBinding.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Driver Version
|
||||||
|
//
|
||||||
|
#define TLS_VERSION 0x00000000
|
||||||
|
|
||||||
|
#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S')
|
||||||
|
|
||||||
|
#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I')
|
||||||
|
|
||||||
|
///
|
||||||
|
/// TLS Service Data
|
||||||
|
///
|
||||||
|
typedef struct _TLS_SERVICE TLS_SERVICE;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// TLS Instance Data
|
||||||
|
///
|
||||||
|
typedef struct _TLS_INSTANCE TLS_INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
struct _TLS_SERVICE {
|
||||||
|
UINT32 Signature;
|
||||||
|
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||||
|
|
||||||
|
UINT16 TlsChildrenNum;
|
||||||
|
LIST_ENTRY TlsChildrenList;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle to install TlsServiceBinding protocol.
|
||||||
|
//
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
EFI_HANDLE ImageHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main SSL Context object which is created by a server or client once per program
|
||||||
|
// life-time and which holds mainly default values for the SSL object which are later
|
||||||
|
// created for the connections.
|
||||||
|
//
|
||||||
|
VOID *TlsCtx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TLS_INSTANCE {
|
||||||
|
UINT32 Signature;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
|
||||||
|
BOOLEAN InDestroy;
|
||||||
|
|
||||||
|
TLS_SERVICE *Service;
|
||||||
|
EFI_HANDLE ChildHandle;
|
||||||
|
|
||||||
|
EFI_TLS_PROTOCOL Tls;
|
||||||
|
EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig;
|
||||||
|
|
||||||
|
EFI_TLS_SESSION_STATE TlsSessionState;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main SSL Connection which is created by a server or a client
|
||||||
|
// per established connection.
|
||||||
|
//
|
||||||
|
VOID *TlsConn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define TLS_SERVICE_FROM_THIS(a) \
|
||||||
|
CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
|
||||||
|
|
||||||
|
#define TLS_INSTANCE_FROM_PROTOCOL(a) \
|
||||||
|
CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
|
||||||
|
|
||||||
|
#define TLS_INSTANCE_FROM_CONFIGURATION(a) \
|
||||||
|
CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release all the resources used by the TLS instance.
|
||||||
|
|
||||||
|
@param[in] Instance The TLS instance data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
TlsCleanInstance (
|
||||||
|
IN TLS_INSTANCE *Instance
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create the TLS instance and initialize it.
|
||||||
|
|
||||||
|
@param[in] Service The pointer to the TLS service.
|
||||||
|
@param[out] Instance The pointer to the TLS instance.
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||||
|
@retval EFI_SUCCESS The TLS instance is created.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsCreateInstance (
|
||||||
|
IN TLS_SERVICE *Service,
|
||||||
|
OUT TLS_INSTANCE **Instance
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release all the resources used by the TLS service binding instance.
|
||||||
|
|
||||||
|
@param[in] Service The TLS service data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
TlsCleanService (
|
||||||
|
IN TLS_SERVICE *Service
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create then initialize a TLS service.
|
||||||
|
|
||||||
|
@param[in] Image ImageHandle of the TLS driver
|
||||||
|
@param[out] Service The service for TLS driver
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
|
||||||
|
@retval EFI_SUCCESS The service is created for the driver.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsCreateService (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
OUT TLS_SERVICE **Service
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Unloads an image.
|
||||||
|
|
||||||
|
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The image has been unloaded.
|
||||||
|
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsUnload (
|
||||||
|
IN EFI_HANDLE ImageHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
||||||
|
|
||||||
|
@param ImageHandle The firmware allocated handle for the UEFI image.
|
||||||
|
@param SystemTable A pointer to the EFI System Table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval Others An unexpected error occurred.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsDriverEntryPoint (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a child handle and installs a protocol.
|
||||||
|
|
||||||
|
The CreateChild() function installs a protocol on ChildHandle.
|
||||||
|
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||||
|
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||||
|
@param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||||
|
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||||
|
then the protocol is added to the existing UEFI handle.
|
||||||
|
|
||||||
|
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||||
|
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||||
|
the child.
|
||||||
|
@retval other The child handle was not created.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsServiceBindingCreateChild (
|
||||||
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE *ChildHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroys a child handle with a protocol installed on it.
|
||||||
|
|
||||||
|
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||||
|
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||||
|
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||||
|
|
||||||
|
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||||
|
@param ChildHandle Handle of the child to destroy.
|
||||||
|
|
||||||
|
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||||
|
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||||
|
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||||
|
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||||
|
because its services are being used.
|
||||||
|
@retval other The child handle was not destroyed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsServiceBindingDestroyChild (
|
||||||
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ChildHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
65
NetworkPkg/TlsDxe/TlsDxe.inf
Normal file
65
NetworkPkg/TlsDxe/TlsDxe.inf
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
## @file
|
||||||
|
# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
|
||||||
|
# EFI TLS Configuration Protocol.
|
||||||
|
#
|
||||||
|
# This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS
|
||||||
|
# Service Binding Protocol, to provide TLS services.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016, 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 = TlsDxe
|
||||||
|
FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646
|
||||||
|
MODULE_TYPE = UEFI_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
ENTRY_POINT = TlsDriverEntryPoint
|
||||||
|
UNLOAD_IMAGE = TlsUnload
|
||||||
|
MODULE_UNI_FILE = TlsDxe.uni
|
||||||
|
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
CryptoPkg/CryptoPkg.dec
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
TlsDriver.h
|
||||||
|
TlsDriver.c
|
||||||
|
TlsProtocol.c
|
||||||
|
TlsConfigProtocol.c
|
||||||
|
TlsImpl.h
|
||||||
|
TlsImpl.c
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
BaseMemoryLib
|
||||||
|
BaseLib
|
||||||
|
UefiLib
|
||||||
|
DebugLib
|
||||||
|
NetLib
|
||||||
|
BaseCryptLib
|
||||||
|
TlsLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiTlsServiceBindingProtocolGuid ## PRODUCES
|
||||||
|
gEfiTlsProtocolGuid ## PRODUCES
|
||||||
|
gEfiTlsConfigurationProtocolGuid ## PRODUCES
|
||||||
|
|
||||||
|
[UserExtensions.TianoCore."ExtraFiles"]
|
||||||
|
TlsDxeExtra.uni
|
25
NetworkPkg/TlsDxe/TlsDxe.uni
Normal file
25
NetworkPkg/TlsDxe/TlsDxe.uni
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// /** @file
|
||||||
|
// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
|
||||||
|
// EFI TLS Configuration Protocol.
|
||||||
|
//
|
||||||
|
// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
|
||||||
|
// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS
|
||||||
|
// services.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016, 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service"
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services."
|
||||||
|
|
18
NetworkPkg/TlsDxe/TlsDxeExtra.uni
Normal file
18
NetworkPkg/TlsDxe/TlsDxeExtra.uni
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// /** @file
|
||||||
|
// TlsDxe Localized Strings and Content
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016, 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
#string STR_PROPERTIES_MODULE_NAME
|
||||||
|
#language en-US
|
||||||
|
"EFI TLS DXE Driver"
|
326
NetworkPkg/TlsDxe/TlsImpl.c
Normal file
326
NetworkPkg/TlsDxe/TlsImpl.c
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
/** @file
|
||||||
|
The Miscellaneous Routines for TlsDxe driver.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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 "TlsImpl.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Encrypt the message listed in fragment.
|
||||||
|
|
||||||
|
@param[in] TlsInstance The pointer to the TLS instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment.
|
||||||
|
On input these fragments contain the TLS header and
|
||||||
|
plain text TLS payload;
|
||||||
|
On output these fragments contain the TLS header and
|
||||||
|
cipher text TLS payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
|
||||||
|
@retval EFI_ABORTED TLS session state is incorrect.
|
||||||
|
@retval Others Other errors as indicated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsEncryptPacket (
|
||||||
|
IN TLS_INSTANCE *TlsInstance,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 BytesCopied;
|
||||||
|
UINT32 BufferInSize;
|
||||||
|
UINT8 *BufferIn;
|
||||||
|
UINT8 *BufferInPtr;
|
||||||
|
TLS_RECORD_HEADER *RecordHeaderIn;
|
||||||
|
UINT16 ThisPlainMessageSize;
|
||||||
|
TLS_RECORD_HEADER *TempRecordHeader;
|
||||||
|
UINT16 ThisMessageSize;
|
||||||
|
UINT32 BufferOutSize;
|
||||||
|
UINT8 *BufferOut;
|
||||||
|
INTN Ret;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
BytesCopied = 0;
|
||||||
|
BufferInSize = 0;
|
||||||
|
BufferIn = NULL;
|
||||||
|
BufferInPtr = NULL;
|
||||||
|
RecordHeaderIn = NULL;
|
||||||
|
TempRecordHeader = NULL;
|
||||||
|
BufferOutSize = 0;
|
||||||
|
BufferOut = NULL;
|
||||||
|
Ret = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the size according to the fragment table.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||||
|
BufferInSize += (*FragmentTable)[Index].FragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate buffer for processing data.
|
||||||
|
//
|
||||||
|
BufferIn = AllocateZeroPool (BufferInSize);
|
||||||
|
if (BufferIn == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy all TLS plain record header and payload into BufferIn.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||||
|
CopyMem (
|
||||||
|
(BufferIn + BytesCopied),
|
||||||
|
(*FragmentTable)[Index].FragmentBuffer,
|
||||||
|
(*FragmentTable)[Index].FragmentLength
|
||||||
|
);
|
||||||
|
BytesCopied += (*FragmentTable)[Index].FragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
|
||||||
|
if (BufferOut == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parsing buffer.
|
||||||
|
//
|
||||||
|
BufferInPtr = BufferIn;
|
||||||
|
TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
|
||||||
|
while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
|
||||||
|
RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
|
||||||
|
|
||||||
|
if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPlainMessageSize = RecordHeaderIn->Length;
|
||||||
|
|
||||||
|
TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);
|
||||||
|
|
||||||
|
Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize);
|
||||||
|
|
||||||
|
if (Ret > 0) {
|
||||||
|
ThisMessageSize = (UINT16) Ret;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// No data was successfully encrypted, continue to encrypt other messages.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_WARN, "TlsEncryptPacket: No data read from TLS object.\n"));
|
||||||
|
|
||||||
|
ThisMessageSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferOutSize += ThisMessageSize;
|
||||||
|
|
||||||
|
BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
|
||||||
|
TempRecordHeader += ThisMessageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (BufferIn);
|
||||||
|
BufferIn = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The caller will be responsible to handle the original fragment table.
|
||||||
|
//
|
||||||
|
*FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
|
||||||
|
if (*FragmentTable == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*FragmentTable)[0].FragmentBuffer = BufferOut;
|
||||||
|
(*FragmentTable)[0].FragmentLength = BufferOutSize;
|
||||||
|
*FragmentCount = 1;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
ERROR:
|
||||||
|
|
||||||
|
if (BufferIn != NULL) {
|
||||||
|
FreePool (BufferIn);
|
||||||
|
BufferIn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferOut != NULL) {
|
||||||
|
FreePool (BufferOut);
|
||||||
|
BufferOut = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decrypt the message listed in fragment.
|
||||||
|
|
||||||
|
@param[in] TlsInstance The pointer to the TLS instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment.
|
||||||
|
On input these fragments contain the TLS header and
|
||||||
|
cipher text TLS payload;
|
||||||
|
On output these fragments contain the TLS header and
|
||||||
|
plain text TLS payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
|
||||||
|
@retval EFI_ABORTED TLS session state is incorrect.
|
||||||
|
@retval Others Other errors as indicated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsDecryptPacket (
|
||||||
|
IN TLS_INSTANCE *TlsInstance,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 BytesCopied;
|
||||||
|
UINT8 *BufferIn;
|
||||||
|
UINT32 BufferInSize;
|
||||||
|
UINT8 *BufferInPtr;
|
||||||
|
TLS_RECORD_HEADER *RecordHeaderIn;
|
||||||
|
UINT16 ThisCipherMessageSize;
|
||||||
|
TLS_RECORD_HEADER *TempRecordHeader;
|
||||||
|
UINT16 ThisPlainMessageSize;
|
||||||
|
UINT8 *BufferOut;
|
||||||
|
UINT32 BufferOutSize;
|
||||||
|
INTN Ret;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
BytesCopied = 0;
|
||||||
|
BufferIn = NULL;
|
||||||
|
BufferInSize = 0;
|
||||||
|
BufferInPtr = NULL;
|
||||||
|
RecordHeaderIn = NULL;
|
||||||
|
TempRecordHeader = NULL;
|
||||||
|
BufferOut = NULL;
|
||||||
|
BufferOutSize = 0;
|
||||||
|
Ret = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the size according to the fragment table.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||||
|
BufferInSize += (*FragmentTable)[Index].FragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate buffer for processing data
|
||||||
|
//
|
||||||
|
BufferIn = AllocateZeroPool (BufferInSize);
|
||||||
|
if (BufferIn == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy all TLS plain record header and payload to BufferIn
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < *FragmentCount; Index++) {
|
||||||
|
CopyMem (
|
||||||
|
(BufferIn + BytesCopied),
|
||||||
|
(*FragmentTable)[Index].FragmentBuffer,
|
||||||
|
(*FragmentTable)[Index].FragmentLength
|
||||||
|
);
|
||||||
|
BytesCopied += (*FragmentTable)[Index].FragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
|
||||||
|
if (BufferOut == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parsing buffer. Received packet may have multiple TLS record messages.
|
||||||
|
//
|
||||||
|
BufferInPtr = BufferIn;
|
||||||
|
TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
|
||||||
|
while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
|
||||||
|
RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
|
||||||
|
|
||||||
|
if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
|
||||||
|
|
||||||
|
Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);
|
||||||
|
if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
|
||||||
|
TlsInstance->TlsSessionState = EfiTlsSessionError;
|
||||||
|
Status = EFI_ABORTED;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = 0;
|
||||||
|
Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize);
|
||||||
|
|
||||||
|
if (Ret > 0) {
|
||||||
|
ThisPlainMessageSize = (UINT16) Ret;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// No data was successfully decrypted, continue to decrypt other messages.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));
|
||||||
|
|
||||||
|
ThisPlainMessageSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);
|
||||||
|
TempRecordHeader->Length = ThisPlainMessageSize;
|
||||||
|
BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
|
||||||
|
|
||||||
|
BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
|
||||||
|
TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (BufferIn);
|
||||||
|
BufferIn = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The caller will be responsible to handle the original fragment table
|
||||||
|
//
|
||||||
|
*FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
|
||||||
|
if (*FragmentTable == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*FragmentTable)[0].FragmentBuffer = BufferOut;
|
||||||
|
(*FragmentTable)[0].FragmentLength = BufferOutSize;
|
||||||
|
*FragmentCount = 1;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
ERROR:
|
||||||
|
|
||||||
|
if (BufferIn != NULL) {
|
||||||
|
FreePool (BufferIn);
|
||||||
|
BufferIn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferOut != NULL) {
|
||||||
|
FreePool (BufferOut);
|
||||||
|
BufferOut = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
315
NetworkPkg/TlsDxe/TlsImpl.h
Normal file
315
NetworkPkg/TlsDxe/TlsImpl.h
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
/** @file
|
||||||
|
Header file of Miscellaneous Routines for TlsDxe driver.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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_TLS_IMPL_H__
|
||||||
|
#define __EFI_TLS_IMPL_H__
|
||||||
|
|
||||||
|
//
|
||||||
|
// Libraries
|
||||||
|
//
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/NetLib.h>
|
||||||
|
#include <Library/BaseCryptLib.h>
|
||||||
|
#include <Library/TlsLib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Consumed Protocols
|
||||||
|
//
|
||||||
|
#include <Protocol/Tls.h>
|
||||||
|
#include <Protocol/TlsConfig.h>
|
||||||
|
|
||||||
|
#include <IndustryStandard/Tls1.h>
|
||||||
|
|
||||||
|
#include "TlsDriver.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protocol instances
|
||||||
|
//
|
||||||
|
extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding;
|
||||||
|
extern EFI_TLS_PROTOCOL mTlsProtocol;
|
||||||
|
extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol;
|
||||||
|
|
||||||
|
#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2)
|
||||||
|
|
||||||
|
#define MAX_BUFFER_SIZE 32768
|
||||||
|
|
||||||
|
/**
|
||||||
|
Encrypt the message listed in fragment.
|
||||||
|
|
||||||
|
@param[in] TlsInstance The pointer to the TLS instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment.
|
||||||
|
On input these fragments contain the TLS header and
|
||||||
|
plain text TLS payload;
|
||||||
|
On output these fragments contain the TLS header and
|
||||||
|
cipher text TLS payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
|
||||||
|
@retval EFI_ABORTED TLS session state is incorrect.
|
||||||
|
@retval Others Other errors as indicated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsEncryptPacket (
|
||||||
|
IN TLS_INSTANCE *TlsInstance,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decrypt the message listed in fragment.
|
||||||
|
|
||||||
|
@param[in] TlsInstance The pointer to the TLS instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment.
|
||||||
|
On input these fragments contain the TLS header and
|
||||||
|
cipher text TLS payload;
|
||||||
|
On output these fragments contain the TLS header and
|
||||||
|
plain text TLS payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
|
||||||
|
@retval EFI_ABORTED TLS session state is incorrect.
|
||||||
|
@retval Others Other errors as indicated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlsDecryptPacket (
|
||||||
|
IN TLS_INSTANCE *TlsInstance,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set TLS session data.
|
||||||
|
|
||||||
|
The SetSessionData() function set data for a new TLS session. All session data should
|
||||||
|
be set before BuildResponsePacket() invoked.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] DataType TLS session data type.
|
||||||
|
@param[in] Data Pointer to session data.
|
||||||
|
@param[in] DataSize Total size of session data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS session data is set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
Data is NULL.
|
||||||
|
DataSize is 0.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_ACCESS_DENIED If the DataType is one of below:
|
||||||
|
EfiTlsClientRandom
|
||||||
|
EfiTlsServerRandom
|
||||||
|
EfiTlsKeyMaterial
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT
|
||||||
|
EfiTlsSessionStateNotStarted.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetSessionData (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_SESSION_DATA_TYPE DataType,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get TLS session data.
|
||||||
|
|
||||||
|
The GetSessionData() function return the TLS session information.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] DataType TLS session data type.
|
||||||
|
@param[in, out] Data Pointer to session data.
|
||||||
|
@param[in, out] DataSize Total size of session data. On input, it means
|
||||||
|
the size of Data buffer. On output, it means the size
|
||||||
|
of copied Data buffer if EFI_SUCCESS, and means the
|
||||||
|
size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS session data is got successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
DataSize is NULL.
|
||||||
|
Data is NULL if *DataSize is not zero.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_NOT_FOUND The TLS session data is not found.
|
||||||
|
@retval EFI_NOT_READY The DataType is not ready in current session state.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetSessionData (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_SESSION_DATA_TYPE DataType,
|
||||||
|
IN OUT VOID *Data, OPTIONAL
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build response packet according to TLS state machine. This function is only valid for
|
||||||
|
alert, handshake and change_cipher_spec content type.
|
||||||
|
|
||||||
|
The BuildResponsePacket() function builds TLS response packet in response to the TLS
|
||||||
|
request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
|
||||||
|
RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
|
||||||
|
will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
|
||||||
|
NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
|
||||||
|
session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
|
||||||
|
NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
|
||||||
|
session has errors and the response packet needs to be Alert message based on error
|
||||||
|
type.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
|
||||||
|
means TLS need initiate the TLS session and response
|
||||||
|
packet need to be ClientHello.
|
||||||
|
@param[in] RequestSize Packet size in bytes for the most recently received TLS
|
||||||
|
packet. 0 is only valid when RequestBuffer is NULL.
|
||||||
|
@param[out] Buffer Pointer to the buffer to hold the built packet.
|
||||||
|
@param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
|
||||||
|
the buffer size provided by the caller. On output, it
|
||||||
|
is the buffer size in fact needed to contain the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The required TLS packet is built successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
RequestBuffer is NULL but RequestSize is NOT 0.
|
||||||
|
RequestSize is 0 but RequestBuffer is NOT NULL.
|
||||||
|
BufferSize is NULL.
|
||||||
|
Buffer is NULL if *BufferSize is not zero.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT ready to build
|
||||||
|
ResponsePacket.
|
||||||
|
@retval EFI_ABORTED Something wrong build response packet.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsBuildResponsePacket (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN UINT8 *RequestBuffer, OPTIONAL
|
||||||
|
IN UINTN RequestSize, OPTIONAL
|
||||||
|
OUT UINT8 *Buffer, OPTIONAL
|
||||||
|
IN OUT UINTN *BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decrypt or encrypt TLS packet during session. This function is only valid after
|
||||||
|
session connected and for application_data content type.
|
||||||
|
|
||||||
|
The ProcessPacket () function process each inbound or outbound TLS APP packet.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
|
||||||
|
responsible to handle the original FragmentTable while
|
||||||
|
it may be reallocated in TLS driver. If CryptMode is
|
||||||
|
EfiTlsEncrypt, on input these fragments contain the TLS
|
||||||
|
header and plain text TLS APP payload; on output these
|
||||||
|
fragments contain the TLS header and cipher text TLS
|
||||||
|
APP payload. If CryptMode is EfiTlsDecrypt, on input
|
||||||
|
these fragments contain the TLS header and cipher text
|
||||||
|
TLS APP payload; on output these fragments contain the
|
||||||
|
TLS header and plain text TLS APP payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
@param[in] CryptMode Crypt mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
FragmentTable is NULL.
|
||||||
|
FragmentCount is NULL.
|
||||||
|
CryptoMode is invalid.
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT
|
||||||
|
EfiTlsSessionDataTransferring.
|
||||||
|
@retval EFI_ABORTED Something wrong decryption the message. TLS session
|
||||||
|
status will become EfiTlsSessionError. The caller need
|
||||||
|
call BuildResponsePacket() to generate Error Alert
|
||||||
|
message and send it out.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsProcessPacket (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount,
|
||||||
|
IN EFI_TLS_CRYPT_MODE CryptMode
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set TLS configuration data.
|
||||||
|
|
||||||
|
The SetData() function sets TLS configuration to non-volatile storage or volatile
|
||||||
|
storage.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
|
||||||
|
@param[in] DataType Configuration data type.
|
||||||
|
@param[in] Data Pointer to configuration data.
|
||||||
|
@param[in] DataSize Total size of configuration data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS configuration data is set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
Data is NULL.
|
||||||
|
DataSize is 0.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsConfigurationSetData (
|
||||||
|
IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_CONFIG_DATA_TYPE DataType,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get TLS configuration data.
|
||||||
|
|
||||||
|
The GetData() function gets TLS configuration.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
|
||||||
|
@param[in] DataType Configuration data type.
|
||||||
|
@param[in, out] Data Pointer to configuration data.
|
||||||
|
@param[in, out] DataSize Total size of configuration data. On input, it means
|
||||||
|
the size of Data buffer. On output, it means the size
|
||||||
|
of copied Data buffer if EFI_SUCCESS, and means the
|
||||||
|
size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS configuration data is got successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
DataSize is NULL.
|
||||||
|
Data is NULL if *DataSize is not zero.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_NOT_FOUND The TLS configuration data is not found.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsConfigurationGetData (
|
||||||
|
IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_CONFIG_DATA_TYPE DataType,
|
||||||
|
IN OUT VOID *Data, OPTIONAL
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
632
NetworkPkg/TlsDxe/TlsProtocol.c
Normal file
632
NetworkPkg/TlsDxe/TlsProtocol.c
Normal file
@@ -0,0 +1,632 @@
|
|||||||
|
/** @file
|
||||||
|
Implementation of EFI TLS Protocol Interfaces.
|
||||||
|
|
||||||
|
Copyright (c) 2016, 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 "TlsImpl.h"
|
||||||
|
|
||||||
|
EFI_TLS_PROTOCOL mTlsProtocol = {
|
||||||
|
TlsSetSessionData,
|
||||||
|
TlsGetSessionData,
|
||||||
|
TlsBuildResponsePacket,
|
||||||
|
TlsProcessPacket
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set TLS session data.
|
||||||
|
|
||||||
|
The SetSessionData() function set data for a new TLS session. All session data should
|
||||||
|
be set before BuildResponsePacket() invoked.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] DataType TLS session data type.
|
||||||
|
@param[in] Data Pointer to session data.
|
||||||
|
@param[in] DataSize Total size of session data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS session data is set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
Data is NULL.
|
||||||
|
DataSize is 0.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_ACCESS_DENIED If the DataType is one of below:
|
||||||
|
EfiTlsClientRandom
|
||||||
|
EfiTlsServerRandom
|
||||||
|
EfiTlsKeyMaterial
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT
|
||||||
|
EfiTlsSessionStateNotStarted.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetSessionData (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_SESSION_DATA_TYPE DataType,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
UINT16 *CipherId;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
CipherId = NULL;
|
||||||
|
|
||||||
|
if (This == NULL || Data == NULL || DataSize == 0) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_PROTOCOL (This);
|
||||||
|
|
||||||
|
if (DataType != EfiTlsSessionState && Instance->TlsSessionState != EfiTlsSessionNotStarted){
|
||||||
|
Status = EFI_NOT_READY;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DataType) {
|
||||||
|
//
|
||||||
|
// Session Configuration
|
||||||
|
//
|
||||||
|
case EfiTlsVersion:
|
||||||
|
if (DataSize != sizeof (EFI_TLS_VERSION)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);
|
||||||
|
break;
|
||||||
|
case EfiTlsConnectionEnd:
|
||||||
|
if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));
|
||||||
|
break;
|
||||||
|
case EfiTlsCipherList:
|
||||||
|
CipherId = AllocatePool (DataSize);
|
||||||
|
if (CipherId == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
|
||||||
|
*(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));
|
||||||
|
|
||||||
|
FreePool (CipherId);
|
||||||
|
break;
|
||||||
|
case EfiTlsCompressionMethod:
|
||||||
|
//
|
||||||
|
// TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
|
||||||
|
// record protocol will not be compressed.
|
||||||
|
// More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
|
||||||
|
// The TLS RFC does however not specify compression methods or their corresponding identifiers,
|
||||||
|
// so there is currently no compatible way to integrate compression with unknown peers.
|
||||||
|
// It is therefore currently not recommended to integrate compression into applications.
|
||||||
|
// Applications for non-public use may agree on certain compression methods.
|
||||||
|
// Using different compression methods with the same identifier will lead to connection failure.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
|
||||||
|
Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EfiTlsExtensionData:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
goto ON_EXIT;
|
||||||
|
case EfiTlsVerifyMethod:
|
||||||
|
if (DataSize != sizeof (EFI_TLS_VERIFY)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionID:
|
||||||
|
if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TlsSetSessionId (
|
||||||
|
Instance->TlsConn,
|
||||||
|
((EFI_TLS_SESSION_ID *) Data)->Data,
|
||||||
|
((EFI_TLS_SESSION_ID *) Data)->Length
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionState:
|
||||||
|
if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
// Session information
|
||||||
|
//
|
||||||
|
case EfiTlsClientRandom:
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
break;
|
||||||
|
case EfiTlsServerRandom:
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
break;
|
||||||
|
case EfiTlsKeyMaterial:
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
// Unsupported type.
|
||||||
|
//
|
||||||
|
default:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get TLS session data.
|
||||||
|
|
||||||
|
The GetSessionData() function return the TLS session information.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] DataType TLS session data type.
|
||||||
|
@param[in, out] Data Pointer to session data.
|
||||||
|
@param[in, out] DataSize Total size of session data. On input, it means
|
||||||
|
the size of Data buffer. On output, it means the size
|
||||||
|
of copied Data buffer if EFI_SUCCESS, and means the
|
||||||
|
size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS session data is got successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
DataSize is NULL.
|
||||||
|
Data is NULL if *DataSize is not zero.
|
||||||
|
@retval EFI_UNSUPPORTED The DataType is unsupported.
|
||||||
|
@retval EFI_NOT_FOUND The TLS session data is not found.
|
||||||
|
@retval EFI_NOT_READY The DataType is not ready in current session state.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetSessionData (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN EFI_TLS_SESSION_DATA_TYPE DataType,
|
||||||
|
IN OUT VOID *Data, OPTIONAL
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_PROTOCOL (This);
|
||||||
|
|
||||||
|
if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
|
||||||
|
(DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
|
||||||
|
DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
|
||||||
|
Status = EFI_NOT_READY;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DataType) {
|
||||||
|
case EfiTlsVersion:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_VERSION)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_VERSION);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_VERSION);
|
||||||
|
*((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
|
||||||
|
break;
|
||||||
|
case EfiTlsConnectionEnd:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_CONNECTION_END);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_CONNECTION_END);
|
||||||
|
*((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
|
||||||
|
break;
|
||||||
|
case EfiTlsCipherList:
|
||||||
|
//
|
||||||
|
// Get the current session cipher suite.
|
||||||
|
//
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_CIPHER);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof(EFI_TLS_CIPHER);
|
||||||
|
Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
|
||||||
|
*((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
|
||||||
|
break;
|
||||||
|
case EfiTlsCompressionMethod:
|
||||||
|
//
|
||||||
|
// Get the current session compression method.
|
||||||
|
//
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_COMPRESSION);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_COMPRESSION);
|
||||||
|
Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);
|
||||||
|
break;
|
||||||
|
case EfiTlsExtensionData:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
goto ON_EXIT;
|
||||||
|
case EfiTlsVerifyMethod:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_VERIFY);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_VERIFY);
|
||||||
|
*((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionID:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_SESSION_ID);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_SESSION_ID);
|
||||||
|
Status = TlsGetSessionId (
|
||||||
|
Instance->TlsConn,
|
||||||
|
((EFI_TLS_SESSION_ID *) Data)->Data,
|
||||||
|
&(((EFI_TLS_SESSION_ID *) Data)->Length)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionState:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_SESSION_STATE);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_SESSION_STATE);
|
||||||
|
CopyMem (Data, &Instance->TlsSessionState, *DataSize);
|
||||||
|
break;
|
||||||
|
case EfiTlsClientRandom:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_RANDOM);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_RANDOM);
|
||||||
|
TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
|
||||||
|
break;
|
||||||
|
case EfiTlsServerRandom:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_RANDOM);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_RANDOM);
|
||||||
|
TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
|
||||||
|
break;
|
||||||
|
case EfiTlsKeyMaterial:
|
||||||
|
if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
|
||||||
|
*DataSize = sizeof (EFI_TLS_MASTER_SECRET);
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
*DataSize = sizeof (EFI_TLS_MASTER_SECRET);
|
||||||
|
Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
// Unsupported type.
|
||||||
|
//
|
||||||
|
default:
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build response packet according to TLS state machine. This function is only valid for
|
||||||
|
alert, handshake and change_cipher_spec content type.
|
||||||
|
|
||||||
|
The BuildResponsePacket() function builds TLS response packet in response to the TLS
|
||||||
|
request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
|
||||||
|
RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
|
||||||
|
will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
|
||||||
|
NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
|
||||||
|
session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
|
||||||
|
NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
|
||||||
|
session has errors and the response packet needs to be Alert message based on error
|
||||||
|
type.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
|
||||||
|
means TLS need initiate the TLS session and response
|
||||||
|
packet need to be ClientHello.
|
||||||
|
@param[in] RequestSize Packet size in bytes for the most recently received TLS
|
||||||
|
packet. 0 is only valid when RequestBuffer is NULL.
|
||||||
|
@param[out] Buffer Pointer to the buffer to hold the built packet.
|
||||||
|
@param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
|
||||||
|
the buffer size provided by the caller. On output, it
|
||||||
|
is the buffer size in fact needed to contain the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The required TLS packet is built successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
RequestBuffer is NULL but RequestSize is NOT 0.
|
||||||
|
RequestSize is 0 but RequestBuffer is NOT NULL.
|
||||||
|
BufferSize is NULL.
|
||||||
|
Buffer is NULL if *BufferSize is not zero.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT ready to build
|
||||||
|
ResponsePacket.
|
||||||
|
@retval EFI_ABORTED Something wrong build response packet.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsBuildResponsePacket (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN UINT8 *RequestBuffer, OPTIONAL
|
||||||
|
IN UINTN RequestSize, OPTIONAL
|
||||||
|
OUT UINT8 *Buffer, OPTIONAL
|
||||||
|
IN OUT UINTN *BufferSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
if ((This == NULL) || (BufferSize == NULL) ||
|
||||||
|
(RequestBuffer == NULL && RequestSize != 0) ||
|
||||||
|
(RequestBuffer != NULL && RequestSize == 0) ||
|
||||||
|
(Buffer == NULL && *BufferSize !=0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_PROTOCOL (This);
|
||||||
|
|
||||||
|
if(RequestBuffer == NULL && RequestSize == 0) {
|
||||||
|
switch (Instance->TlsSessionState) {
|
||||||
|
case EfiTlsSessionNotStarted:
|
||||||
|
//
|
||||||
|
// ClientHello.
|
||||||
|
//
|
||||||
|
Status = TlsDoHandshake (
|
||||||
|
Instance->TlsConn,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
Buffer,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// *BufferSize should not be zero when ClientHello.
|
||||||
|
//
|
||||||
|
if (*BufferSize == 0) {
|
||||||
|
Status = EFI_ABORTED;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instance->TlsSessionState = EfiTlsSessionHandShaking;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionClosing:
|
||||||
|
//
|
||||||
|
// TLS session will be closed and response packet needs to be CloseNotify.
|
||||||
|
//
|
||||||
|
Status = TlsCloseNotify (
|
||||||
|
Instance->TlsConn,
|
||||||
|
Buffer,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// *BufferSize should not be zero when build CloseNotify message.
|
||||||
|
//
|
||||||
|
if (*BufferSize == 0) {
|
||||||
|
Status = EFI_ABORTED;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EfiTlsSessionError:
|
||||||
|
//
|
||||||
|
// TLS session has errors and the response packet needs to be Alert
|
||||||
|
// message based on error type.
|
||||||
|
//
|
||||||
|
Status = TlsHandleAlert (
|
||||||
|
Instance->TlsConn,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
Buffer,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//
|
||||||
|
// Current TLS session state is NOT ready to build ResponsePacket.
|
||||||
|
//
|
||||||
|
Status = EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// 1. Received packet may have multiple TLS record messages.
|
||||||
|
// 2. One TLS record message may have multiple handshake protocol.
|
||||||
|
// 3. Some errors may be happened in handshake.
|
||||||
|
// TlsDoHandshake() can handle all of those cases.
|
||||||
|
//
|
||||||
|
if (TlsInHandshake (Instance->TlsConn)) {
|
||||||
|
Status = TlsDoHandshake (
|
||||||
|
Instance->TlsConn,
|
||||||
|
RequestBuffer,
|
||||||
|
RequestSize,
|
||||||
|
Buffer,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TlsInHandshake (Instance->TlsConn)) {
|
||||||
|
Instance->TlsSessionState = EfiTlsSessionDataTransferring;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Must be alert message, Decrypt it and build the ResponsePacket.
|
||||||
|
//
|
||||||
|
ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TLS_CONTENT_TYPE_ALERT);
|
||||||
|
|
||||||
|
Status = TlsHandleAlert (
|
||||||
|
Instance->TlsConn,
|
||||||
|
RequestBuffer,
|
||||||
|
RequestSize,
|
||||||
|
Buffer,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
Instance->TlsSessionState = EfiTlsSessionError;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decrypt or encrypt TLS packet during session. This function is only valid after
|
||||||
|
session connected and for application_data content type.
|
||||||
|
|
||||||
|
The ProcessPacket () function process each inbound or outbound TLS APP packet.
|
||||||
|
|
||||||
|
@param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
|
||||||
|
@param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
|
||||||
|
responsible to handle the original FragmentTable while
|
||||||
|
it may be reallocated in TLS driver. If CryptMode is
|
||||||
|
EfiTlsEncrypt, on input these fragments contain the TLS
|
||||||
|
header and plain text TLS APP payload; on output these
|
||||||
|
fragments contain the TLS header and cipher text TLS
|
||||||
|
APP payload. If CryptMode is EfiTlsDecrypt, on input
|
||||||
|
these fragments contain the TLS header and cipher text
|
||||||
|
TLS APP payload; on output these fragments contain the
|
||||||
|
TLS header and plain text TLS APP payload.
|
||||||
|
@param[in] FragmentCount Number of fragment.
|
||||||
|
@param[in] CryptMode Crypt mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
This is NULL.
|
||||||
|
FragmentTable is NULL.
|
||||||
|
FragmentCount is NULL.
|
||||||
|
CryptoMode is invalid.
|
||||||
|
@retval EFI_NOT_READY Current TLS session state is NOT
|
||||||
|
EfiTlsSessionDataTransferring.
|
||||||
|
@retval EFI_ABORTED Something wrong decryption the message. TLS session
|
||||||
|
status will become EfiTlsSessionError. The caller need
|
||||||
|
call BuildResponsePacket() to generate Error Alert
|
||||||
|
message and send it out.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsProcessPacket (
|
||||||
|
IN EFI_TLS_PROTOCOL *This,
|
||||||
|
IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
|
||||||
|
IN UINT32 *FragmentCount,
|
||||||
|
IN EFI_TLS_CRYPT_MODE CryptMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
TLS_INSTANCE *Instance;
|
||||||
|
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
Instance = TLS_INSTANCE_FROM_PROTOCOL (This);
|
||||||
|
|
||||||
|
if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
|
||||||
|
Status = EFI_NOT_READY;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Packet sent or received may have multiple TLS record messages (Application data type).
|
||||||
|
// So,on input these fragments contain the TLS header and TLS APP payload;
|
||||||
|
// on output these fragments also contain the TLS header and TLS APP payload.
|
||||||
|
//
|
||||||
|
switch (CryptMode) {
|
||||||
|
case EfiTlsEncrypt:
|
||||||
|
Status = TlsEncryptPacket (Instance, FragmentTable, FragmentCount);
|
||||||
|
break;
|
||||||
|
case EfiTlsDecrypt:
|
||||||
|
Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
Reference in New Issue
Block a user