/** @file Provide functions to provide tcg storage core spec related functions. Copyright (c) 2016, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include 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; }