| Address | Name | Description | |
|---|---|---|---|
| GetImageSecurityDatabase | |||
| AsciiStrLen | |||
| ZeroMem | |||
| HobLibInit | |||
| CompareGuid | |||
| ReadUnaligned64 | |||
| WriteUnaligned64 | |||
| GetTimeStampSize | |||
| SetVariableWithTimestamp | |||
| FindCertificateInSignatureList | |||
| CpuId | |||
| GetDebugLevelFromCmos | |||
| DebugPrint | |||
| DebugAssert | |||
| FreePool | |||
| IsMatchingHobGuid | |||
| LocateHandleBufferByProtocol | |||
| GetFvbProtocol | |||
| GetFvbAndReadData | |||
| FreeFvbBuffer | |||
| FindCertificateBySubject | |||
| ParseDbSignatureData | |||
| AppendSignatureEntry | |||
| ReadSignatureDatabase | |||
| UpdateSignatureDatabase | |||
| ReadVariableFromFvb | |||
| FreeFvbReadBuffer | |||
| DeviceGuardEntryPoint | |||
| ReadSignatureDatabaseImpl | |||
| FindCertificateBySubjectImpl | |||
| AppendSignatureEntryImpl | |||
| UpdateSignatureDatabaseImpl | |||
| Global | protocol GUID | ||
| EFI_GUID | gAmiDeviceGuardApiProtocolGuid = AMI_DEVICE_GUARD_API_PROTOCOL_GUID; | ||
| Globals | (from .data segment, addresses relative to image base) | ||
| 0x1F10 | - gEfiFirmwareVolumeBlockProtocolGuid or similar protocol GUID | ||
| Used | to locate the debug mask protocol. | ||
| STATIC | EFI_GUID mDebugProtocolGuid; | ||
| 0x1F20 | - EFI_GLOBAL_VARIABLE GUID | ||
| Used | for access to "db" UEFI variable. | ||
| STATIC | EFI_GUID mGlobalVariableGuid; | ||
| 0x1F30 | - First component GUID for timestamp magic | ||
| 0x1F38 | - Second component GUID for timestamp magic | ||
| Used | by sub_14A0 when building the timestamp header. | ||
| STATIC | EFI_GUID mTimeStampGuid1; | ||
| 0x1F40 | - gEfiImageSecurityDatabaseGuid | ||
| Protocol | used for certificate parsing services. | ||
| STATIC | EFI_GUID mImageSecurityDatabaseGuid; | ||
| 0x1F50 | - Protocol GUID for locating FVB (Firmware Volume Block) | ||
| instances | via BootServices->LocateProtocol. | ||
| STATIC | EFI_GUID mFirmwareVolumeBlockProtocolGuid; | ||
| 0x1F60 | - EFI_CERT_SHA256_GUID value (16-byte buffer). | ||
| Compared | against signature list type to identify SHA-256 | ||
| certificate | entries. | ||
| STATIC | UINT8 mCertSha256Guid[16]; | ||
| 0x1F70 | - GUID for the Variable Write service inside the | ||
| EFI_IMAGE_SECURITY_DATABASE | protocol. | ||
| STATIC | EFI_GUID mVariableWriteGuid; | ||
| 0x1F80 | - First GUID for HOB list owner GUID comparison | ||
| 0x1F88 | - Second GUID for HOB list owner GUID comparison | ||
| Used | by sub_14E4 to match against HOB owner GUIDs. | ||
| STATIC | EFI_GUID mHobOwnerGuid1; | ||
| 0x1F90 | - The Device Guard API Protocol GUID structure (installed). | ||
| 0x1FA0 | - Pointer to "Microsoft Corporation UEFI CA 2011" string. | ||
| The | well-known subject name for the Microsoft UEFI CA 2011 | ||
| certificate | trusted by Windows Secure Boot. | ||
| STATIC | CONST CHAR8 *mMsftUefiCa2011Subject = "Microsoft Corporation UEFI CA 2011"; | ||
| 0x1FD0 | - Protocol instance flag (dword, initialised to 1). | ||
| Indicates | that the protocol has been installed. | ||
| STATIC | UINT32 mProtocolInstalled = 0; | ||
| 0x20A0 | - Debug mask protocol pointer (cached) | ||
| 0x20A8 | - HOB list pointer (cached) | ||
| STATIC | VOID *mDebugMaskProtocol; | ||
| Global | UEFI table pointers assigned in entry point | ||
| EFI_HANDLE | gImageHandle = NULL; | ||
| Forward | declarations for internal helper functions | ||
| Functions | that are library-level wrappers | ||
| Function | Implementations | ||
| Read | CMOS index 0x4B from bank 0x70. | ||
| Preserve | the NMI disable bit (bit 7). | ||
| Index | = IoRead8 (0x70); | ||
| If | DebugLevel > 3 and DebugLevel == 0, read from MEMORY[0xFDAF0490]. | ||
| if | (DebugLevel > 3) { | ||
| Map | debug level to EFI debug mask. | ||
| Level | 1 -> INFO (0x00000004) | ||
| Level | 2 -> WARN (0x00000008) | ||
| if | (DebugLevel == 1) { | ||
| Level | 0 or > 2 -> disabled. | ||
| return | 0; | ||
| Debug | mask protocol structure | ||
| Used | for debug print and assertion support. | ||
| typedef | struct { | ||
| Locate | the debug mask protocol. The GUID is stored at | ||
| address | 0x1F10 in the data section. | ||
| Status | = gBootServices->LocateProtocol ( | ||
| if | (Length >= 8) { | ||
| Handle | misaligned head | ||
| Index | = ((UINTN)DestBytes & 7); | ||
| Compare | aligned 8-byte chunks | ||
| while | ((UINTN)DestBytes <= (UINTN)(Destination + Length - 8) && | ||
| Compare | remaining bytes one at a time | ||
| while | ((UINTN)DestBytes < (UINTN)(Destination + Length)) { | ||
| EDK2 | unaligned read: copy byte-by-byte from the buffer. | ||
| CopyMem | (Value, Buffer, sizeof (UINT64)); | ||
| Read | GUIDs as two 64-bit values for fast comparison. | ||
| UINT64 | Guid1Part1; | ||
| HOB | List Support | ||
| The | HOB list pointer is stored in SystemTable at offset +104 | ||
| if | (gSystemTable->HobList == NULL) { | ||
| Iterate | through HOBs. Each HOB entry is 24 bytes: | ||
| Offset | 0: EFI_GUID (16 bytes) - Owner GUID | ||
| Offset | 16: (8 bytes) - HOB data pointer | ||
| while | (HobCount < (UINTN)gSystemTable->HobList) { | ||
| If | we reach here, no matching HOB was found. | ||
| Log | an assertion failure. | ||
| DebugPrint | ( | ||
| Timestamp | and Variable Support | ||
| Structure | consists of: | ||
| EFI_TIME | (16 bytes) + 0x10 pad/magic + 8 bytes GUID + 8 bytes GUID | ||
| return | sizeof (EFI_TIME) + 24; | ||
| Magic | values for timestamp structure initialisation | ||
| UINT32 | MagicValue = 0x07060402; // 117704678 decimal | ||
| 927510 | decimal | ||
| Initialise | the MagicValue trackers for debug print | ||
| ZeroMem | (TimeStamp, sizeof (EFI_TIME) + 24); | ||
| Try | to get the current time from the runtime services. | ||
| If | time services are not available, use the magic defaults above. | ||
| if | (gRuntimeServices != NULL) { | ||
| Debug | print the time information | ||
| Day | (MagicValue >> 16) & 0xFF, // Hour | ||
| Minute | MagicValue2 // Second | ||
| Copy | time data into timestamp buffer | ||
| CopyMem | (TimeStamp, &Now, sizeof (EFI_TIME)); | ||
| Fill | in the remaining fields of the timestamp structure: | ||
| Offset | 16: MonotonicCount | ||
| Offset | 20: FormatMagic | ||
| MonotonicCount | (or structure version) | ||
| 250675712 | - format magic | ||
| Write | the two GUID components for timestamp verification | ||
| WriteUnaligned64 | ((UINT64 )TimeStamp + 3, (UINT64 *)&mTimeStampGuid1); | ||
| Timestamp | **attributes: EFI_VARIABLE_NON_VOLATILE | ** | |
| EFI_VARIABLE_BOOTSERVICE_ACCESS | ** | ** | |
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | **// (0x21 = NV | BS | AT)** |
| UINT32 | TimeAttributes; | ||
| Attempt | to query the current variable size. | ||
| If | the variable does not exist, gRT->GetVariable returns | ||
| EFI_BUFFER_TOO_SMALL | with the required size in OldDataSize. | ||
| OldDataSize | = 0; | ||
| The | variable exists. Re-write with timestamp attributes. | ||
| BuildTimestamp | (&TimeStamp); | ||
| Attributes | **= NV | BS | AT (0x21) + time-based auth.** |
| TimeAttributes | **= Attributes | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;** | |
| Variable | does not exist yet. Use the raw attributes. | ||
| TimeAttributes | = Attributes; | ||
| Now | write the variable with the requested data. | ||
| Attributes | **= NV | BS | (AT if existing) -> 0x21 or 0x07.** |
| AttemptAttributes | **= TimeAttributes | 0x21;** | |
| EFI_UNSUPPORTED | (0x800000000000000E) means we succeeded | ||
| if | (Status == EFI_UNSUPPORTED) { | ||
| If | the write succeeded, query the old variable size for debug | ||
| logging | so the caller can see the size change. | ||
| if | (!EFI_ERROR (Status)) { | ||
| Certificate | Lookup | ||
| Already | cached, return existing pointer. | ||
| Get | the list of all FVB protocol instances | ||
| Status | = LocateHandleBufferByProtocol ( | ||
| Iterate | through handles to find one where Read can succeed | ||
| for | (Index = 0; Index < HandleCount; Index++) { | ||
| Try | to read from the FVB volume | ||
| Allocate | a buffer and read from FVB | ||
| Buffer | = AllocatePool (BufferSize); | ||
| No | suitable FVB handle found | ||
| Status | = EFI_NOT_FOUND; | ||
| Query | the "db" variable size first | ||
| Allocate | a buffer and read the variable data | ||
| Data | = AllocatePool (DataSize); | ||
| Search | for the certificate in the signature list | ||
| if | (DataSize > 0) { | ||
| The | "db" variable does not exist at all | ||
| return | EFI_NOT_FOUND; | ||
| Get | the Image Security Database protocol for certificate parsing | ||
| SecurityDatabase | = NULL; | ||
| Calculate | the subject name length | ||
| SubjectNameLen | = AsciiStrLen (SubjectName); | ||
| Allocate | a buffer for certificate parsing | ||
| CertBufferSize | = DataSize + 1; | ||
| Count | the number of signature lists | ||
| Debug | print the signature list info | ||
| Iterate | through each signature list | ||
| CertCount | = SigListCount; | ||
| Calculate | the offset to the signature data within this list | ||
| UINTN | SigDataOffset; | ||
| Get | the owner GUID from the signature list | ||
| Actually | owner GUID for this list context | ||
| This | is simplified | ||
| Check | if this signature type is EFI_CERT_SHA256_GUID | ||
| if | (CompareMem (&SigList->SignatureType, mCertSha256Guid, sizeof (EFI_GUID)) == 0) { | ||
| Iterate | through each signature data entry in this list | ||
| SigData | = (EFI_SIGNATURE_DATA )((UINT8 )SigList + SigDataOffset); | ||
| The | signature data contains: | ||
| EFI_GUID | SignatureOwner (16 bytes) | ||
| UINT8 | SignatureData[...] | ||
| For | X.509 certs, the SignatureData starts with the X.509 certificate. | ||
| We | can search for the subject name within the DER-encoded cert. | ||
| UINTN | CertDataOffset; | ||
| Zero | the cert buffer and call the security database to parse | ||
| ZeroMem | (CertBuffer, CertBufferSize); | ||
| If | SecurityDatabase is available, call its parse function | ||
| if | (SecurityDatabase != NULL) { | ||
| The | security database protocol entry point for parsing | ||
| certificates | and extracting subject names. | ||
| This | calls into the Authenticated Variable parser. | ||
| UINTN | ParsedDataSize; | ||
| Call | the parse function. This typically invokes | ||
| an | internal function that extracts the subject from | ||
| an | X.509 certificate. | ||
| if | (mDebugMaskProtocol != NULL) { | ||
| Use | the image security database protocol's parse function | ||
| to | extract the subject name from the certificate. | ||
| Compare | the parsed subject name with the target | ||
| if | (CompareMem (CertBuffer, SubjectName, SubjectNameLen) == 0) { | ||
| Move | to the next signature data entry | ||
| SigData | = (EFI_SIGNATURE_DATA )((UINT8 )SigData + SigSize); | ||
| Move | to the next signature list | ||
| SigList | = (EFI_SIGNATURE_LIST )((UINT8 )SigList + SigList->SignatureListSize); | ||
| Signature | Database Update | ||
| This | function validates the EFI_SIGNATURE_LIST structure(s) | ||
| in | the buffer and returns the total size of valid entries. | ||
| Currently | a stub that returns the input size after validation. | ||
| if | **(Data == NULL | ParsedSize == NULL) {** | |
| Step | 1: Read the current "db" variable size | ||
| Step | 2: Allocate and read the current data | ||
| DbData | = AllocatePool (DbDataSize); | ||
| Step | 3: Parse the existing data to validate it | ||
| Status | = ParseDbSignatureData (DbData, &ParsedSize); | ||
| Step | 4: Allocate a new buffer with room for timestamp + existing + new data | ||
| NewDataSize | = GetTimeStampSize () + DbDataSize; | ||
| Step | 5: Build the timestamp at the start of the new buffer | ||
| BuildTimestamp | ((EFI_TIME *)NewData); | ||
| Step | 6: Copy existing signature data after the timestamp | ||
| Step | 7: Write the updated variable | ||
| Status | = SetVariableWithTimestamp ( | ||
| Query | the "db" variable size | ||
| Status | = gRuntimeServices->GetVariable ( | ||
| Step | 2: Allocate and read the current variable data | ||
| Step | 3: Allocate new buffer with room for timestamp | ||
| Step | 4: Build timestamp at the start | ||
| Step | 5: Copy existing data after timestamp | ||
| Step | 6: Write the updated variable | ||
| Get | the FVB protocol on the given handle | ||
| Status | = gBootServices->HandleProtocol ( | ||
| Query | FVB size | ||
| Allocate | buffer and read | ||
| Buffer | = AllocatePool (Size); | ||
| Driver | Entry Point | ||
| Cache | global table pointers. | ||
| This | mirrors the standard UEFI BootServicesTableLib initialisation. | ||
| gImageHandle | = ImageHandle; | ||
| Initialise | the HOB list (required for variable services) | ||
| HobLibInit | (); | ||
| Cache | runtime/BS pointers if not already set in the global init above | ||
| if | (SystemTable->RuntimeServices == NULL) { | ||
| Create | a new handle and install the Device Guard API protocol. | ||
| The | protocol is a singleton interface for managing the "db" variable. | ||
| Expand | 16-bit value to 32-bit pattern | ||
| WordValue | **= Value | ((UINT32)Value << 16);** | |
| Handle | misalignment | ||
| AlignAdjust | = (4 - ((UINTN)ByteBuffer & 3)) & 3; | ||
| Fill | 4 bytes at a time | ||
| WordBuffer | = (UINT32 *)ByteBuffer; | ||
| Fill | remaining bytes | ||
| for | (Index = 0; Index < Size; Index++) { | ||
| Save | interrupt state and disable interrupts | ||
| InterruptState | = SaveAndDisableInterrupts (); | ||
| Handle | overlapping regions where source < dest | ||
| by | copying from the end. | ||
| if | ((UINTN)Source < (UINTN)Destination && | ||
| SrcBytes | = (CONST UINT8 *)Source + Length; | ||
| Align | destination | ||
| AlignDelta | = (UINTN)DestBytes & 7; | ||
| Copy | 8 bytes at a time | ||
| Count64 | = Length >> 3; | ||
| Copy | remaining bytes backwards | ||
| while | (Length-- != 0) { | ||
| if | (Length >= 8 && (UINTN)((INTN)DestBytes - (INTN)SrcBytes) >= 8) { | ||
| Align | source and destination | ||
| Restore | interrupt state | ||
| RestoreInterrupts | (InterruptState); | ||
| Protocol | Method Implementation (for the installed protocol structure) | ||
| The | AMI_DEVICE_GUARD_API_PROTOCOL instance | ||
| AMI_DEVICE_GUARD_API_PROTOCOL | gAmiDeviceGuardApiProtocol = { |
Generated by HR650X BIOS Decompilation Project