/** @file
|
Provide functions to provide tcg storage core spec related functions.
|
|
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Library/TcgStorageCoreLib.h>
|
|
#include <Library/BaseLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <Library/DebugLib.h>
|
|
typedef struct {
|
UINT16 FeatureCode;
|
TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feature;
|
UINTN FeatureSize;
|
} TCG_FIND_FEATURE_CTX;
|
|
/**
|
Returns a human-readable string representing a method status return code.
|
|
@param[in] MethodStatus Method status to translate to a string
|
|
|
@retval return the string info.
|
**/
|
CHAR8*
|
EFIAPI
|
TcgMethodStatusString(
|
UINT8 MethodStatus
|
)
|
{
|
switch (MethodStatus) {
|
#define C(status) case TCG_METHOD_STATUS_CODE_ ## status: return #status
|
C(SUCCESS);
|
C(NOT_AUTHORIZED);
|
C(OBSOLETE);
|
C(SP_BUSY);
|
C(SP_FAILED);
|
C(SP_DISABLED);
|
C(SP_FROZEN);
|
C(NO_SESSIONS_AVAILABLE);
|
C(UNIQUENESS_CONFLICT);
|
C(INSUFFICIENT_SPACE);
|
C(INSUFFICIENT_ROWS);
|
C(INVALID_PARAMETER);
|
C(OBSOLETE2);
|
C(OBSOLETE3);
|
C(TPER_MALFUNCTION);
|
C(TRANSACTION_FAILURE);
|
C(RESPONSE_OVERFLOW);
|
C(AUTHORITY_LOCKED_OUT);
|
C(FAIL);
|
#undef C
|
}
|
return "unknown";
|
}
|
|
|
/**
|
adds call token and method Header (invoking id, and method id).
|
|
@param CreateStruct The input create structure.
|
@param InvokingId Invoking id.
|
@param MethodId Method id.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgStartMethodCall(
|
TCG_CREATE_STRUCT *CreateStruct,
|
TCG_UID InvokingId,
|
TCG_UID MethodId
|
)
|
{
|
NULL_CHECK(CreateStruct);
|
|
if (CreateStruct->ComPacket == NULL ||
|
CreateStruct->CurPacket == NULL ||
|
CreateStruct->CurSubPacket == NULL
|
) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
|
return (TcgResultFailureInvalidAction);
|
}
|
|
ERROR_CHECK(TcgAddCall(CreateStruct));
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, InvokingId));
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, MethodId));
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Adds START LIST token.
|
|
@param CreateStruct The input create structure.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgStartParameters(
|
TCG_CREATE_STRUCT *CreateStruct
|
)
|
{
|
NULL_CHECK(CreateStruct);
|
|
if (CreateStruct->ComPacket == NULL ||
|
CreateStruct->CurPacket == NULL ||
|
CreateStruct->CurSubPacket == NULL
|
) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
|
return (TcgResultFailureInvalidAction);
|
}
|
|
return TcgAddStartList(CreateStruct);
|
}
|
|
/**
|
Adds END LIST token.
|
|
@param CreateStruct The input create structure.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgEndParameters(
|
TCG_CREATE_STRUCT *CreateStruct
|
)
|
{
|
NULL_CHECK(CreateStruct);
|
|
if (CreateStruct->ComPacket == NULL ||
|
CreateStruct->CurPacket == NULL ||
|
CreateStruct->CurSubPacket == NULL
|
) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
|
return (TcgResultFailureInvalidAction);
|
}
|
|
return TcgAddEndList(CreateStruct);
|
}
|
|
/**
|
Adds END Data token and method list.
|
|
@param CreateStruct The input create structure.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgEndMethodCall(
|
TCG_CREATE_STRUCT *CreateStruct
|
)
|
{
|
NULL_CHECK(CreateStruct);
|
|
if (CreateStruct->ComPacket == NULL ||
|
CreateStruct->CurPacket == NULL ||
|
CreateStruct->CurSubPacket == NULL
|
) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
|
return (TcgResultFailureInvalidAction);
|
}
|
|
ERROR_CHECK(TcgAddEndOfData(CreateStruct));
|
|
ERROR_CHECK(TcgAddStartList(CreateStruct));
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00)); // expected to complete properly
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00)); // reserved
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00)); // reserved
|
ERROR_CHECK(TcgAddEndList(CreateStruct));
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Retrieves the comID and Extended comID of the ComPacket in the Tcg response.
|
It is intended to be used to confirm the received Tcg response is intended for user that received it.
|
|
@param [in] ParseStruct Structure used to parse received TCG response.
|
@param [in/out] ComId comID retrieved from received ComPacket.
|
@param [in/out] ComIdExtension Extended comID retrieved from received ComPacket
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgGetComIds(
|
const TCG_PARSE_STRUCT *ParseStruct,
|
UINT16 *ComId,
|
UINT16 *ComIdExtension
|
)
|
{
|
NULL_CHECK(ParseStruct);
|
NULL_CHECK(ComId);
|
NULL_CHECK(ComIdExtension);
|
|
if (ParseStruct->ComPacket == NULL) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p\n", ParseStruct->ComPacket));
|
return TcgResultFailureInvalidAction;
|
}
|
|
*ComId = SwapBytes16(ParseStruct->ComPacket->ComIDBE);
|
*ComIdExtension = SwapBytes16(ParseStruct->ComPacket->ComIDExtensionBE);
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Checks if the ComIDs of the response match the expected values.
|
|
@param[in] ParseStruct Structure used to parse received TCG response
|
@param[in] ExpectedComId Expected comID
|
@param[in] ExpectedComIdExtension Expected extended comID
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgCheckComIds(
|
const TCG_PARSE_STRUCT *ParseStruct,
|
UINT16 ExpectedComId,
|
UINT16 ExpectedComIdExtension
|
)
|
{
|
UINT16 ParseComId;
|
UINT16 ParseComIdExtension;
|
|
ERROR_CHECK(TcgGetComIds(ParseStruct, &ParseComId, &ParseComIdExtension));
|
if (ParseComId != ExpectedComId || ParseComIdExtension != ExpectedComIdExtension) {
|
DEBUG ((DEBUG_INFO, "Com ID: Actual 0x%02X Expected 0x%02X\n", ParseComId, ExpectedComId));
|
DEBUG ((DEBUG_INFO, "Extended Com ID: 0x%02X Expected 0x%02X\n", ParseComIdExtension, ExpectedComIdExtension));
|
return TcgResultFailure;
|
}
|
return TcgResultSuccess;
|
}
|
|
/**
|
Returns the method status of the current subpacket. Does not affect the current position
|
in the ComPacket. In other words, it can be called whenever you have a valid SubPacket.
|
|
@param [in/out] ParseStruct Structure used to parse received TCG response
|
@param [in/out] MethodStatus Method status retrieved of the current SubPacket
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgGetMethodStatus(
|
const TCG_PARSE_STRUCT *ParseStruct,
|
UINT8 *MethodStatus
|
)
|
{
|
TCG_PARSE_STRUCT TmpParseStruct;
|
TCG_TOKEN TcgToken;
|
UINT8 Reserved1, Reserved2;
|
|
NULL_CHECK(ParseStruct);
|
NULL_CHECK(MethodStatus);
|
|
if (ParseStruct->ComPacket == NULL ||
|
ParseStruct->CurPacket == NULL ||
|
ParseStruct->CurSubPacket == NULL
|
) {
|
DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));
|
return TcgResultFailureInvalidAction;
|
}
|
|
// duplicate ParseStruct, then don't need to "reset" location cur ptr
|
CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));
|
|
// method status list exists after the end method call in the subpacket
|
// skip tokens until ENDDATA is found
|
do {
|
ERROR_CHECK(TcgGetNextToken(&TmpParseStruct, &TcgToken));
|
} while (TcgToken.Type != TcgTokenTypeEndOfData);
|
|
// only reach here if enddata is found
|
// at this point, the curptr is pointing at method status list beginning
|
ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));
|
ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, MethodStatus));
|
ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved1));
|
ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved2));
|
ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));
|
|
if (Reserved1 != 0) {
|
DEBUG ((DEBUG_INFO, "Method status reserved1 = 0x%02X (expected 0)\n", Reserved1));
|
return TcgResultFailure;
|
}
|
|
if (Reserved2 != 0) {
|
DEBUG ((DEBUG_INFO, "Method status reserved2 = 0x%02X (expected 0)\n", Reserved1));
|
return TcgResultFailure;
|
}
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Return the toke type string info.
|
|
@param Type Input the type info.
|
|
@retval Return the string for this type.
|
|
**/
|
CHAR8*
|
EFIAPI
|
TcgTokenTypeString(
|
TCG_TOKEN_TYPE Type
|
)
|
{
|
switch (Type) {
|
case TcgTokenTypeReserved: return "Reserved";
|
case TcgTokenTypeTinyAtom: return "Tiny Atom";
|
case TcgTokenTypeShortAtom: return "Short Atom";
|
case TcgTokenTypeMediumAtom: return "Medium Atom";
|
case TcgTokenTypeLongAtom: return "Long Atom";
|
case TcgTokenTypeStartList: return "Start List";
|
case TcgTokenTypeEndList: return "End List";
|
case TcgTokenTypeStartName: return "Start Name";
|
case TcgTokenTypeEndName: return "End Name";
|
case TcgTokenTypeCall: return "Call";
|
case TcgTokenTypeEndOfData: return "End of Data";
|
case TcgTokenTypeEndOfSession: return "End of Session";
|
case TcgTokenTypeStartTransaction: return "Start Transaction";
|
case TcgTokenTypeEndTransaction: return "End Transaction";
|
case TcgTokenTypeEmptyAtom: return "Empty atom";
|
}
|
return "Unknown";
|
}
|
|
|
/**
|
|
Adds Start Session call to the data structure. This creates the entire ComPacket structure and
|
returns the size of the entire compacket in the size parameter.
|
|
@param [in/out] CreateStruct Structure used to add the start session call
|
@param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
|
@param [in] ComId ComID for the ComPacket
|
@param [in] ComIdExtension Extended ComID for the ComPacket
|
@param [in] HostSessionId Host Session ID
|
@param [in] SpId Security Provider to start session with
|
@param [in] Write Write option for start session. TRUE = start session requests write access
|
@param [in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
|
@param [in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge shall be sent.
|
@param [in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority shall be sent.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgCreateStartSession(
|
TCG_CREATE_STRUCT *CreateStruct,
|
UINT32 *Size,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 HostSessionId,
|
TCG_UID SpId,
|
BOOLEAN Write,
|
UINT32 HostChallengeLength,
|
const VOID *HostChallenge,
|
TCG_UID HostSigningAuthority
|
)
|
{
|
ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
|
ERROR_CHECK(TcgStartPacket(CreateStruct, 0x0, 0x0, 0x0, 0x0, 0x0)) ;
|
ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
|
ERROR_CHECK(TcgStartMethodCall(CreateStruct, TCG_UID_SMUID, TCG_UID_SM_START_SESSION));
|
ERROR_CHECK(TcgStartParameters(CreateStruct));
|
ERROR_CHECK(TcgAddUINT32(CreateStruct, HostSessionId));
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, SpId));
|
ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Write));
|
|
// optional parameters
|
if (HostChallenge != NULL && HostChallengeLength != 0) {
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00)); //TODO Create Enum for Method Optional Parameters?
|
ERROR_CHECK(TcgAddByteSequence(CreateStruct, HostChallenge, HostChallengeLength, FALSE));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
}
|
// optional parameters
|
if (HostSigningAuthority != 0) {
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x03)); //TODO Create Enum for Method Optional Parameters?
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, HostSigningAuthority));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
}
|
|
ERROR_CHECK(TcgEndParameters(CreateStruct));
|
ERROR_CHECK(TcgEndMethodCall(CreateStruct));
|
ERROR_CHECK(TcgEndSubPacket(CreateStruct));
|
ERROR_CHECK(TcgEndPacket(CreateStruct));
|
ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID. If the Sync Session response
|
parameters do not match the comID, extended ComID and host session ID then a failure is returned.
|
|
@param[in/out] ParseStruct Structure used to parse received TCG response, contains Sync Session response.
|
@param[in] ComId Expected ComID that is compared to actual ComID of response
|
@param[in] ComIdExtension Expected Extended ComID that is compared to actual Extended ComID of response
|
@param[in] HostSessionId Expected Host Session ID that is compared to actual Host Session ID of response
|
@param[in/out] TperSessionId Tper Session ID retrieved from the Sync Session response.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgParseSyncSession(
|
const TCG_PARSE_STRUCT *ParseStruct,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 HostSessionId,
|
UINT32 *TperSessionId
|
)
|
{
|
UINT8 MethodStatus;
|
TCG_PARSE_STRUCT TmpParseStruct;
|
UINT16 ParseComId;
|
UINT16 ParseExtComId;
|
TCG_UID InvokingUID;
|
TCG_UID MethodUID;
|
UINT32 RecvHostSessionId;
|
|
NULL_CHECK(ParseStruct);
|
NULL_CHECK(TperSessionId);
|
|
CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));
|
|
// verify method status is good
|
ERROR_CHECK(TcgGetMethodStatus(&TmpParseStruct, &MethodStatus));
|
METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
|
|
// verify comids
|
ERROR_CHECK(TcgGetComIds(&TmpParseStruct, &ParseComId, &ParseExtComId));
|
|
if ((ComId != ParseComId) || (ComIdExtension != ParseExtComId)) {
|
DEBUG ((DEBUG_INFO, "unmatched comid (exp: 0x%X recv: 0x%X) or comid extension (exp: 0x%X recv: 0x%X)\n", ComId, ParseComId, ComIdExtension, ParseExtComId));
|
return TcgResultFailure;
|
}
|
ERROR_CHECK(TcgGetNextCall(&TmpParseStruct));
|
ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &InvokingUID));
|
ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &MethodUID));
|
ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));
|
ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, &RecvHostSessionId));
|
ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, TperSessionId));
|
ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));
|
ERROR_CHECK(TcgGetNextEndOfData(&TmpParseStruct));
|
|
if (InvokingUID != TCG_UID_SMUID) {
|
DEBUG ((DEBUG_INFO, "Invoking UID did not match UID_SMUID\n"));
|
return TcgResultFailure;
|
}
|
|
if (MethodUID != TCG_UID_SM_SYNC_SESSION) {
|
DEBUG ((DEBUG_INFO, "Method UID did not match UID_SM_SYNC_SESSION\n"));
|
return TcgResultFailure;
|
}
|
|
if (HostSessionId != RecvHostSessionId) {
|
DEBUG ((DEBUG_INFO, "unmatched HostSessionId (exp: 0x%X recv: 0x%X)\n", HostSessionId, RecvHostSessionId));
|
return TcgResultFailure;
|
}
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
|
Creates ComPacket with EndSession.
|
This assumes a start session has already been opened.
|
|
@param [in/out] CreateStruct Structure used to add Endsession
|
@param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
|
@param [in] ComId ComID for the ComPacket
|
@param [in] ComIdExtension Extended ComID for the ComPacket
|
@param [in] HostSessionId Host Session ID for the Packet
|
@param [in] TpSessionId Tper Session ID for the Packet
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgCreateEndSession(
|
TCG_CREATE_STRUCT *CreateStruct,
|
UINT32 *Size,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 HostSessionId,
|
UINT32 TpSessionId
|
)
|
{
|
ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
|
ERROR_CHECK(TcgStartPacket(CreateStruct, TpSessionId, HostSessionId, 0x0, 0x0, 0x0));
|
ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
|
ERROR_CHECK(TcgAddEndOfSession(CreateStruct));
|
ERROR_CHECK(TcgEndSubPacket(CreateStruct));
|
ERROR_CHECK(TcgEndPacket(CreateStruct));
|
ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
|
|
return TcgResultSuccess;
|
}
|
|
/**
|
Set start method.
|
|
@param CreateStruct Input create structure.
|
@param Row Input the row info.
|
@param ColumnNumber the column info.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgStartMethodSet(
|
TCG_CREATE_STRUCT *CreateStruct,
|
TCG_UID Row,
|
UINT32 ColumnNumber
|
)
|
{
|
ERROR_CHECK(TcgStartMethodCall(CreateStruct, Row, TCG_UID_METHOD_SET));
|
ERROR_CHECK(TcgStartParameters(CreateStruct));
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x01)); // "Values"
|
ERROR_CHECK(TcgAddStartList(CreateStruct));
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddUINT32(CreateStruct, ColumnNumber));
|
return TcgResultSuccess;
|
}
|
|
/**
|
Set end method.
|
|
@param CreateStruct Input create structure.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgEndMethodSet(
|
TCG_CREATE_STRUCT *CreateStruct
|
)
|
{
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
ERROR_CHECK(TcgAddEndList(CreateStruct));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
ERROR_CHECK(TcgEndParameters(CreateStruct));
|
ERROR_CHECK(TcgEndMethodCall(CreateStruct));
|
return TcgResultSuccess;
|
}
|
|
/**
|
Creates ComPacket with a Method call that sets the PIN column for the row specified.
|
This assumes a start session has already been opened with the desired SP.
|
|
@param [in/out] CreateStruct Structure used to add method call.
|
@param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
|
@param [in] ComId ComID for the ComPacket
|
@param [in] ComIdExtension Extended ComID for the ComPacket
|
@param [in] TperSession Tper Session ID for the Packet
|
@param [in] HostSession Host Session ID for the Packet
|
@param [in] SidRow UID of row of current SP to set PIN column
|
@param [in] Password value of PIN to set
|
@param [in] PasswordSize Size of PIN
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgCreateSetCPin(
|
TCG_CREATE_STRUCT *CreateStruct,
|
UINT32 *Size,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 TperSession,
|
UINT32 HostSession,
|
TCG_UID SidRow,
|
const VOID *Password,
|
UINT32 PasswordSize
|
)
|
{
|
// set new SID Password
|
ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
|
ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
|
ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
|
ERROR_CHECK(TcgStartMethodSet(CreateStruct, SidRow, 0x03)); // "PIN"
|
ERROR_CHECK(TcgAddByteSequence(CreateStruct, Password, PasswordSize, FALSE));
|
ERROR_CHECK(TcgEndMethodSet(CreateStruct));
|
ERROR_CHECK(TcgEndSubPacket(CreateStruct));
|
ERROR_CHECK(TcgEndPacket(CreateStruct));
|
ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
|
return TcgResultSuccess;
|
}
|
|
/**
|
Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.
|
This assumes a start session has already been opened with the desired SP.
|
|
@param [in/out] CreateStruct Structure used to add method call
|
@param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
|
@param [in] ComId ComID for the ComPacket
|
@param [in] ComIdExtension Extended ComID for the ComPacket
|
@param [in] TperSession Tper Session ID for the Packet
|
@param [in] HostSession Host Session ID for the Packet
|
@param [in] AuthorityUid Authority UID to modify the "Enabled" column for
|
@param [in] Enabled Value to set the "Enabled" column to
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgSetAuthorityEnabled(
|
TCG_CREATE_STRUCT *CreateStruct,
|
UINT32 *Size,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 TperSession,
|
UINT32 HostSession,
|
TCG_UID AuthorityUid,
|
BOOLEAN Enabled
|
)
|
{
|
ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
|
ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
|
ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
|
ERROR_CHECK(TcgStartMethodSet(CreateStruct, AuthorityUid, 0x05)); // "Enabled"
|
ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Enabled));
|
ERROR_CHECK(TcgEndMethodSet(CreateStruct));
|
ERROR_CHECK(TcgEndSubPacket(CreateStruct));
|
ERROR_CHECK(TcgEndPacket(CreateStruct));
|
ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
|
return TcgResultSuccess;
|
}
|
|
/**
|
Create set ace.
|
|
@param CreateStruct Input create structure.
|
@param Size size info.
|
@param ComId ComId info.
|
@param ComIdExtension ComId extension info.
|
@param TperSession Tper session data.
|
@param HostSession Host session data.
|
@param AceRow Ace row info.
|
@param Authority1 Authority 1 info.
|
@param LogicalOperator Logical operator info.
|
@param Authority2 Authority 2 info.
|
|
@retval Return the action result.
|
|
**/
|
TCG_RESULT
|
EFIAPI
|
TcgCreateSetAce(
|
TCG_CREATE_STRUCT *CreateStruct,
|
UINT32 *Size,
|
UINT16 ComId,
|
UINT16 ComIdExtension,
|
UINT32 TperSession,
|
UINT32 HostSession,
|
TCG_UID AceRow,
|
TCG_UID Authority1,
|
BOOLEAN LogicalOperator,
|
TCG_UID Authority2
|
)
|
{
|
UINT8 HalfUidAuthorityObjectRef[4];
|
UINT8 HalfUidBooleanAce[4];
|
|
HalfUidAuthorityObjectRef[0] = 0x0;
|
HalfUidAuthorityObjectRef[1] = 0x0;
|
HalfUidAuthorityObjectRef[2] = 0xC;
|
HalfUidAuthorityObjectRef[3] = 0x5;
|
|
HalfUidBooleanAce[0] = 0x0;
|
HalfUidBooleanAce[1] = 0x0;
|
HalfUidBooleanAce[2] = 0x4;
|
HalfUidBooleanAce[3] = 0xE;
|
|
ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
|
ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
|
ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
|
ERROR_CHECK(TcgStartMethodSet(CreateStruct, AceRow, 0x03)); // "BooleanExpr"
|
ERROR_CHECK(TcgAddStartList(CreateStruct));
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority1));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));
|
ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority2));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
|
ERROR_CHECK(TcgAddStartName(CreateStruct));
|
ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidBooleanAce, sizeof(HalfUidBooleanAce), FALSE));
|
ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, LogicalOperator));
|
ERROR_CHECK(TcgAddEndName(CreateStruct));
|
ERROR_CHECK(TcgAddEndList(CreateStruct));
|
ERROR_CHECK(TcgEndMethodSet(CreateStruct));
|
ERROR_CHECK(TcgEndSubPacket(CreateStruct));
|
ERROR_CHECK(TcgEndPacket(CreateStruct));
|
ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
|
return TcgResultSuccess;
|
}
|
|
/**
|
Enum level 0 discovery.
|
|
@param DiscoveryHeader Discovery header.
|
@param Callback Callback function.
|
@param Context The context for the function.
|
|
@retval return true if the callback return TRUE, else return FALSE.
|
|
**/
|
BOOLEAN
|
EFIAPI
|
TcgEnumLevel0Discovery(
|
const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
|
TCG_LEVEL0_ENUM_CALLBACK Callback,
|
VOID *Context
|
)
|
{
|
UINT32 BytesLeft;
|
const UINT8 *DiscoveryBufferPtr;
|
UINT32 FeatLength;
|
TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feat;
|
|
//
|
// Total bytes including descriptors but not including the Length field
|
//
|
BytesLeft = SwapBytes32(DiscoveryHeader->LengthBE);
|
|
//
|
// If discovery Header is not valid, exit
|
//
|
if (BytesLeft == 0) {
|
return FALSE;
|
}
|
|
//
|
// Subtract the Length of the Header, except the Length field, which is not included
|
//
|
BytesLeft -= (sizeof(TCG_LEVEL0_DISCOVERY_HEADER) - sizeof(DiscoveryHeader->LengthBE));
|
|
//
|
// Move ptr to first descriptor
|
//
|
DiscoveryBufferPtr = (const UINT8*)DiscoveryHeader + sizeof(TCG_LEVEL0_DISCOVERY_HEADER);
|
|
while (BytesLeft > sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER)) {
|
//
|
// Pointer to beginning of descriptor (including common Header)
|
//
|
Feat = (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*)DiscoveryBufferPtr;
|
|
FeatLength = Feat->Length + sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER);
|
|
//
|
// Not enough bytes left for Feature descriptor
|
//
|
if (BytesLeft < FeatLength) {
|
break;
|
}
|
|
//
|
// Report the Feature to the callback
|
//
|
if (Callback(DiscoveryHeader, Feat, FeatLength, Context)) {
|
return TRUE;
|
}
|
|
//
|
// Descriptor Length only describes Data after common Header
|
//
|
BytesLeft -= FeatLength;
|
DiscoveryBufferPtr += FeatLength;
|
}
|
|
return FALSE;
|
}
|
|
/**
|
The callback function for Get Feature function.
|
|
@param DiscoveryHeader Input discovery header.
|
@param Feature Input Feature.
|
@param FeatureSize Input Feature size.
|
@param Context The context.
|
|
**/
|
BOOLEAN
|
EFIAPI
|
TcgFindFeatureCallback(
|
const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
|
TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feature,
|
UINTN FeatureSize,
|
VOID *Context
|
)
|
{
|
TCG_FIND_FEATURE_CTX* FindCtx;
|
|
FindCtx = (TCG_FIND_FEATURE_CTX*)Context;
|
if ( SwapBytes16( Feature->FeatureCode_BE ) == FindCtx->FeatureCode ) {
|
FindCtx->Feature = Feature;
|
FindCtx->FeatureSize = FeatureSize;
|
return TRUE; // done enumerating features
|
}
|
return FALSE; // continue enumerating
|
}
|
|
/**
|
Get Feature code from the header.
|
|
@param DiscoveryHeader The discovery header.
|
@param FeatureCode return the Feature code.
|
@param FeatureSize return the Feature size.
|
|
@retval return the Feature code data.
|
**/
|
TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*
|
EFIAPI
|
TcgGetFeature(
|
const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
|
UINT16 FeatureCode,
|
UINTN *FeatureSize
|
)
|
{
|
TCG_FIND_FEATURE_CTX FindCtx;
|
|
FindCtx.FeatureCode = FeatureCode;
|
FindCtx.Feature = NULL;
|
FindCtx.FeatureSize = 0;
|
|
TcgEnumLevel0Discovery(DiscoveryHeader, TcgFindFeatureCallback, &FindCtx);
|
if (FeatureSize != NULL) {
|
*FeatureSize = FindCtx.FeatureSize;
|
}
|
return FindCtx.Feature;
|
}
|
|
/**
|
Determines if the protocol provided is part of the provided supported protocol list.
|
|
@param[in] ProtocolList Supported protocol list to investigate
|
@param[in] Protocol Protocol value to determine if supported
|
|
@return TRUE = protocol is supported, FALSE = protocol is not supported
|
**/
|
BOOLEAN
|
EFIAPI
|
TcgIsProtocolSupported(
|
const TCG_SUPPORTED_SECURITY_PROTOCOLS *ProtocolList,
|
UINT16 Protocol
|
)
|
{
|
UINT16 Index;
|
UINT16 ListLength;
|
|
ListLength = SwapBytes16(ProtocolList->ListLength_BE);
|
|
if (ListLength > sizeof(ProtocolList->List)) {
|
DEBUG ((DEBUG_INFO, "WARNING: list Length is larger than max allowed Value; truncating\n"));
|
ListLength = sizeof(ProtocolList->List);
|
}
|
|
for (Index = 0; Index < ListLength; Index++) {
|
if (ProtocolList->List[Index] == Protocol) {
|
return TRUE;
|
}
|
}
|
|
return FALSE;
|
}
|
|
/**
|
Check whether lock or not.
|
|
@param Discovery
|
|
@retval TRUE if lock, FALSE if not lock.
|
**/
|
BOOLEAN
|
EFIAPI
|
TcgIsLocked(
|
const TCG_LEVEL0_DISCOVERY_HEADER *Discovery
|
)
|
{
|
UINTN Size;
|
TCG_LOCKING_FEATURE_DESCRIPTOR *LockDescriptor;
|
|
Size = 0;
|
LockDescriptor =(TCG_LOCKING_FEATURE_DESCRIPTOR*) TcgGetFeature (Discovery, TCG_FEATURE_LOCKING, &Size);
|
|
if (LockDescriptor != NULL && Size >= sizeof(*LockDescriptor)) {
|
DEBUG ((DEBUG_INFO, "locked: %d\n", LockDescriptor->Locked));
|
return LockDescriptor->Locked;
|
}
|
|
//
|
// Descriptor was not found
|
//
|
return FALSE;
|
}
|