📄 core_updt_boa.c
字号:
// If 'ParameterId' was retrieved ...
if ( brc == BIS_OK )
{
//Check the ParmeterId value for validity...
if ( 0 == BIS_strncmp(parmID_Value.Data
, BOAC_PARMID, sizeof(BOAC_PARMID)-1 ) )
{
UBOATRACE("UBOA150 ");
updateField= UPDATE_CERT;
}
else if ( 0 == BIS_strncmp(parmID_Value.Data
, BOACF_PARMID, sizeof(BOACF_PARMID)-1 ) )
{
UBOATRACE("UBOA160 ");
updateField= UPDATE_FLAG;
}
else {
brc= BIS_SECURITY_FAILURE;
}
//free memory occupied by base64 decode value.
MEM_free( cssmInfo->appInfo, parmID_Value.Data);
}
// If 'ParameterId' was retrieved and is valid ...
UBOATRACE("UBOA170 ");
if ( brc == BIS_OK )
{
//Get the Value of the Platform parameter that is be be updated:
// (Manifest data object name is: "ParameterValue" ).
// It is the value of the platform cert or the check flag.
UBOATRACE("UBOA180 ");
brc= GetDataObjectByName(cssmInfo
,&smInfo //SM to obtain ParmId from.
,parmValue_Name //ObjName
,&parmValue_Value //ObjValue [OUT]
,BIS_TRUE ); //do base 64 decode.
}
//If any problem with parmid of value, bail out.
if (brc != BIS_OK)
{
brc= BIS_SECURITY_FAILURE;
goto ERROR_EXIT;
}
//When updating the check flag, data length must be 1.
if (updateField == UPDATE_FLAG && parmValue_Value.Length != 1)
{
brc= BIS_SECURITY_FAILURE;
goto ERROR_EXIT;
}
//else when updating the cert do some verifcation on the cert.
//(Don't consider null certs, Length == 0).
else if (updateField == UPDATE_CERT && parmValue_Value.Length > 0)
{
UINT32 newCertChk;
newCertChk= CSSM_VL_SelfVerifyCertificate(
cssmInfo->hVL, /* VLHandle */
&parmValue_Value); /* Certificate */
if ( ISL_OK != newCertChk )
{
brc= BIS_SECURITY_FAILURE;
goto ERROR_EXIT;
}
}
//Update requested parm in NonVolatile Storage
UBOATRACE("UBOA190 ");
brc= (BIS_STATUS)UpdateBoaInNVM( appInfo, updateField, &parmValue_Value);
if (brc != BIS_OK)
{
goto ERROR_EXIT;
}
// ***Increment update counter in NVM***
//Attempt to read the update counter from NVM.
UBOATRACE("UBOA200 ");
brc= (BIS_STATUS)NVM_Read( appInfo->nvmHandle
, (UINT8 *)&updateCounter
, GET_NVM_FIELD_SIZE( bootObjectAuthorizationUpdateCount )
, GET_NVM_FIELD_OFFSET( bootObjectAuthorizationUpdateCount )
);
//Update token in NonVolatile Storage (unless an error has occured).
if (brc == BIS_OK )
{
UBOATRACE("UBOA210 ");
//Incr counter and put into CSSM_DATA form.
updateCounter += 1;
updateCounterLV.Data= (UINT8*)&updateCounter;
updateCounterLV.Length= sizeof(updateCounter);
//Update in NVM.
brc= (BIS_STATUS)UpdateBoaInNVM( appInfo
, UPDATE_COUNTER, &updateCounterLV);
}
// Get a copy of the platform update token for the caller.
// (unless an error has occured).
// MEMFREEBUG description: the memory allocated for the update token
// in the following call will be freed in the call to
// FreeSignedManifestHandle (FSMH) just below? It is believed that FSMH
// is freeing a stale pointer to memory that has been reallocated to
// the update token. Something about the legacy BIS implementation
// masks this behavior.
UBOATRACE("UBOA220 ");
if (brc == BIS_OK)
{
gboautParms.sizeOfStruct= sizeof(gboautParms);
gboautParms.appHandle= parmBlock->appHandle;
brc= BIS_GetBootObjectAuthorizationUpdateToken( &gboautParms );
parmBlock->newUpdateToken = gboautParms.updateToken;
}
ERROR_EXIT:
if (freeSmInfo){
FreeSignedManifestHandle(cssmInfo, &smInfo);
}
if ( gboacParms.certificate != BIS_NULL )
{
MEM_free( cssmInfo->appInfo, gboacParms.certificate);
}
return (parmBlock->returnValue= brc);
}
//-------------------------------------------------------------
// CheckParmsetValue
//
// Checks that the signedManfest pointed to by 'smInfo' contains
// a data object name "ParameterSet" and that it's value is
// equal to the value of the #define symbol
// BOOT_OBJECT_AUTHORIZATION_PARMSET_GUIDVALUE.
// returns:
// BIS_BOOLEAN true if OK.
//
BIS_STATUS
CheckParmsetValue(
APP_CSSMINFO_PTR cssmInfo
,BIS_SM_PTR smInfo)
{
BIS_STATUS brc;
BIS_BOOLEAN result;
CSSM_STRING parmSetName= PARMSET_ATTR_NAME;
CSSM_DATA parmSetValue; //guid from update manifest.
CSSM_GUID bootObjectAuthorizationSetGUID=
BOOT_OBJECT_AUTHORIZATION_PARMSET_GUIDVALUE;
CSSM_GUID_PTR valueFromSm;
//Get the "ParameterSet" data object from the SM.
brc= GetDataObjectByName(cssmInfo
,smInfo //SM to obtain token from.
,parmSetName //ObjName
,&parmSetValue //ObjValue [OUT]
,BIS_TRUE ); //do base 64 decode.
if (brc!=BIS_OK){
return BIS_FALSE;
}
//check that the parmSetValue is the correct
// length for a guid.
if ( parmSetValue.Length != sizeof(CSSM_GUID) )
{
result= BIS_FALSE;
}
else {
//Cast pointer to guid pointer and compare against expected guid.
valueFromSm= (CSSM_GUID_PTR)parmSetValue.Data;
result= EfiCompareGuid( (EFI_GUID *)valueFromSm, (EFI_GUID *)&bootObjectAuthorizationSetGUID);
}
//Free memory obtained by GetDataObjectByValue.
MEM_free( cssmInfo->appInfo, parmSetValue.Data );
return result;
}
//-------------------------------------------------------------
// Update Boot Object Authorization Field in NonVolatile Memory.
//
EFI_STATUS
UpdateBoaInNVM(
BIS_APPINFO_PTR appInfo
, UINT32 updateField
, CSSM_DATA_PTR fieldValue)
{
EFI_STATUS status;
BIS_BOOLEAN checkFlag;
UINT8 *pCheckFlag;
switch (updateField)
{
case UPDATE_FLAG: //Update the bootAuthCheckFlag.
pCheckFlag= (UINT8*)fieldValue->Data; //promote byte to uint32.
checkFlag= *pCheckFlag;
status= NVM_Write( appInfo->nvmHandle
, (UINT8 *)&checkFlag
, sizeof(BIS_BOOLEAN)
, GET_NVM_FIELD_OFFSET( bootObjectAuthorizationCheckFlag ) );
break;
case UPDATE_CERT: //Update the bootAuth Certificate.
status= NVM_Write( appInfo->nvmHandle
, (UINT8 *)&fieldValue->Length
, sizeof(UINT32)
, GET_NVM_FIELD_OFFSET( byteLengthOfBOACert ) );
if ( status == BIS_OK ) {
status= NVM_Write( appInfo->nvmHandle
, (UINT8 *)fieldValue->Data
, fieldValue->Length
, GET_NVM_FIELD_OFFSET( bootObjectAuthorizationCertificate ));
}
break;
case UPDATE_COUNTER: //Update the bootAuth update token.
status= NVM_Write( appInfo->nvmHandle
, (UINT8 *)fieldValue->Data
, sizeof(UINT32)
, GET_NVM_FIELD_OFFSET( bootObjectAuthorizationUpdateCount ) );
break;
default:
status= BIS_BAD_PARM;
} //switch
return status;
}
//---------------------------------------------------------
// areTokensEqual - compares a freshly calculated update
// token to the token extracted from the update
// request manifest.
//
// returns: BIS_OK if two tokens are identical.
// and BIS_SECURITY_FAILURE if not.
BIS_STATUS
areTokensEqual( BIS_DATA_PTR calculatedToken
, CSSM_DATA_PTR tokenFromUpdateManifest)
{
BIS_STATUS result= BIS_OK;
UINT32 l1, l2;
UINT8 *d1, *d2;
//Check length for equality.
l1= calculatedToken->length;
l2= tokenFromUpdateManifest->Length;
if ( l1 != l2 )
{
result= BIS_SECURITY_FAILURE;
}
//Check data for equality
else {
d1= calculatedToken->data;
d2= tokenFromUpdateManifest->Data;
//Compare 'l1' bytes of data.
for ( ; l1>0 ; --l1)
{
if (*d1 != *d2){
result= BIS_SECURITY_FAILURE;
break;
}
d1+=1;
d2+=1;
}
}
return result;
}
//eof
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -