24#include <Library/DebugLib.h>
25#include <Library/BaseLib.h>
26#include <Library/BaseMemoryLib.h>
27#include <Library/BaseOverflowLib.h>
28#include <Library/PeCoffLib2.h>
29#include <Library/UefiRuntimeServicesTableLib.h>
30#include <Library/UefiBootServicesTableLib.h>
31#include <Library/MemoryAllocationLib.h>
32#include <Library/PrintLib.h>
33#include <Library/UefiLib.h>
44 IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
46 OUT CONST EFI_IMAGE_DATA_DIRECTORY **DirectoryEntry
49 CONST EFI_IMAGE_NT_HEADERS32 *Pe32Hdr;
50 CONST EFI_IMAGE_NT_HEADERS64 *Pe32PlusHdr;
55 ASSERT (DirectoryEntry != NULL);
57 switch (Context->ImageType) {
58 case PeCoffLoaderTypePe32:
59 Pe32Hdr = (CONST EFI_IMAGE_NT_HEADERS32 *)(CONST VOID *)(
60 (CONST CHAR8 *)Context->FileBuffer + Context->ExeHdrOffset
63 if (Pe32Hdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
64 return RETURN_UNSUPPORTED;
67 *DirectoryEntry = &Pe32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
70 case PeCoffLoaderTypePe32Plus:
71 Pe32PlusHdr = (CONST EFI_IMAGE_NT_HEADERS64 *)(CONST VOID *)(
72 (CONST CHAR8 *)Context->FileBuffer + Context->ExeHdrOffset
75 if (Pe32PlusHdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
76 return RETURN_UNSUPPORTED;
79 *DirectoryEntry = &Pe32PlusHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
86 return RETURN_INVALID_PARAMETER;
92 if ((*DirectoryEntry)->VirtualAddress < Context->SizeOfHeaders) {
93 return RETURN_INVALID_PARAMETER;
96 Result = BaseOverflowAddU32 (
97 (*DirectoryEntry)->VirtualAddress,
98 (*DirectoryEntry)->Size,
101 if (Result || (EntryTop > FileSize)) {
102 return RETURN_INVALID_PARAMETER;
105 return RETURN_SUCCESS;
111 IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
114 OUT UINT32 *SecDirOffset,
115 OUT UINT32 *SignedFileSize
119 CONST EFI_IMAGE_DATA_DIRECTORY *SecDir;
127 if (EFI_ERROR (Status)) {
128 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff has no SecDir - %r\n", Status));
129 return EFI_NOT_FOUND;
132 *SecDirOffset = (UINT32)((UINT8 *)SecDir - (UINT8 *)Context->FileBuffer);
135 DEBUG ((DEBUG_INFO,
"OCPE: Certificate info size mismatch\n"));
136 return EFI_UNSUPPORTED;
140 DEBUG ((DEBUG_INFO,
"OCPE: Certificate info is misaligned %X\n", SecDir->VirtualAddress));
141 return EFI_UNSUPPORTED;
148 (UINT8 *)Context->FileBuffer + SecDir->VirtualAddress
150 if ( BaseOverflowAddU32 ((*CertInfo)->CertOffset, (*CertInfo)->CertSize, &EndOffset)
151 || (EndOffset > FileSize))
153 DEBUG ((DEBUG_INFO,
"OCPE: Certificate entry is beyond file area\n"));
154 return EFI_INVALID_PARAMETER;
160 *SignedFileSize = SecDir->VirtualAddress;
168 IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
181 DEBUG ((DEBUG_INFO,
"OCPE: Certificate has invalid size %u\n", CertInfo->CertSize));
182 return EFI_UNSUPPORTED;
186 DEBUG ((DEBUG_INFO,
"OCPE: Certificate is misaligned %X\n", CertInfo->CertOffset));
187 return EFI_UNSUPPORTED;
194 (UINT8 *)Context->FileBuffer + CertInfo->CertOffset
200 if (CertInfo->CertSize != Cert->
CertSize) {
201 DEBUG ((DEBUG_INFO,
"OCPE: Certificate size mismatch %u vs %u\n", CertInfo->CertSize, Cert->
CertSize));
202 return EFI_UNSUPPORTED;
209 DEBUG ((DEBUG_INFO,
"OCPE: Unknown certificate type %u\n", Cert->
CertType));
210 return EFI_UNSUPPORTED;
217 DEBUG ((DEBUG_INFO,
"OCPE: Unknown certificate signature %g\n", Cert->
AppleSignatureGuid));
218 return EFI_UNSUPPORTED;
225 DEBUG ((DEBUG_INFO,
"OCPE: Unknown certificate hash %g\n", Cert->
CertData.HashType));
226 return EFI_UNSUPPORTED;
241 for (Index = 0; Index <
NUM_OF_PK; ++Index) {
249 DEBUG ((DEBUG_INFO,
"OCPE: Unknown publickey or malformed certificate\n"));
250 return EFI_UNSUPPORTED;
256 for (Index = 0; Index <
sizeof (Cert->
CertData.PublicKey); Index++) {
257 SignatureContext->Signature[
sizeof (Cert->
CertData.PublicKey) - 1 - Index]
267 IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
268 IN UINT32 SecDirOffset,
269 IN UINT32 SignedFileSize,
278 if ( (Context->ImageType != PeCoffLoaderTypePe32)
279 && (Context->ImageType != PeCoffLoaderTypePe32Plus))
281 DEBUG ((DEBUG_INFO,
"OCPE: Unsupported image type %d for Apple Image\n", Context->ImageType));
282 return EFI_UNSUPPORTED;
290 if (Context->ExeHdrOffset < sizeof (EFI_IMAGE_DOS_HEADER)) {
291 DEBUG ((DEBUG_INFO,
"OCPE: DOS header is required for signed Apple Image\n"));
292 return EFI_UNSUPPORTED;
299 (UINT8 *)Context->FileBuffer + sizeof (EFI_IMAGE_DOS_HEADER),
300 Context->ExeHdrOffset - sizeof (EFI_IMAGE_DOS_HEADER)
315 (UINT8 *)Context->FileBuffer + SecDirOffset,
316 sizeof (EFI_IMAGE_DATA_DIRECTORY)
323 (UINT8 *)Context->FileBuffer + SignedFileSize,
324 FileSize - SignedFileSize
333 IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
334 IN UINT32 SecDirOffset,
335 IN UINT32 SignedFileSize,
351 HashBase = (UINT8 *)Context->FileBuffer;
352 HashSize =
sizeof (EFI_IMAGE_DOS_HEADER);
358 HashBase += Context->ExeHdrOffset;
366 HashSize = SecDirOffset - (UINT32)(HashBase - (UINT8 *)Context->FileBuffer);
372 HashBase += HashSize +
sizeof (EFI_IMAGE_DATA_DIRECTORY);
373 HashSize = SignedFileSize - (UINT32)(HashBase - (UINT8 *)Context->FileBuffer);
384 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
385 IN OUT UINT32 *ImageSize
388 EFI_STATUS ImageStatus;
394 UINT32 SignedFileSize;
403 if (EFI_ERROR (ImageStatus)) {
404 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff no cert info - %r\n", ImageStatus));
405 return EFI_UNSUPPORTED;
413 if (EFI_ERROR (ImageStatus)) {
414 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff no valid signature - %r\n", ImageStatus));
415 return EFI_UNSUPPORTED;
424 if (EFI_ERROR (ImageStatus)) {
425 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff cannot be sanitised - %r\n", ImageStatus));
426 return EFI_UNSUPPORTED;
429 *ImageSize = SignedFileSize;
451 return EFI_SECURITY_VIOLATION;
459 IN OUT VOID *PeImage,
460 IN OUT UINT32 *ImageSize
463 EFI_STATUS ImageStatus;
464 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
466 ImageStatus = PeCoffInitializeContext (
470 UefiImageOriginUserImage
472 if (EFI_ERROR (ImageStatus)) {
473 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff verify init failure - %r\n", ImageStatus));
474 return EFI_UNSUPPORTED;
485 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
486 IN UINT32 DriverSize,
494 EFI_IMAGE_NT_HEADERS64 *OptionalHeader;
495 EFI_IMAGE_SECTION_HEADER *SectionHeader;
499 if ( (ImageContext->Machine != IMAGE_FILE_MACHINE_X64)
500 || (ImageContext->ImageType != PeCoffLoaderTypePe32Plus)
501 || (ImageContext->Subsystem != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER))
503 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff apfs unsupported image\n"));
504 return EFI_UNSUPPORTED;
510 OptionalHeader = (EFI_IMAGE_NT_HEADERS64 *)(
511 (CONST UINT8 *)ImageContext->FileBuffer
512 + ImageContext->ExeHdrOffset
514 ImageVersion = (UINT32)OptionalHeader->MajorImageVersion << 16
515 | (UINT32)OptionalHeader->MinorImageVersion;
521 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(
522 (CONST UINT8 *)ImageContext->FileBuffer
523 + ImageContext->SectionsOffset
526 if (AsciiStrnCmp ((CHAR8 *)SectionHeader->Name,
".text", sizeof (SectionHeader->Name)) != 0) {
527 return EFI_UNSUPPORTED;
531 return EFI_BUFFER_TOO_SMALL;
538 (CONST UINT8 *)ImageContext->FileBuffer
539 + SectionHeader->PointerToRawData
545 return EFI_INVALID_PARAMETER;
548 *DriverVersionPtr = DriverVersion;
554 IN VOID *DriverBuffer,
555 IN UINT32 DriverSize,
559 EFI_STATUS ImageStatus;
560 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
562 ImageStatus = PeCoffInitializeContext (
566 UefiImageOriginUserImage
568 if (EFI_ERROR (ImageStatus)) {
569 DEBUG ((DEBUG_INFO,
"OCPE: PeCoff apfs init failure - %r\n", ImageStatus));
570 return EFI_UNSUPPORTED;
578 IN VOID *DriverBuffer,
582 EFI_STATUS ImageStatus;
583 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
591 if (EFI_ERROR (ImageStatus)) {
592 DEBUG ((DEBUG_WARN,
"OCPE: PeCoff legacy patch failure - %r\n", ImageStatus));
593 return EFI_UNSUPPORTED;
#define APFS_DRIVER_VERSION_MAGIC
EFI_GUID gAppleEfiCertificateGuid
#define APPLE_EFI_CERTIFICATE_TYPE
CONST APPLE_PK_ENTRY PkDataBase[NUM_OF_PK]
VOID Sha256Init(SHA256_CONTEXT *Context)
BOOLEAN RsaVerifySigHashFromKeyDynalloc(IN CONST OC_RSA_PUBLIC_KEY *Key, IN CONST UINT8 *Signature, IN UINTN SignatureSize, IN CONST UINT8 *Hash, IN UINTN HashSize, IN OC_SIG_HASH_TYPE Algorithm)
#define SHA256_DIGEST_SIZE
VOID Sha256Final(SHA256_CONTEXT *Context, UINT8 *HashDigest)
VOID Sha256(UINT8 *Hash, CONST UINT8 *Data, UINTN Len)
VOID Sha256Update(SHA256_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
#define APPLE_CHECKSUM_OFFSET
#define APPLE_CHECKSUM_SIZE
STATIC EFI_STATUS InternalPeCoffGetApfsDriverVersionFromContext(IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN UINT32 DriverSize, OUT APFS_DRIVER_VERSION **DriverVersionPtr)
EFI_STATUS PeCoffVerifyAppleSignature(IN OUT VOID *PeImage, IN OUT UINT32 *ImageSize)
EFI_STATUS PeCoffGetApfsDriverVersion(IN VOID *DriverBuffer, IN UINT32 DriverSize, OUT APFS_DRIVER_VERSION **DriverVersionPtr)
STATIC VOID PeCoffHashAppleImage(IN PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN UINT32 SecDirOffset, IN UINT32 SignedFileSize, OUT UINT8 *Hash)
STATIC EFI_STATUS InternalPeCoffVerifyAppleSignatureFromContext(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN OUT UINT32 *ImageSize)
STATIC EFI_STATUS PeCoffGetAppleSignature(IN PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN APPLE_EFI_CERTIFICATE_INFO *CertInfo, OUT APPLE_SIGNATURE_CONTEXT *SignatureContext)
STATIC RETURN_STATUS PeCoffGetSecurityDirectoryEntry(IN PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN UINT32 FileSize, OUT CONST EFI_IMAGE_DATA_DIRECTORY **DirectoryEntry)
STATIC EFI_STATUS PeCoffGetAppleCertificateInfo(IN PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN UINT32 FileSize, OUT APPLE_EFI_CERTIFICATE_INFO **CertInfo, OUT UINT32 *SecDirOffset, OUT UINT32 *SignedFileSize)
EFI_STATUS OcPatchLegacyEfi(IN VOID *DriverBuffer, IN UINT32 DriverSize)
STATIC EFI_STATUS PeCoffSanitiseAppleImage(IN PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN UINT32 SecDirOffset, IN UINT32 SignedFileSize, IN UINT32 FileSize)
RETURN_STATUS OcPeCoffFixupInitializeContext(OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, IN BOOLEAN InMemoryFixup)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_GUID gEfiCertTypeRsa2048Sha256Guid
EFI_CERT_BLOCK_RSA_2048_SHA256 CertData
EFI_GUID AppleSignatureGuid
OC_RSA_PUBLIC_KEY * PublicKey