summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c901
1 files changed, 901 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c
new file mode 100644
index 00000000..5a975057
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c
@@ -0,0 +1,901 @@
+/** @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;
+}