Newer
Older
AMI-Aptio-BIOS-Reversed / TcgStorageSecurity / TcgStorageSecurity.md
@Ajax Dong Ajax Dong 2 days ago 11 KB Init

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