# TcgStorageSecurity

## Function Table

| 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*