mirror of https://github.com/acidanthera/audk.git
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:
parent
9396cdfeaa
commit
7e1f2209b0
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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."
|
||||
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue