1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zsl588-OpenCorePkg

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
PavpProvision.c 15 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
dakanji Отправлено 5 лет назад d9cc305
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
/** @file
Provision EPID key.
Copyright (c) 2019, vit9696. 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 <PiDxe.h>
#include <Protocol/FirmwareVolume.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PciLib.h>
#include <Library/HobLib.h>
#include <Library/IoLib.h>
#include <Guid/GlobalVariable.h>
#include <Library/OcDebugLogLib.h>
#include <Library/OcHeciLib.h>
#include <Library/OcMiscLib.h>
#include <Protocol/Heci.h>
#include <Protocol/Heci2.h>
#include <IndustryStandard/AppleProvisioning.h>
#include <IndustryStandard/HeciMsg.h>
#include <IndustryStandard/HeciClientMsg.h>
#define FORCE_PROVISIONING 1
#define SA_MC_BUS 0x00
#define R_SA_PAVPC (0x58)
#define MmPciAddress(Segment, Bus, Device, Function, Register) \
((UINTN) (PciRead32 (PCI_LIB_ADDRESS (0,0,0,0x60)) & 0xFC000000) + \
(UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) \
(Function << 12) + (UINTN) (Register))
#define MmPci32(Segment, Bus, Device, Function, Register) \
*((volatile UINT32 *) MmPciAddress (Segment, Bus, Device, Function, Register))
STATIC UINT8 mMeClientMap[HBM_ME_CLIENT_MAX];
STATIC UINT8 mMeClientActiveCount;
extern UINT8 gDefaultAppleEpidCertificate[];
extern UINTN gDefaultAppleEpidCertificateSize;
extern UINT8 gDefaultAppleGroupPublicKeys[];
extern UINTN gDefaultAppleGroupPublicKeysSize;
STATIC
EFI_STATUS
ReadProvisioningDataFile (
IN EFI_GUID *FvNameGuid,
OUT VOID **Buffer,
OUT UINTN *BufferSize
)
{
UINTN Index;
EFI_STATUS Status;
UINT32 AuthenticationStatus;
EFI_FIRMWARE_VOLUME_PROTOCOL *FirmwareVolumeInterface;
UINTN NumOfHandles;
EFI_HANDLE *HandleBuffer;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolumeProtocolGuid,
NULL,
&NumOfHandles,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
for (Index = 0; Index < NumOfHandles; ++Index) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiFirmwareVolumeProtocolGuid,
(VOID **) &FirmwareVolumeInterface
);
if (EFI_ERROR (Status)) {
gBS->FreePool (HandleBuffer);
return Status;
}
*Buffer = NULL;
*BufferSize = 0;
Status = FirmwareVolumeInterface->ReadSection (
FirmwareVolumeInterface,
FvNameGuid,
EFI_SECTION_RAW,
0,
Buffer,
BufferSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
gBS->FreePool (HandleBuffer);
return Status;
}
}
gBS->FreePool (HandleBuffer);
Status = EFI_NOT_FOUND;
}
//
// Implement fallback for our firmware.
//
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCPAVP: No %g in firmware, using default - %r\n", FvNameGuid, Status));
if (CompareGuid (&gAppleEpidCertificateFileGuid, FvNameGuid)) {
*Buffer = AllocateCopyPool (gDefaultAppleEpidCertificateSize, gDefaultAppleEpidCertificate);
*BufferSize = gDefaultAppleEpidCertificateSize;
} else if (CompareGuid (&gAppleEpidGroupPublicKeysFileGuid, FvNameGuid)) {
*Buffer = AllocateCopyPool (gDefaultAppleGroupPublicKeysSize, gDefaultAppleGroupPublicKeys);
*BufferSize = gDefaultAppleGroupPublicKeysSize;
} else {
*Buffer = NULL;
}
if (*Buffer != NULL) {
Status = EFI_SUCCESS;
} else {
Status = EFI_NOT_FOUND;
}
}
return Status;
}
STATIC
EFI_STATUS
ReadProvisioningData (
OUT EPID_CERTIFICATE **EpidCertificate,
OUT EPID_GROUP_PUBLIC_KEY **EpidGroupPublicKeys,
OUT UINT32 *EpidGroupPublicKeysCount
)
{
EFI_STATUS Status;
UINTN EpidCertificateSize;
UINTN EpidGroupPublicKeysSize;
Status = ReadProvisioningDataFile (
&gAppleEpidCertificateFileGuid,
(VOID **) EpidCertificate,
&EpidCertificateSize
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = ReadProvisioningDataFile (
&gAppleEpidGroupPublicKeysFileGuid,
(VOID **) EpidGroupPublicKeys,
&EpidGroupPublicKeysSize
);
if (EFI_ERROR (Status)) {
gBS->FreePool (*EpidGroupPublicKeys);
return Status;
}
if (EpidCertificateSize == EPID_CERTIFICATE_SIZE
&& EpidGroupPublicKeysSize % EPID_GROUP_PUBLIC_KEY_SIZE == 0) {
*EpidGroupPublicKeysCount = (UINT32) (EpidGroupPublicKeysSize / EPID_GROUP_PUBLIC_KEY_SIZE);
return EFI_SUCCESS;
}
gBS->FreePool (*EpidCertificate);
gBS->FreePool (*EpidGroupPublicKeys);
return EFI_VOLUME_CORRUPTED;
}
STATIC
VOID
SetProvisioningVariable (
IN CHAR16 *Variable,
IN UINT32 Value
)
{
#ifdef FORCE_PROVISIONING
(VOID) Variable;
(VOID) Value;
#else
gRT->SetVariable (
Variable,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (Value),
&Value
);
#endif
}
STATIC
EFI_STATUS
GetGroupPublicKey (
IN EPID_GROUP_PUBLIC_KEY *PublicKeys,
IN UINTN PublicKeyCount,
IN UINT32 Key,
OUT EPID_GROUP_PUBLIC_KEY **ChosenPublicKey
)
{
EFI_STATUS Status;
UINT32 Index;
Status = EFI_NOT_FOUND;
for (Index = 0; Index < PublicKeyCount; ++Index) {
if (SwapBytes32 (PublicKeys[Index].GroupId) == Key) {
*ChosenPublicKey = &PublicKeys[Index];
return EFI_SUCCESS;
}
}
return Status;
}
STATIC
BOOLEAN
IsBuiltinGpuAvailable (
VOID
)
{
EFI_STATUS Status;
UINT32 Value;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Interface;
Status = gBS->LocateProtocol (
&gEfiPciRootBridgeIoProtocolGuid,
NULL,
(VOID **) &Interface
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCPAVP: Failed to find PCI root protocol - %r\n", Status));
return FALSE;
}
//
// IGPU_DEVICE_ID = 0x2
// PCI_VENDOR_ID_OFFSET = 0x0
// (IGPU_DEVICE_ID << 16U | PCI_VENDOR_ID_OFFSET)
// See EFI_PCI_ADDRESS
//
Status = Interface->Pci.Read (
Interface,
EfiPciWidthUint32,
0x20000,
1,
&Value
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCPAVP: Failed to read from IGPU device - %r\n", Status));
return FALSE;
}
DEBUG ((DEBUG_INFO, "OCPAVP: IGPU is %X\n", Value));
return Value != 0xFFFFFFFFU;
}
STATIC
EFI_STATUS
NeedsEpidProvisioning (
VOID
)
{
EFI_STATUS Status;
UINT32 Data;
UINTN DataSize;
if (IsBuiltinGpuAvailable()) {
DataSize = sizeof (Data);
Status = gRT->GetVariable (
APPLE_EPID_PROVISIONED_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
NULL,
&DataSize,
&Data
);
#ifdef FORCE_PROVISIONING
Data = 0;
#endif
if (EFI_ERROR (Status) || Data != 1) {
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
STATIC
EFI_STATUS
NeedsFpfProvisioning (
VOID
)
{
EFI_STATUS Status;
UINT32 Data;
UINTN DataSize;
APPLE_FPF_CONFIGURATION_HOB *Hob;
#if 0
Hob = GetFirstGuidHob (&gAppleFpfConfigurationHobGuid);
#else
Hob = NULL;
#endif
DEBUG ((DEBUG_INFO, "OCPAVP: HOB for FPF is %p\n", Hob));
if (Hob == NULL || Hob->ShouldProvision) {
DataSize = sizeof (Data);
Status = gRT->GetVariable (
APPLE_FPF_PROVISIONED_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
NULL,
&DataSize,
&Data
);
if (EFI_ERROR (Status) || Data != 1) {
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
OcPerformEpidProvisioning (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
HECI_CLIENT_PROPERTIES Properties;
EPID_GROUP_PUBLIC_KEY *EpidGroupPublicKeys;
EPID_CERTIFICATE *EpidCertificate;
UINT32 EpidGroupPublicKeysCount;
UINT32 EpidStatus;
UINT32 EpidGroupId;
EPID_GROUP_PUBLIC_KEY *EpidCurrentGroupPublicKey;
BOOLEAN SetVar;
Status = NeedsEpidProvisioning ();
DEBUG ((DEBUG_INFO, "OCPAVP: Needs provisioning EPID - %r\n", Status));
if (EFI_ERROR (Status)) {
return EFI_ALREADY_STARTED;
}
Status = HeciLocateProtocol ();
DEBUG ((DEBUG_INFO, "OCPAVP: HECI protocol lookup - %r\n", Status));
if (EFI_ERROR (Status)) {
return Status;
}
Status = ReadProvisioningData (
&EpidCertificate,
&EpidGroupPublicKeys,
&EpidGroupPublicKeysCount
);
DEBUG ((DEBUG_INFO, "OCPAVP: Provisioning data - %r\n", Status));
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get Management Engine proccesses namespace.
// Each App like PAVP or FPF have unique identifier represented as GUID.
//
Status = HeciGetClientMap (mMeClientMap, &mMeClientActiveCount);
DEBUG ((DEBUG_INFO, "OCPAVP: Got %d clients - %r\n", mMeClientActiveCount, Status));
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_NOT_FOUND;
for (Index = 0; Index < mMeClientActiveCount; ++Index) {
Status = HeciGetClientProperties (
mMeClientMap[Index],
&Properties
);
DEBUG ((
DEBUG_INFO,
"OCPAVP: Client %u has %g protocol - %r\n",
(UINT32) Index,
Properties.ProtocolName,
Status
));
if (EFI_ERROR (Status)) {
break;
}
if (CompareGuid (&Properties.ProtocolName, &gMePavpProtocolGuid)) {
break;
}
}
if (!EFI_ERROR (Status) && Index != mMeClientActiveCount) {
DEBUG ((DEBUG_INFO, "OCPAVP: Found application at %u\n", (UINT32) Index));
Status = HeciConnectToClient (mMeClientMap[Index]);
if (!EFI_ERROR (Status)) {
EpidStatus = EpidGroupId = 0;
Status = HeciPavpRequestProvisioning (&EpidStatus, &EpidGroupId);
DEBUG ((DEBUG_INFO, "OCPAVP: Got EPID status %X and group id %x - %r\n", EpidStatus, EpidGroupId, Status));
}
if (!EFI_ERROR (Status)) {
if (EpidStatus == EPID_STATUS_PROVISIONED) {
SetProvisioningVariable (APPLE_EPID_PROVISIONED_VARIABLE_NAME, 1);
} else if (EpidStatus == EPID_STATUS_CAN_PROVISION) {
Status = GetGroupPublicKey (
EpidGroupPublicKeys,
EpidGroupPublicKeysCount,
EpidGroupId,
&EpidCurrentGroupPublicKey
);
DEBUG ((DEBUG_INFO, "OCPAVP: Got EPID group public key - %r\n", Status));
if (!EFI_ERROR (Status)) {
Status = HeciPavpPerformProvisioning (EpidCertificate, EpidCurrentGroupPublicKey, &SetVar);
DEBUG ((DEBUG_INFO, "OCPAVP: Sent EPID certificate - %r / %d\n", Status, SetVar));
if (!EFI_ERROR (Status) || SetVar) {
SetProvisioningVariable (APPLE_EPID_PROVISIONED_VARIABLE_NAME, 1);
}
}
}
}
HeciDisconnectFromClients ();
} else {
DEBUG ((DEBUG_INFO, "OCPAVP: No EPID application found\n"));
if (Index == mMeClientActiveCount) {
//
// Do not retry provisioning on incompatible firmware.
// TODO: Do we really need this?
//
SetProvisioningVariable (APPLE_EPID_PROVISIONED_VARIABLE_NAME, 1);
Status = EFI_NOT_FOUND;
}
}
gBS->FreePool (EpidCertificate);
gBS->FreePool (EpidGroupPublicKeys);
return Status;
}
EFI_STATUS
OcPerformFpfProvisioning (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
HECI_CLIENT_PROPERTIES Properties;
UINT32 FpfStatus;
Status = NeedsFpfProvisioning ();
DEBUG ((DEBUG_INFO, "OCPAVP: Needs provisioning FPF - %r\n", Status));
if (EFI_ERROR (Status)) {
return EFI_ALREADY_STARTED;
}
Status = HeciLocateProtocol ();
DEBUG ((DEBUG_INFO, "OCPAVP: HECI protocol lookup - %r\n", Status));
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get Management Engine proccesses namespace.
// Each App like PAVP or FPF have unique identifier represented as GUID.
//
Status = HeciGetClientMap (mMeClientMap, &mMeClientActiveCount);
DEBUG ((DEBUG_INFO, "OCPAVP: Got %d clients - %r\n", mMeClientActiveCount, Status));
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_NOT_FOUND;
for (Index = 0; Index < mMeClientActiveCount; ++Index) {
Status = HeciGetClientProperties (
mMeClientMap[Index],
&Properties
);
DEBUG ((
DEBUG_INFO,
"OCPAVP: Client %u has %g protocol - %r\n",
(UINT32) Index,
Properties.ProtocolName,
Status
));
if (EFI_ERROR (Status)) {
break;
}
if (CompareGuid (&Properties.ProtocolName, &gMeFpfProtocolGuid)) {
break;
}
}
if (!EFI_ERROR (Status) && Index != mMeClientActiveCount) {
DEBUG ((DEBUG_INFO, "OCPAVP: Found application at %u\n", (UINT32) Index));
Status = HeciConnectToClient (mMeClientMap[Index]);
//
// I *think* FPF provisioning locks fuses from further update.
// For this reason we do not want it.
//
if (!EFI_ERROR (Status)) {
Status = HeciFpfGetStatus (&FpfStatus);
DEBUG ((DEBUG_INFO, "OCPAVP: Got FPF status %u - %r\n", FpfStatus, Status));
if (!EFI_ERROR (Status)) {
if (FpfStatus == 250) {
Status = HeciFpfProvision (&FpfStatus);
DEBUG ((DEBUG_INFO, "OCPAVP: Got FPF provisioning %u - %r\n", FpfStatus, Status));
if (!EFI_ERROR (Status) && FpfStatus == 0) {
SetProvisioningVariable (APPLE_FPF_PROVISIONED_VARIABLE_NAME, 1);
} else {
Status = EFI_DEVICE_ERROR;
}
} else {
Status = EFI_DEVICE_ERROR;
}
}
HeciDisconnectFromClients ();
}
} else {
DEBUG ((DEBUG_INFO, "OCPAVP: No FPF application found\n"));
if (Index == mMeClientActiveCount) {
//
// Do not retry provisioning on incompatible firmware.
// TODO: Do we really need this?
//
SetProvisioningVariable (APPLE_FPF_PROVISIONED_VARIABLE_NAME, 1);
Status = EFI_NOT_FOUND;
}
}
return Status;
}
STATIC
VOID
OcPerformProvisioning (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "OCPAVP: Checking PAVPC register...\n"));
UINT32 PAVPC = MmPci32 (0, SA_MC_BUS, 0, 0, R_SA_PAVPC);
DEBUG ((DEBUG_INFO, "OCPAVP: Current PAVPC is %X\n", PAVPC));
if ((PAVPC & BIT2) == 0) {
MmPci32 (0, SA_MC_BUS, 0, 0, R_SA_PAVPC) = (PAVPC & (~BIT2)) | BIT4;
PAVPC = MmPci32 (0, SA_MC_BUS, 0, 0, R_SA_PAVPC);
DEBUG ((DEBUG_INFO, "OCPAVP: New PAVPC is %X\n", PAVPC));
}
DEBUG ((DEBUG_INFO, "OCPAVP: Starting EPID provisioning\n"));
Status = OcPerformEpidProvisioning ();
DEBUG ((DEBUG_INFO, "OCPAVP: Done EPID provisioning - %r\n", Status));
#if 0
DEBUG ((DEBUG_INFO, "OCPAVP: Starting FPF provisioning\n"));
Status = OcPerformFpfProvisioning ();
DEBUG ((DEBUG_INFO, "OCPAVP: Done FPF provisioning - %r\n", Status));
#endif
}
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
OcPerformProvisioning ();
gBS->Stall (SECONDS_TO_MICROSECONDS (3));
return EFI_SUCCESS;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/zsl588-OpenCorePkg.git
git@gitlife.ru:oschina-mirror/zsl588-OpenCorePkg.git
oschina-mirror
zsl588-OpenCorePkg
zsl588-OpenCorePkg
0.7.5