| Address | Name | Description |
|---|---|---|
| SendReceiveRaw | ||
| DriverInitEntry | ||
| TcgStorageSecuritySupported | ||
| TcgStorageSecurityStart | ||
| TcgStorageSecurityStop | ||
| TcgRetrieveSecurityStatus | ||
| TcgSendReceive | ||
| TcgGetInfo | ||
| TcgSetPassword | ||
| TcgReset | ||
| TcgBlockSid | ||
| GetSupportedProtocols | ||
| OpenSessionWithAdminSpMsid | ||
| CloseSession | ||
| GetLevel0DiscoveryData | ||
| ParseLevel0DiscoveryData | ||
| OpenLockingSpSession | ||
| ReadLockingRange | ||
| SetLockingRange | ||
| ConfigureLockingRange | ||
| SetSidCredential | ||
| InitializeTcgSessions | ||
| GetMsidCredential | ||
| GetOpalSecurityStatus | ||
| UpdateLockingStatus | ||
| CopyPciDataToS3Buffer | ||
| RestoreS3Data | ||
| InitializeS3Data | ||
| _ModuleEntryPoint | ||
| External | protocol GUIDs and device path protocols | |
| extern | EFI_GUID gEfiTcgStorageProtocolGuid; | |
| Global | data references | |
| volatile | UINTN gImageHandle = 0; | |
| Module | global state | |
| UINTN | n0x180 = 0; | |
| GUID | tables | |
| EFI_GUID | gTcgStorageProtocolGuid = { 0xCA1E3F1A, 0x2D84, 0x46C8, { 0x9B, 0x2E, 0x23, 0x51, 0xC0, 0xB9, 0x1B, 0x94 } }; | |
| Static | data used by Level 0 discovery parsing | |
| extern | UINT8 FeatureTper[]; | |
| Validate | input parameters using UEFI Boot Services Table Library | |
| ASSERT | (gImageHandle != 0); | |
| Perform | platform-specific initialization | |
| Check | for PCI OPAL presence and configure CMOS | |
| PciData | = PciRead32 (PCI_LIB_ADDRESS (0, 0, 0, 0)); | |
| Configure | chipset register for OPAL | |
| PciOr8 | (PCI_LIB_ADDRESS (0, 0, 0, 0xA4), BIT7); | |
| Check | CMOS for TCG enable | |
| if | ((IoRead8 (0x71) & 0x0F) == 0) { | |
| Check | platform type via memory-mapped I/O | |
| if | ((MmioRead8 (0xFEDAF0490) & 0x02) != 0) { | |
| Check | if controller supports EFI Storage Security Command Protocol | |
| Status | = gBS->OpenProtocol ( | |
| Open | the Storage Security Command Protocol | |
| Check | if TCG security protocol (0x01) is supported | |
| Status | = GetSupportedProtocols (TcgProtocol, 1); | |
| Check | if the protocol is already installed (already started) | |
| Allocate | protocol context | |
| Status | = gBS->AllocatePool ( | |
| Set | up function dispatch table | |
| Link | back to driver context and set flags | |
| Primary | context | |
| Initialize | per-controller session data | |
| Status | = InitializeTcgSessions (TcgProtocol, 1); | |
| Retrieve | initial security status | |
| Status | = TcgRetrieveSecurityStatus (Context, &SecurityStatus); | |
| Handle | TPER reset / Block SID if needed | |
| if | (!(SecurityStatus & TCG_SECURITY_STATUS_FROZEN) && | |
| Issue | TPER reset for locked drives | |
| Status | = OpenSessionWithAdminSpMsid ( | |
| Install | the protocol on the controller handle | |
| Status | = gBS->InstallMultipleProtocolInterfaces ( | |
| Register | protocol notification for Block SID | |
| if | (gBlockSidStorageProtocol == NULL) { | |
| Register | timer event for periodic S3 data save | |
| if | (gSidBlockCommandInterface == NULL) { | |
| Uninstall | the protocol and free context | |
| Status | = gBS->UninstallMultipleProtocolInterfaces ( | |
| Close | the storage security command protocol | |
| TCG | Storage Protocol Interface Functions | |
| Resolve | TPER context based on primary/secondary binding | |
| if | (Index == 1) { | |
| BIT0 | operations: Locking range related | |
| StatusFlags | = GetOpalSecurityStatus (TcgContext->DriverContext, Index); | |
| Already | locked: perform ReadLockingRange | |
| Status | = ReadLockingRange (TperContext, Buffer); | |
| Not | locked: perform full Locking SP session | |
| Status | = OpenLockingSpSession (TperContext, Buffer); | |
| Set | locking state to ReadWrite (0x02) | |
| LockingState | = OPAL_LOCKING_STATE_READWRITE; | |
| BIT1 | operations: Set SID credential / MSID related | |
| Status | = SetSidCredential (TperContext, Buffer); | |
| Other | operations: C_PIN_SID / credential handling | |
| if | ((Operation & BIT0) != 0) { | |
| Check | for Block SID feature | |
| if | ((UINT16 )((UINTN)TperContext + 82) == TCG_FEATURE_CODE_BLOCK_SID) { | |
| Check | C_PIN_SID vs C_PIN_MSID equality | |
| if | (((UINT8 )((UINTN)TperContext + 86) & SID_BLOCK_STATUS_C_PIN_SID) == 0) { | |
| Block | SID supported | |
| Check | if SID is already blocked | |
| if | (((UINT8 )((UINTN)TperContext + 86) & SID_BLOCK_STATUS_SID_VALUE) != 0) { | |
| Already | blocked | |
| Issue | TPER reset via Admin SP session | |
| return | OpenSessionWithAdminSpMsid ( | |
| Check | if Block SID feature is supported (feature code 0x0402 = 1026) | |
| if | ((UINT16 )((UINTN)TperContext + 82) != 0x0402) { | |
| Check | C_PIN_SID is not equal to C_PIN_MSID | |
| SidStatus | = (UINT8 )((UINTN)TperContext + 86); | |
| if | ((SidStatus & SID_BLOCK_STATUS_SID_VALUE) != 0) { | |
| Clear | and send Block SID command | |
| if | (gSidBlockPassword[0] != 0) { | |
| Open | session and issue Block SID | |
| 1280 | bytes | |
| Internal | Helper Functions | |
| 10 | seconds | |
| 113 | * 8 | |
| Query | supported protocols | |
| ZeroMem | (Buffer, sizeof (Buffer)); | |
| Security | protocol 0 = list | |
| Receive | BufferSize | |
| Parse | protocol list (big-endian byte count at offset 6) | |
| ProtocolList | = Buffer + 8; | |
| Number | of supported protocols | |
| Look | for protocol 0x01 (TCG / OPAL) | |
| for | (SpIndex = 0; SpIndex < SpCount; SpIndex++) { | |
| Build | session open request | |
| ZeroMem | (Request, sizeof (Request)); | |
| session | manager / start session | |
| Admin | SP UID (0x00000000) | |
| Authority | (e.g. 0x01 = Admin1, 0x02 = Admin2) | |
| Write | method header (8 bytes) | |
| WriteUnaligned64 | ((UINT64 *)&Request[16], (UINT64)0x0000000000000003); // SMUID + method | |
| Send | the command | |
| TransferLength | = sizeof (Request); | |
| TCG | protocol | |
| Send | TransferLength | |
| Build | close session request (end session) | |
| ZeroMem | (CloseRequest, sizeof (CloseRequest)); | |
| session | manager | |
| Send | close session via security protocol 0x01 | |
| Status | = SendReceiveRaw ( | |
| 50 | second timeout | |
| Allocate | discovery buffer | |
| AllocSize | = sizeof (UINTN) * 64; | |
| Determine | timeout and other params | |
| Timeout | = 10000000; // 10 seconds default | |
| TCG | layer request | |
| ComID | 0x0100 | |
| Check | if this is a Level 0 session | |
| DiscoveryContext | = (UINT8 *)DeviceContext; | |
| 50 | seconds for non-Level0 | |
| Perform | discovery receive | |
| TransferLength | = 512; | |
| Protocol | ID | |
| Parse | the discovery response | |
| Status | = ParseLevel0DiscoveryData (DeviceContext, Buffer); | |
| Skip | the TCG Level 0 discovery header (first 48 bytes) | |
| Header | includes: Length (4), Version (2), Reserved, VendorID, etc. | |
| Data | = (UINT8 *)Data + 48; // +12 dwords | |
| Walk | feature descriptors | |
| Each | descriptor: FeatureCode(2) + Version(1) + Length(1) + Data(Length) | |
| while | ((UINTN)(Data - (UINT8 *)DiscoveryBuffer) < RemainingLength) { | |
| 0x0001 | // | |
| TPER | feature: byte 0 of data has TPER flags | |
| Locking | feature: byte 0 of data has locking flags | |
| Geometry | feature: 32 bytes of geometry data | |
| CopyMem | ((VOID *)((UINTN)Context + 30), FeatureData, 32); | |
| OPAL | SSC V2 | |
| OPAL | SSC V2 feature descriptor | |
| SSC | V1 | |
| SSC | V2 (alternate) | |
| SSC | feature descriptor: similar structure | |
| Block | SID | |
| Block | SID feature descriptor | |
| Advance | to next descriptor | |
| Data | += FeatureLength + 4; | |
| Open | session with Locking SP using the stored MSID/PIN | |
| This | is a simplified wrapper around the TCG session open method. | |
| return | EFI_SUCCESS; | |
| Read | locking range info via TCG method calls | |
| Send | locking range config method call | |
| Set | locking range state to desired value | |
| Set | C_PIN_SID using the provided credential buffer. | |
| Opens | session with Admin SP, sends Set method for C_PIN_SID. | |
| Allocate | session buffer | |
| Initialize | based on binding index | |
| Primary | context: use device path node and PFA | |
| CopyMem | (SessionData, (VOID *)((UINTN)DeviceContext + 904), sizeof (UINTN)); | |
| Secondary | context: use secondary binding data | |
| CopyMem | (SessionData, (VOID *)((UINTN)DeviceContext + 4256), sizeof (UINTN)); | |
| Get | Level 0 Discovery data | |
| Status | = GetLevel0DiscoveryData (SessionData); | |
| Allocate | and retrieve MSID credential (C_PIN_MSID) | |
| if | (gMsidCredential[0] == 0) { | |
| Perform | MSID credential retrieval (Get C_PIN_MSID_UID) | |
| DEBUG | ((DEBUG_INFO, "Get C_PIN_MSID_UID\n")); | |
| Store | session pointer in the appropriate context slot | |
| Send | Get method for C_PIN_MSID UID | |
| This | sends a TCG command to read C_PIN_MSID value from | |
| the | Admin SP, using the stored credential UID. | |
| Read | locking flags | |
| StatusFlags | = ((UINT8 )(TperContext + 25) & 0x07); | |
| Check | SID blocked status (SID is blocked if BIT1 set at offset 86) | |
| if | (((UINT8 )(TperContext + 86) & 0x02) != 0) { | |
| Notify | the system via S3 buffer that locking state changed | |
| S3 | Resume Data Management | |
| Check | buffer capacity (0x180 entries max) | |
| if | (n0x180 >= TCG_S3_BUFFER_SLOTS) { | |
| Store | at slot position (3 UINT64 per slot = 24 bytes) | |
| SlotIndex | = n0x180; | |
| Walk | all stored entries and perform PCI config writes | |
| for | (SlotIndex = 0; SlotIndex < Count; SlotIndex++) { | |
| Initialization | and Dispatch | |
| Table | of (BDF, Register, Value) triples for S3 save | |
| typedef | struct { | |
| These | entries come from the PciS3Table in the HOB | |
| EntryCount | = 5; // 5 entries: 5 descriptors * 12 bytes each = 60 bytes | |
| Driver | Binding Protocol instance | |
| EFI_DRIVER_BINDING_PROTOCOL | gDriverBinding = { | |
| Protocol | installation notification entries | |
| EFI_EVENT | gTcgStorageSecurityEvent; |
Generated by HR650X BIOS Decompilation Project