📄 efibis_basecode.c
字号:
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
efibis_basecode.c
Abstract:
Public EFI/BIS functions.
Revision History
--*/
#include <efi.h>
#include <efidriverlib.h>
#include EFI_PROTOCOL_DEFINITION (Bis)
#include <bisBaseCode.h>
static EFI_GUID BISBaseCodeProto= EFI_BIS_PROTOCOL_GUID;
EFI_BIS_PROTOCOL *BISBC= NULL;
//
// EBDP2DB - Assign EFI_BIS_DATA* to BIS_DATA.
// Conversion is safe even if null EFI_BIS_DATA* is presented.
//
void
EBDP2BD( EFI_BIS_DATA *ebdp, BIS_DATA* bd)
{
if ( ebdp == NULL ){
bd->length= 0;
bd->data= 0;
}
else {
bd->length= ebdp->Length;
bd->data= ebdp->Data;
}
}
//
// getInstanceData -
// parm: EFI_BIS_PROTOCOL pointer
// returns: address of BISBC_INSTANCEDATA that contains the input parm.
//
BISBC_INSTANCEDATA*
getInstanceData( EFI_BIS_PROTOCOL *bisInterface )
{
BISBC_INSTANCEDATA *result= NULL;
if ( bisInterface != NULL )
{
result= CR(bisInterface, BISBC_INSTANCEDATA, bisInterface, BBCIDSIG);
//structure at computed address should contain structure length
//and contain signature.
if ( result->sizeOfThis != sizeof(BISBC_INSTANCEDATA)
|| result->Signature != BBCIDSIG )
{
result= NULL;
}
}
return result;
}
//
// EFI_BIS_Initialize()
//
EFI_STATUS
EFI_BIS_Initialize(
IN EFI_BIS_PROTOCOL *This, //this
OUT BIS_APPLICATION_HANDLE *AppHandle, //Application handle.
IN OUT EFI_BIS_VERSION *InterfaceVersion, //ver needed/available.
IN EFI_BIS_DATA *TargetAddress //Address of BIS platform.
)
{
BIS_INIT_PARMS initParms;
BIS_INIT_PARMS *parmBlock= &initParms;
BIS_APPINFO_PTR appInfo;
NVM_AREA_ID bisNvmAreaId= NVM_BIS_AREA_ID;
UINT32 maxSize;
BIS_STATUS addOK;
BISBC_INSTANCEDATA *bisGlobal;
COLLECTION *appInfoTrackingCollection;
//Print(L"Bis_Initialize called\n");
if ( This == NULL || AppHandle == NULL
|| InterfaceVersion == NULL )
{
return EFI_DEVICE_ERROR;
}
//
// Do parm block validation. Almost verbatim from BIS legacy client.
//
bisGlobal= getInstanceData( This );
if ( bisGlobal == NULL )
{
return EFI_DEVICE_ERROR;
}
//Only one BIS user at a time.
if ( bisGlobal->bisInUse == BIS_TRUE ){
return EFI_OUT_OF_RESOURCES;
}
appInfoTrackingCollection= bisGlobal->appInfoTrackingCollection;
//Convert EFI_BIS parms to BIS parm block.
EfiZeroMem( &initParms, sizeof(initParms) );
initParms.sizeOfStruct= sizeof(initParms);
initParms.interfaceVersion.major= InterfaceVersion->Major;
initParms.interfaceVersion.minor= InterfaceVersion->Minor;
EBDP2BD( TargetAddress, &initParms.targetAddress);
//Version negotiation. As of Sept. 98 there is only one
//version. If you ask for anything else, we fail you.
//In the future we'll need to determine if the requested
//version is compatible with the available version.
if (parmBlock->interfaceVersion.major != BIS_CURRENT_VERSION_MAJOR)
{
//pass back actual numbers.
InterfaceVersion->Major= BIS_CURRENT_VERSION_MAJOR;
InterfaceVersion->Minor= BIS_CURRENT_VERSION_MINOR;
return EFI_INCOMPATIBLE_VERSION;
}
//pass back actual minor version.
InterfaceVersion->Minor= BIS_CURRENT_VERSION_MINOR;
//Allocate and initialize appInfo structure and CSSM structure.
parmBlock->appHandle= BIS_NULL;
appInfo= (BIS_APPINFO_PTR) x_malloc( sizeof(BIS_APPINFO) + sizeof(APP_CSSMINFO));
if (appInfo)
{
appInfo->SizeOfStruct= sizeof(BIS_APPINFO);
//Add new appinfo struct to BIS' collection.
addOK= COL_AddElement( appInfoTrackingCollection, (UINTN)appInfo );
//create the apps memory tracking collection.
if (addOK)
{
appInfo->memoryAllocations= COL_New( BIS_INIT_COLLECTION_SIZE
, BIS_INIT_COLLECTION_INCR );
}
//Bail on memory allocation failures.
if (addOK == BIS_FALSE || appInfo->memoryAllocations == NULL )
{
gBS->FreePool( appInfo );
return EFI_OUT_OF_RESOURCES;
}
//Make appInfo->pCssmInfo point to it's piece of the allocation;
appInfo->pCssmInfo= (APP_CSSMINFO_PTR) ( appInfo + 1);
//Point to same instance data that interface structure points to.
appInfo->efiInstanceData= bisGlobal;
}
else
{
return EFI_OUT_OF_RESOURCES;
}
//return the appinfo struct address.
parmBlock->appHandle= (BIS_APPLICATION_HANDLE)appInfo;
//Initialize the crypto and manifest service subsys.
parmBlock->returnValue = (UINT32)PSD_InitializeApp( appInfo, appInfo->pCssmInfo );
if ( parmBlock->returnValue != BIS_OK )
{
COL_Destroy( appInfo->memoryAllocations );
gBS->FreePool( appInfo );
return parmBlock->returnValue;
}
//Open our NVM (non volatile mem area).
appInfo->nvmHandle= NVM_Open( appInfo, &bisNvmAreaId, &maxSize);
if ( appInfo->nvmHandle == BIS_NULL)
{
//this not currently fatal.
return EFI_DEVICE_ERROR;
}
bisGlobal->bisInUse= BIS_TRUE;
*AppHandle= parmBlock->appHandle;
return EFI_SUCCESS;
} //End EFI_BIS_Initialize
//
// EFI_BIS_FREE()
//
EFI_STATUS
EFI_BIS_Free(
IN BIS_APPLICATION_HANDLE AppHandle, //From Initialize( ).
IN EFI_BIS_DATA *ToFree //[in] BIS_DATA being freed.
)
{
EFI_STATUS rc= EFI_SUCCESS;
BIS_APPINFO_PTR appInfo;
//Extract BIS_APPINFO_PTR
appInfo= CAST_APP_HANDLE(AppHandle);
//Check apphandle validity
if ( appInfo == BIS_NULL || (!IS_APPINFO_VALID(appInfo)))
{
rc= BIS_BAD_APPHANDLE;
}
if ( ToFree == NULL )
{
return EFI_INVALID_PARAMETER;
}
//Free memory and remove from tracking collection in 'appInfo'.
if ( rc == EFI_SUCCESS )
{
if ( !MEM_free( appInfo, ToFree ) )
{
rc= EFI_INVALID_PARAMETER;
}
}
//success.
return rc;
}
//
// EFI_BIS_Shutdown()
//
EFI_STATUS
EFI_BIS_Shutdown(
IN BIS_APPLICATION_HANDLE AppHandle // From Initialize( ).
)
{
BIS_SHUTDOWN_PARMS shutParms;
BIS_APPINFO_PTR appInfo;
COLLECTION *col;
UINTN colIx;
UINTN element;
void *memptr;
EFI_STATUS rv;
BISBC_INSTANCEDATA *bisGlobal;
COLLECTION *appInfoTrackingCollection;
//Shutdown logic is almost verbatin from BIS legacy implementation.
//Extract BIS_APPINFO_PTR
appInfo= CAST_APP_HANDLE(AppHandle);
//Check apphandle validity
if ( appInfo == BIS_NULL || (!IS_APPINFO_VALID(appInfo))){
return EFI_NO_MAPPING;
}
bisGlobal= appInfo->efiInstanceData;
appInfoTrackingCollection= bisGlobal->appInfoTrackingCollection;
EfiZeroMem( &shutParms, sizeof(shutParms) );
shutParms.sizeOfStruct= sizeof(shutParms);
shutParms.appHandle= AppHandle;
//Close the non-volative memory
rv= NVM_Close( appInfo, appInfo->nvmHandle );
if ( rv != EFI_SUCCESS)
{
bisGlobal->bisInUse= BIS_FALSE;
return rv;
}
//Close CSSM subsystem.
PSD_Shutdown( appInfo->pCssmInfo );
//Interate over the collection appInfo->memoryAllocations,
//Free any memory that this app failed to free for itself
col= appInfo->memoryAllocations;
//Processing highest to lowest index, avoids compaction in COLLECTION.
colIx= COL_GetCount( col );
while ( colIx ) //NOTE: while condition contains an assignement!
{
colIx -= 1; //adjust for zero origin index.
if ( COL_ElementAt( col, colIx, &element ) )
{
memptr= (void*)element;
gBS->FreePool( memptr ); //free the memory
COL_RemoveElementAt( col, colIx); //delete collection element.
}
colIx= COL_GetCount( col );
}
// Delete the collection object
COL_Destroy( col );
//Destroy appinfo object and remove from BIS' collection.
gBS->FreePool( appInfo );
COL_RemoveElement( appInfoTrackingCollection, (UINTN)appInfo );
bisGlobal->bisInUse= BIS_FALSE;
return EFI_SUCCESS;
}
//
// EFI_BIS_GetBootObjectAuthorizationCertificate()
//
EFI_STATUS
EFI_BIS_GetBootObjectAuthorizationCertificate(
IN BIS_APPLICATION_HANDLE AppHandle, // From Initialize( ).
OUT EFI_BIS_DATA **Certificate // Pointer to certificate.
)
{
BIS_GBOAC_PARMS gboacParms;
BIS_GBOAC_PARMS *parmBlock= &gboacParms;
BIS_APPINFO_PTR appInfo;
BIS_DATA_PTR boaCert;
EFI_STATUS status;
EFI_STATUS persistSt;
UINT32 certLength;
UINT32 flashLength;
BISBC_INSTANCEDATA *bisGlobal;
//Extract BIS_APPINFO_PTR
appInfo= CAST_APP_HANDLE(AppHandle);
//Check parms.
if ( appInfo == BIS_NULL || (!IS_APPINFO_VALID(appInfo))){
return EFI_NO_MAPPING;
}
if ( Certificate == NULL )
{
return EFI_INVALID_PARAMETER;
}
bisGlobal= appInfo->efiInstanceData;
EfiZeroMem( &gboacParms, sizeof(gboacParms) );
gboacParms.sizeOfStruct= sizeof(gboacParms);
gboacParms.appHandle= AppHandle;
//Attempt to read the certificate length field from NVM.
status= NVM_Read( appInfo->nvmHandle
, (UINT8 *)&certLength
, sizeof(certLength)
, GET_NVM_FIELD_OFFSET( byteLengthOfBOACert )
);
if ( status != EFI_SUCCESS ) {
return status;
}
else if ( certLength == 0 ){
return EFI_NOT_FOUND;
}
//Is certLength reasonable? If too big for available area
//assume that the plat cert is not configured.
persistSt= bisGlobal->Persist->GetLength(
bisGlobal->Persist, &flashLength, BIS_NULL );
if ( persistSt != EFI_SUCCESS ){
return EFI_NOT_FOUND;
}
flashLength= flashLength - sizeof(BIS_BOOLEAN); //updateCheckFlag size
flashLength= flashLength
- GET_NVM_FIELD_SIZE( bootObjectAuthorizationUpdateCount );
flashLength= flashLength - sizeof(certLength);
if ( certLength > flashLength)
{
return EFI_NOT_FOUND;
}
//Create structure to hold the certificate.
boaCert= parmBlock->certificate=
MEM_allocBisData( appInfo, certLength );
if ( boaCert == BIS_NULL) {
return EFI_OUT_OF_RESOURCES;
}
//Attempt to read the certificate from NVM.
status= NVM_Read( appInfo->nvmHandle
, (UINT8 *)boaCert->data
, certLength
, GET_NVM_FIELD_OFFSET( bootObjectAuthorizationCertificate )
);
//Delete the data block if read failed.
if (status != EFI_SUCCESS){
MEM_free( appInfo, boaCert);
parmBlock->certificate= BIS_NULL;
}
*Certificate= (EFI_BIS_DATA*)parmBlock->certificate;
return status;
}
//
// EFI_BIS_VerifyBootObject( )
//
EFI_STATUS
EFI_BIS_VerifyBootObject(
IN BIS_APPLICATION_HANDLE AppHandle, // From Initialize( ).
IN EFI_BIS_DATA *Credentials, // Verification signed manifest.
IN EFI_BIS_DATA *DataObject, // Boot object to verify.
OUT BOOLEAN *IsVerified // Result of verifcation.
)
{
BIS_VBO_PARMS vboParms;
BIS_STATUS rc;
BIS_APPINFO_PTR appInfo;
//Extract BIS_APPINFO_PTR
appInfo= CAST_APP_HANDLE(AppHandle);
//Check apphandle validity
if ( appInfo == BIS_NULL || (!IS_APPINFO_VALID(appInfo))){
return EFI_NO_MAPPING;
}
if ( Credentials == NULL || DataObject == NULL || IsVerified == NULL)
{
return EFI_INVALID_PARAMETER;
}
//Setup Parm Block
EfiZeroMem( &vboParms, sizeof(vboParms) );
vboParms.sizeOfStruct= sizeof(vboParms);
vboParms.appHandle= AppHandle;
EBDP2BD( Credentials, &vboParms.credentials);
EBDP2BD( DataObject, &vboParms.dataObject);
rc= Core_VerifyBootObject( appInfo, appInfo->pCssmInfo, &vboParms );
*IsVerified= (BOOLEAN)((vboParms.isVerified == BIS_TRUE) ? TRUE:FALSE);
return mapBisToEfi(rc);
}
//
// EFI_BIS_GetBootObjectAuthorizationCheckFlag()
//
EFI_STATUS
EFI_BIS_GetBootObjectAuthorizationCheckFlag(
IN BIS_APPLICATION_HANDLE AppHandle, // From Initialize( ).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -