Home | History | Annotate | Download | only in TcgStorageCoreLib
      1 /** @file
      2   Provide functions to provide tcg storage core spec related functions.
      3 
      4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Library/TcgStorageCoreLib.h>
     16 
     17 #include <Library/BaseLib.h>
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/DebugLib.h>
     20 
     21 typedef struct {
     22     UINT16                                FeatureCode;
     23     TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER  *Feature;
     24     UINTN                                 FeatureSize;
     25 } TCG_FIND_FEATURE_CTX;
     26 
     27 /**
     28   Returns a human-readable string representing a method status return code.
     29 
     30   @param[in]  MethodStatus   Method status to translate to a string
     31 
     32 
     33   @retval   return the string info.
     34 **/
     35 CHAR8*
     36 EFIAPI
     37 TcgMethodStatusString(
     38   UINT8 MethodStatus
     39   )
     40 {
     41   switch (MethodStatus) {
     42     #define C(status) case TCG_METHOD_STATUS_CODE_ ## status: return #status
     43             C(SUCCESS);
     44             C(NOT_AUTHORIZED);
     45             C(OBSOLETE);
     46             C(SP_BUSY);
     47             C(SP_FAILED);
     48             C(SP_DISABLED);
     49             C(SP_FROZEN);
     50             C(NO_SESSIONS_AVAILABLE);
     51             C(UNIQUENESS_CONFLICT);
     52             C(INSUFFICIENT_SPACE);
     53             C(INSUFFICIENT_ROWS);
     54             C(INVALID_PARAMETER);
     55             C(OBSOLETE2);
     56             C(OBSOLETE3);
     57             C(TPER_MALFUNCTION);
     58             C(TRANSACTION_FAILURE);
     59             C(RESPONSE_OVERFLOW);
     60             C(AUTHORITY_LOCKED_OUT);
     61             C(FAIL);
     62     #undef C
     63   }
     64   return "unknown";
     65 }
     66 
     67 
     68 /**
     69   adds call token and method Header (invoking id, and method id).
     70 
     71   @param    CreateStruct             The input create structure.
     72   @param    InvokingId               Invoking id.
     73   @param    MethodId                 Method id.
     74 
     75 **/
     76 TCG_RESULT
     77 EFIAPI
     78 TcgStartMethodCall(
     79   TCG_CREATE_STRUCT   *CreateStruct,
     80   TCG_UID             InvokingId,
     81   TCG_UID             MethodId
     82   )
     83 {
     84   NULL_CHECK(CreateStruct);
     85 
     86   if (CreateStruct->ComPacket == NULL ||
     87       CreateStruct->CurPacket == NULL ||
     88       CreateStruct->CurSubPacket == NULL
     89      ) {
     90     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
     91     return (TcgResultFailureInvalidAction);
     92   }
     93 
     94   ERROR_CHECK(TcgAddCall(CreateStruct));
     95   ERROR_CHECK(TcgAddTcgUid(CreateStruct, InvokingId));
     96   ERROR_CHECK(TcgAddTcgUid(CreateStruct, MethodId));
     97 
     98   return TcgResultSuccess;
     99 }
    100 
    101 /**
    102   Adds START LIST token.
    103 
    104   @param    CreateStruct        The input create structure.
    105 
    106 **/
    107 TCG_RESULT
    108 EFIAPI
    109 TcgStartParameters(
    110   TCG_CREATE_STRUCT           *CreateStruct
    111   )
    112 {
    113   NULL_CHECK(CreateStruct);
    114 
    115   if (CreateStruct->ComPacket == NULL ||
    116       CreateStruct->CurPacket == NULL ||
    117       CreateStruct->CurSubPacket == NULL
    118      ) {
    119     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    120     return (TcgResultFailureInvalidAction);
    121   }
    122 
    123   return TcgAddStartList(CreateStruct);
    124 }
    125 
    126 /**
    127   Adds END LIST token.
    128 
    129   @param    CreateStruct        The input create structure.
    130 
    131 **/
    132 TCG_RESULT
    133 EFIAPI
    134 TcgEndParameters(
    135   TCG_CREATE_STRUCT   *CreateStruct
    136   )
    137 {
    138   NULL_CHECK(CreateStruct);
    139 
    140   if (CreateStruct->ComPacket == NULL ||
    141       CreateStruct->CurPacket == NULL ||
    142       CreateStruct->CurSubPacket == NULL
    143      ) {
    144     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    145     return (TcgResultFailureInvalidAction);
    146   }
    147 
    148   return TcgAddEndList(CreateStruct);
    149 }
    150 
    151 /**
    152   Adds END Data token and method list.
    153 
    154   @param    CreateStruct        The input create structure.
    155 
    156 **/
    157 TCG_RESULT
    158 EFIAPI
    159 TcgEndMethodCall(
    160   TCG_CREATE_STRUCT      *CreateStruct
    161   )
    162 {
    163   NULL_CHECK(CreateStruct);
    164 
    165   if (CreateStruct->ComPacket == NULL ||
    166       CreateStruct->CurPacket == NULL ||
    167       CreateStruct->CurSubPacket == NULL
    168      ) {
    169     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    170     return (TcgResultFailureInvalidAction);
    171   }
    172 
    173   ERROR_CHECK(TcgAddEndOfData(CreateStruct));
    174 
    175   ERROR_CHECK(TcgAddStartList(CreateStruct));
    176   ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // expected to complete properly
    177   ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // reserved
    178   ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // reserved
    179   ERROR_CHECK(TcgAddEndList(CreateStruct));
    180 
    181   return TcgResultSuccess;
    182 }
    183 
    184 /**
    185   Retrieves the comID and Extended comID of the ComPacket in the Tcg response.
    186   It is intended to be used to confirm the received Tcg response is intended for user that received it.
    187 
    188   @param [in]        ParseStruct        Structure used to parse received TCG response.
    189   @param [in/out]    ComId              comID retrieved from received ComPacket.
    190   @param [in/out]    ComIdExtension     Extended comID retrieved from received ComPacket
    191 
    192 **/
    193 TCG_RESULT
    194 EFIAPI
    195 TcgGetComIds(
    196   const TCG_PARSE_STRUCT     *ParseStruct,
    197   UINT16                     *ComId,
    198   UINT16                     *ComIdExtension
    199   )
    200 {
    201   NULL_CHECK(ParseStruct);
    202   NULL_CHECK(ComId);
    203   NULL_CHECK(ComIdExtension);
    204 
    205   if (ParseStruct->ComPacket == NULL) {
    206     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p\n", ParseStruct->ComPacket));
    207     return TcgResultFailureInvalidAction;
    208   }
    209 
    210   *ComId = SwapBytes16(ParseStruct->ComPacket->ComIDBE);
    211   *ComIdExtension = SwapBytes16(ParseStruct->ComPacket->ComIDExtensionBE);
    212 
    213   return TcgResultSuccess;
    214 }
    215 
    216 /**
    217   Checks if the ComIDs of the response match the expected values.
    218 
    219   @param[in]   ParseStruct               Structure used to parse received TCG response
    220   @param[in]   ExpectedComId             Expected comID
    221   @param[in]   ExpectedComIdExtension    Expected extended comID
    222 
    223 **/
    224 TCG_RESULT
    225 EFIAPI
    226 TcgCheckComIds(
    227   const TCG_PARSE_STRUCT     *ParseStruct,
    228   UINT16                     ExpectedComId,
    229   UINT16                     ExpectedComIdExtension
    230   )
    231 {
    232   UINT16 ParseComId;
    233   UINT16 ParseComIdExtension;
    234 
    235   ERROR_CHECK(TcgGetComIds(ParseStruct, &ParseComId, &ParseComIdExtension));
    236   if (ParseComId != ExpectedComId || ParseComIdExtension != ExpectedComIdExtension) {
    237     DEBUG ((DEBUG_INFO, "Com ID: Actual 0x%02X Expected 0x%02X\n", ParseComId, ExpectedComId));
    238     DEBUG ((DEBUG_INFO, "Extended Com ID: 0x%02X Expected 0x%02X\n", ParseComIdExtension, ExpectedComIdExtension));
    239     return TcgResultFailure;
    240   }
    241   return TcgResultSuccess;
    242 }
    243 
    244 /**
    245  Returns the method status of the current subpacket.  Does not affect the current position
    246  in the ComPacket.  In other words, it can be called whenever you have a valid SubPacket.
    247 
    248  @param [in/out]  ParseStruct       Structure used to parse received TCG response
    249  @param [in/out]  MethodStatus      Method status retrieved of the current SubPacket
    250 
    251 **/
    252 TCG_RESULT
    253 EFIAPI
    254 TcgGetMethodStatus(
    255   const TCG_PARSE_STRUCT            *ParseStruct,
    256   UINT8                             *MethodStatus
    257   )
    258 {
    259   TCG_PARSE_STRUCT TmpParseStruct;
    260   TCG_TOKEN TcgToken;
    261   UINT8 Reserved1, Reserved2;
    262 
    263   NULL_CHECK(ParseStruct);
    264   NULL_CHECK(MethodStatus);
    265 
    266   if (ParseStruct->ComPacket == NULL ||
    267       ParseStruct->CurPacket == NULL ||
    268       ParseStruct->CurSubPacket == NULL
    269      ) {
    270     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));
    271     return TcgResultFailureInvalidAction;
    272   }
    273 
    274   // duplicate ParseStruct, then don't need to "reset" location cur ptr
    275   CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));
    276 
    277   // method status list exists after the end method call in the subpacket
    278   // skip tokens until ENDDATA is found
    279   do {
    280     ERROR_CHECK(TcgGetNextToken(&TmpParseStruct, &TcgToken));
    281   } while (TcgToken.Type != TcgTokenTypeEndOfData);
    282 
    283   // only reach here if enddata is found
    284   // at this point, the curptr is pointing at method status list beginning
    285   ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));
    286   ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, MethodStatus));
    287   ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved1));
    288   ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved2));
    289   ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));
    290 
    291   if (Reserved1 != 0) {
    292     DEBUG ((DEBUG_INFO, "Method status reserved1 = 0x%02X (expected 0)\n", Reserved1));
    293     return TcgResultFailure;
    294   }
    295 
    296   if (Reserved2 != 0) {
    297     DEBUG ((DEBUG_INFO, "Method status reserved2 = 0x%02X (expected 0)\n", Reserved1));
    298     return TcgResultFailure;
    299   }
    300 
    301   return TcgResultSuccess;
    302 }
    303 
    304 /**
    305   Return the toke type string info.
    306 
    307   @param    Type       Input the type info.
    308 
    309   @retval   Return the string for this type.
    310 
    311 **/
    312 CHAR8*
    313 EFIAPI
    314 TcgTokenTypeString(
    315   TCG_TOKEN_TYPE  Type
    316   )
    317 {
    318   switch (Type) {
    319     case TcgTokenTypeReserved: return "Reserved";
    320     case TcgTokenTypeTinyAtom: return "Tiny Atom";
    321     case TcgTokenTypeShortAtom: return "Short Atom";
    322     case TcgTokenTypeMediumAtom: return "Medium Atom";
    323     case TcgTokenTypeLongAtom: return "Long Atom";
    324     case TcgTokenTypeStartList: return "Start List";
    325     case TcgTokenTypeEndList: return "End List";
    326     case TcgTokenTypeStartName: return "Start Name";
    327     case TcgTokenTypeEndName: return "End Name";
    328     case TcgTokenTypeCall: return "Call";
    329     case TcgTokenTypeEndOfData: return "End of Data";
    330     case TcgTokenTypeEndOfSession: return "End of Session";
    331     case TcgTokenTypeStartTransaction: return "Start Transaction";
    332     case TcgTokenTypeEndTransaction: return "End Transaction";
    333     case TcgTokenTypeEmptyAtom: return "Empty atom";
    334   }
    335   return "Unknown";
    336 }
    337 
    338 
    339 /**
    340 
    341   Adds Start Session call to the data structure.  This creates the entire ComPacket structure and
    342   returns the size of the entire compacket in the size parameter.
    343 
    344   @param [in/out]    CreateStruct               Structure used to add the start session call
    345   @param [in/out]    Size                       Describes the size of the entire ComPacket (header and payload). Filled out by function.
    346   @param [in]        ComId                      ComID for the ComPacket
    347   @param [in]        ComIdExtension             Extended ComID for the ComPacket
    348   @param [in]        HostSessionId              Host Session ID
    349   @param [in]        SpId                       Security Provider to start session with
    350   @param [in]        Write                      Write option for start session.  TRUE = start session requests write access
    351   @param [in]        HostChallengeLength        Length of the host challenge.  Length should be 0 if hostChallenge is NULL
    352   @param [in]        HostChallenge              Host challenge for Host Signing Authority.  If NULL, then no Host Challenge shall be sent.
    353   @param [in]        HostSigningAuthority       Host Signing Authority used for start session.  If NULL, then no Host Signing Authority shall be sent.
    354 
    355 **/
    356 TCG_RESULT
    357 EFIAPI
    358 TcgCreateStartSession(
    359   TCG_CREATE_STRUCT     *CreateStruct,
    360   UINT32                *Size,
    361   UINT16                ComId,
    362   UINT16                ComIdExtension,
    363   UINT32                HostSessionId,
    364   TCG_UID               SpId,
    365   BOOLEAN               Write,
    366   UINT32                HostChallengeLength,
    367   const VOID            *HostChallenge,
    368   TCG_UID               HostSigningAuthority
    369   )
    370 {
    371   ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
    372   ERROR_CHECK(TcgStartPacket(CreateStruct, 0x0, 0x0, 0x0, 0x0, 0x0)) ;
    373   ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
    374   ERROR_CHECK(TcgStartMethodCall(CreateStruct, TCG_UID_SMUID, TCG_UID_SM_START_SESSION));
    375   ERROR_CHECK(TcgStartParameters(CreateStruct));
    376   ERROR_CHECK(TcgAddUINT32(CreateStruct, HostSessionId));
    377   ERROR_CHECK(TcgAddTcgUid(CreateStruct, SpId));
    378   ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Write));
    379 
    380   // optional parameters
    381   if (HostChallenge != NULL && HostChallengeLength != 0) {
    382     ERROR_CHECK(TcgAddStartName(CreateStruct));
    383     ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   //TODO Create Enum for Method Optional Parameters?
    384     ERROR_CHECK(TcgAddByteSequence(CreateStruct, HostChallenge, HostChallengeLength, FALSE));
    385     ERROR_CHECK(TcgAddEndName(CreateStruct));
    386   }
    387   // optional parameters
    388   if (HostSigningAuthority != 0) {
    389     ERROR_CHECK(TcgAddStartName(CreateStruct));
    390     ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x03));   //TODO Create Enum for Method Optional Parameters?
    391     ERROR_CHECK(TcgAddTcgUid(CreateStruct, HostSigningAuthority));
    392     ERROR_CHECK(TcgAddEndName(CreateStruct));
    393   }
    394 
    395   ERROR_CHECK(TcgEndParameters(CreateStruct));
    396   ERROR_CHECK(TcgEndMethodCall(CreateStruct));
    397   ERROR_CHECK(TcgEndSubPacket(CreateStruct));
    398   ERROR_CHECK(TcgEndPacket(CreateStruct));
    399   ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
    400 
    401   return TcgResultSuccess;
    402 }
    403 
    404 /**
    405  Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID.  If the Sync Session response
    406  parameters do not match the comID, extended ComID and host session ID then a failure is returned.
    407 
    408  @param[in/out]   ParseStruct          Structure used to parse received TCG response, contains Sync Session response.
    409  @param[in]       ComId                Expected ComID that is compared to actual ComID of response
    410  @param[in]       ComIdExtension       Expected Extended ComID that is compared to actual Extended ComID of response
    411  @param[in]       HostSessionId        Expected Host Session ID that is compared to actual  Host Session ID of response
    412  @param[in/out]   TperSessionId        Tper Session ID retrieved from the Sync Session response.
    413 
    414 **/
    415 TCG_RESULT
    416 EFIAPI
    417 TcgParseSyncSession(
    418   const TCG_PARSE_STRUCT  *ParseStruct,
    419   UINT16                  ComId,
    420   UINT16                  ComIdExtension,
    421   UINT32                  HostSessionId,
    422   UINT32                  *TperSessionId
    423   )
    424 {
    425   UINT8 MethodStatus;
    426   TCG_PARSE_STRUCT TmpParseStruct;
    427   UINT16 ParseComId;
    428   UINT16 ParseExtComId;
    429   TCG_UID InvokingUID;
    430   TCG_UID MethodUID;
    431   UINT32 RecvHostSessionId;
    432 
    433   NULL_CHECK(ParseStruct);
    434   NULL_CHECK(TperSessionId);
    435 
    436   CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));
    437 
    438   // verify method status is good
    439   ERROR_CHECK(TcgGetMethodStatus(&TmpParseStruct, &MethodStatus));
    440   METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
    441 
    442   // verify comids
    443   ERROR_CHECK(TcgGetComIds(&TmpParseStruct, &ParseComId, &ParseExtComId));
    444 
    445   if ((ComId != ParseComId) || (ComIdExtension != ParseExtComId)) {
    446     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));
    447     return TcgResultFailure;
    448   }
    449   ERROR_CHECK(TcgGetNextCall(&TmpParseStruct));
    450   ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &InvokingUID));
    451   ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &MethodUID));
    452   ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));
    453   ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, &RecvHostSessionId));
    454   ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, TperSessionId));
    455   ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));
    456   ERROR_CHECK(TcgGetNextEndOfData(&TmpParseStruct));
    457 
    458   if (InvokingUID != TCG_UID_SMUID) {
    459     DEBUG ((DEBUG_INFO, "Invoking UID did not match UID_SMUID\n"));
    460     return TcgResultFailure;
    461   }
    462 
    463   if (MethodUID != TCG_UID_SM_SYNC_SESSION) {
    464     DEBUG ((DEBUG_INFO, "Method UID did not match UID_SM_SYNC_SESSION\n"));
    465     return TcgResultFailure;
    466   }
    467 
    468   if (HostSessionId != RecvHostSessionId) {
    469     DEBUG ((DEBUG_INFO, "unmatched HostSessionId (exp: 0x%X recv: 0x%X)\n", HostSessionId, RecvHostSessionId));
    470     return TcgResultFailure;
    471   }
    472 
    473   return TcgResultSuccess;
    474 }
    475 
    476 /**
    477 
    478   Creates ComPacket with EndSession.
    479   This assumes a start session has already been opened.
    480 
    481   @param  [in/out]    CreateStruct        Structure used to add Endsession
    482   @param  [in/out]    Size                Describes the size of the entire ComPacket (header and payload). Filled out by function.
    483   @param  [in]        ComId               ComID for the ComPacket
    484   @param  [in]        ComIdExtension      Extended ComID for the ComPacket
    485   @param  [in]        HostSessionId         Host Session ID for the Packet
    486   @param  [in]        TpSessionId         Tper Session ID for the Packet
    487 
    488 **/
    489 TCG_RESULT
    490 EFIAPI
    491 TcgCreateEndSession(
    492   TCG_CREATE_STRUCT   *CreateStruct,
    493   UINT32              *Size,
    494   UINT16              ComId,
    495   UINT16              ComIdExtension,
    496   UINT32              HostSessionId,
    497   UINT32              TpSessionId
    498   )
    499 {
    500   ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
    501   ERROR_CHECK(TcgStartPacket(CreateStruct, TpSessionId, HostSessionId, 0x0, 0x0, 0x0));
    502   ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
    503   ERROR_CHECK(TcgAddEndOfSession(CreateStruct));
    504   ERROR_CHECK(TcgEndSubPacket(CreateStruct));
    505   ERROR_CHECK(TcgEndPacket(CreateStruct));
    506   ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
    507 
    508   return TcgResultSuccess;
    509 }
    510 
    511 /**
    512   Set start method.
    513 
    514   @param     CreateStruct   Input create structure.
    515   @param     Row            Input the row info.
    516   @param     ColumnNumber   the column info.
    517 
    518 **/
    519 TCG_RESULT
    520 EFIAPI
    521 TcgStartMethodSet(
    522   TCG_CREATE_STRUCT        *CreateStruct,
    523   TCG_UID                  Row,
    524   UINT32                   ColumnNumber
    525   )
    526 {
    527   ERROR_CHECK(TcgStartMethodCall(CreateStruct, Row, TCG_UID_METHOD_SET));
    528   ERROR_CHECK(TcgStartParameters(CreateStruct));
    529   ERROR_CHECK(TcgAddStartName(CreateStruct));
    530   ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x01)); // "Values"
    531   ERROR_CHECK(TcgAddStartList(CreateStruct));
    532   ERROR_CHECK(TcgAddStartName(CreateStruct));
    533   ERROR_CHECK(TcgAddUINT32(CreateStruct, ColumnNumber));
    534   return TcgResultSuccess;
    535 }
    536 
    537 /**
    538   Set end method.
    539 
    540   @param     CreateStruct  Input create structure.
    541 
    542 **/
    543 TCG_RESULT
    544 EFIAPI
    545 TcgEndMethodSet(
    546   TCG_CREATE_STRUCT        *CreateStruct
    547   )
    548 {
    549   ERROR_CHECK(TcgAddEndName(CreateStruct));
    550   ERROR_CHECK(TcgAddEndList(CreateStruct));
    551   ERROR_CHECK(TcgAddEndName(CreateStruct));
    552   ERROR_CHECK(TcgEndParameters(CreateStruct));
    553   ERROR_CHECK(TcgEndMethodCall(CreateStruct));
    554   return TcgResultSuccess;
    555 }
    556 
    557 /**
    558   Creates ComPacket with a Method call that sets the PIN column for the row specified.
    559   This assumes a start session has already been opened with the desired SP.
    560 
    561   @param [in/out]   CreateStruct           Structure used to add method call.
    562   @param [in/out]   Size                   Describes the size of the entire ComPacket (header and payload). Filled out by function.
    563   @param [in]       ComId                  ComID for the ComPacket
    564   @param [in]       ComIdExtension         Extended ComID for the ComPacket
    565   @param [in]       TperSession            Tper Session ID for the Packet
    566   @param [in]       HostSession            Host Session ID for the Packet
    567   @param [in]       SidRow                 UID of row of current SP to set PIN column
    568   @param [in]       Password               value of PIN to set
    569   @param [in]       PasswordSize           Size of PIN
    570 
    571 **/
    572 TCG_RESULT
    573 EFIAPI
    574 TcgCreateSetCPin(
    575   TCG_CREATE_STRUCT       *CreateStruct,
    576   UINT32                  *Size,
    577   UINT16                  ComId,
    578   UINT16                  ComIdExtension,
    579   UINT32                  TperSession,
    580   UINT32                  HostSession,
    581   TCG_UID                 SidRow,
    582   const VOID              *Password,
    583   UINT32                  PasswordSize
    584   )
    585 {
    586   // set new SID Password
    587   ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
    588   ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
    589   ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
    590   ERROR_CHECK(TcgStartMethodSet(CreateStruct, SidRow, 0x03)); // "PIN"
    591   ERROR_CHECK(TcgAddByteSequence(CreateStruct, Password, PasswordSize, FALSE));
    592   ERROR_CHECK(TcgEndMethodSet(CreateStruct));
    593   ERROR_CHECK(TcgEndSubPacket(CreateStruct));
    594   ERROR_CHECK(TcgEndPacket(CreateStruct));
    595   ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
    596   return TcgResultSuccess;
    597 }
    598 
    599 /**
    600  Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.
    601  This assumes a start session has already been opened with the desired SP.
    602 
    603  @param [in/out]  CreateStruct          Structure used to add method call
    604  @param [in/out]  Size                  Describes the size of the entire ComPacket (header and payload). Filled out by function.
    605  @param [in]      ComId                 ComID for the ComPacket
    606  @param [in]      ComIdExtension        Extended ComID for the ComPacket
    607  @param [in]      TperSession           Tper Session ID for the Packet
    608  @param [in]      HostSession           Host Session ID for the Packet
    609  @param [in]      AuthorityUid          Authority UID to modify the "Enabled" column for
    610  @param [in]      Enabled               Value to set the "Enabled" column to
    611 
    612 **/
    613 TCG_RESULT
    614 EFIAPI
    615 TcgSetAuthorityEnabled(
    616   TCG_CREATE_STRUCT           *CreateStruct,
    617   UINT32                      *Size,
    618   UINT16                      ComId,
    619   UINT16                      ComIdExtension,
    620   UINT32                      TperSession,
    621   UINT32                      HostSession,
    622   TCG_UID                     AuthorityUid,
    623   BOOLEAN                     Enabled
    624   )
    625 {
    626   ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
    627   ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
    628   ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
    629   ERROR_CHECK(TcgStartMethodSet(CreateStruct, AuthorityUid, 0x05)); // "Enabled"
    630   ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Enabled));
    631   ERROR_CHECK(TcgEndMethodSet(CreateStruct));
    632   ERROR_CHECK(TcgEndSubPacket(CreateStruct));
    633   ERROR_CHECK(TcgEndPacket(CreateStruct));
    634   ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
    635   return TcgResultSuccess;
    636 }
    637 
    638 /**
    639   Create set ace.
    640 
    641   @param     CreateStruct      Input create structure.
    642   @param     Size              size info.
    643   @param     ComId             ComId info.
    644   @param     ComIdExtension    ComId extension info.
    645   @param     TperSession       Tper session data.
    646   @param     HostSession       Host session data.
    647   @param     AceRow            Ace row info.
    648   @param     Authority1        Authority 1 info.
    649   @param     LogicalOperator   Logiccal operator info.
    650   @param     Authority2        Authority 2 info.
    651 
    652   @retval    Return the action result.
    653 
    654 **/
    655 TCG_RESULT
    656 EFIAPI
    657 TcgCreateSetAce(
    658   TCG_CREATE_STRUCT        *CreateStruct,
    659   UINT32                   *Size,
    660   UINT16                   ComId,
    661   UINT16                   ComIdExtension,
    662   UINT32                   TperSession,
    663   UINT32                   HostSession,
    664   TCG_UID                  AceRow,
    665   TCG_UID                  Authority1,
    666   BOOLEAN                  LogicalOperator,
    667   TCG_UID                  Authority2
    668   )
    669 {
    670   UINT8 HalfUidAuthorityObjectRef[4];
    671   UINT8 HalfUidBooleanAce[4];
    672 
    673   HalfUidAuthorityObjectRef[0] = 0x0;
    674   HalfUidAuthorityObjectRef[1] = 0x0;
    675   HalfUidAuthorityObjectRef[2] = 0xC;
    676   HalfUidAuthorityObjectRef[3] = 0x5;
    677 
    678   HalfUidBooleanAce[0] = 0x0;
    679   HalfUidBooleanAce[1] = 0x0;
    680   HalfUidBooleanAce[2] = 0x4;
    681   HalfUidBooleanAce[3] = 0xE;
    682 
    683   ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));
    684   ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
    685   ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));
    686   ERROR_CHECK(TcgStartMethodSet(CreateStruct, AceRow, 0x03));     // "BooleanExpr"
    687   ERROR_CHECK(TcgAddStartList(CreateStruct));
    688   ERROR_CHECK(TcgAddStartName(CreateStruct));
    689   ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));
    690   ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority1));
    691   ERROR_CHECK(TcgAddEndName(CreateStruct));
    692   ERROR_CHECK(TcgAddStartName(CreateStruct));
    693   ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));
    694   ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority2));
    695   ERROR_CHECK(TcgAddEndName(CreateStruct));
    696 
    697   ERROR_CHECK(TcgAddStartName(CreateStruct));
    698   ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidBooleanAce, sizeof(HalfUidBooleanAce), FALSE));
    699   ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, LogicalOperator));
    700   ERROR_CHECK(TcgAddEndName(CreateStruct));
    701   ERROR_CHECK(TcgAddEndList(CreateStruct));
    702   ERROR_CHECK(TcgEndMethodSet(CreateStruct));
    703   ERROR_CHECK(TcgEndSubPacket(CreateStruct));
    704   ERROR_CHECK(TcgEndPacket(CreateStruct));
    705   ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));
    706   return TcgResultSuccess;
    707 }
    708 
    709 /**
    710   Enum level 0 discovery.
    711 
    712   @param     DiscoveryHeader   Discovery header.
    713   @param     Callback          Callback function.
    714   @param     Context           The context for the function.
    715 
    716   @retval    return true if the callback return TRUE, else return FALSE.
    717 
    718 **/
    719 BOOLEAN
    720 EFIAPI
    721 TcgEnumLevel0Discovery(
    722   const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,
    723   TCG_LEVEL0_ENUM_CALLBACK           Callback,
    724   VOID                               *Context
    725   )
    726 {
    727   UINT32                                  BytesLeft;
    728   const UINT8                             *DiscoveryBufferPtr;
    729   UINT32                                  FeatLength;
    730   TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER    *Feat;
    731 
    732   //
    733   // Total bytes including descriptors but not including the Length field
    734   //
    735   BytesLeft = SwapBytes32(DiscoveryHeader->LengthBE);
    736 
    737   //
    738   // If discovery Header is not valid, exit
    739   //
    740   if (BytesLeft == 0) {
    741     return FALSE;
    742   }
    743 
    744   //
    745   // Subtract the Length of the Header, except the Length field, which is not included
    746   //
    747   BytesLeft -= (sizeof(TCG_LEVEL0_DISCOVERY_HEADER) - sizeof(DiscoveryHeader->LengthBE));
    748 
    749   //
    750   // Move ptr to first descriptor
    751   //
    752   DiscoveryBufferPtr = (const UINT8*)DiscoveryHeader + sizeof(TCG_LEVEL0_DISCOVERY_HEADER);
    753 
    754   while (BytesLeft > sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER)) {
    755     //
    756     // Pointer to beginning of descriptor (including common Header)
    757     //
    758     Feat = (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*)DiscoveryBufferPtr;
    759 
    760     FeatLength = Feat->Length + sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER);
    761 
    762     //
    763     // Not enough bytes left for Feature descriptor
    764     //
    765     if (BytesLeft < FeatLength) {
    766       break;
    767     }
    768 
    769     //
    770     // Report the Feature to the callback
    771     //
    772     if (Callback(DiscoveryHeader, Feat, FeatLength, Context)) {
    773       return TRUE;
    774     }
    775 
    776     //
    777     // Descriptor Length only describes Data after common Header
    778     //
    779     BytesLeft -= FeatLength;
    780     DiscoveryBufferPtr += FeatLength;
    781   }
    782 
    783   return FALSE;
    784 }
    785 
    786 /**
    787   The callback function for Get Feature function.
    788 
    789   @param     DiscoveryHeader   Input discovery header.
    790   @param     Feature           Input Feature.
    791   @param     FeatureSize       Input Feature size.
    792   @param     Context           The context.
    793 
    794 **/
    795 BOOLEAN
    796 EFIAPI
    797 TcgFindFeatureCallback(
    798   const TCG_LEVEL0_DISCOVERY_HEADER           *DiscoveryHeader,
    799   TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER        *Feature,
    800   UINTN                                       FeatureSize,
    801   VOID                                        *Context
    802   )
    803 {
    804   TCG_FIND_FEATURE_CTX* FindCtx;
    805 
    806   FindCtx = (TCG_FIND_FEATURE_CTX*)Context;
    807   if ( SwapBytes16( Feature->FeatureCode_BE ) == FindCtx->FeatureCode ) {
    808     FindCtx->Feature = Feature;
    809     FindCtx->FeatureSize = FeatureSize;
    810     return TRUE; // done enumerating features
    811   }
    812   return FALSE; // continue enumerating
    813 }
    814 
    815 /**
    816   Get Feature code from the header.
    817 
    818   @param     DiscoveryHeader    The discovery header.
    819   @param     FeatureCode        reutrn the Feature code.
    820   @param     FeatureSize        return the Feature size.
    821 
    822   @retval    return the Feature code data.
    823 **/
    824 TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*
    825 EFIAPI
    826 TcgGetFeature(
    827   const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,
    828   UINT16                             FeatureCode,
    829   UINTN                              *FeatureSize
    830   )
    831 {
    832   TCG_FIND_FEATURE_CTX FindCtx;
    833 
    834   FindCtx.FeatureCode = FeatureCode;
    835   FindCtx.Feature = NULL;
    836   FindCtx.FeatureSize = 0;
    837 
    838   TcgEnumLevel0Discovery(DiscoveryHeader, TcgFindFeatureCallback, &FindCtx);
    839   if (FeatureSize != NULL) {
    840     *FeatureSize = FindCtx.FeatureSize;
    841   }
    842   return FindCtx.Feature;
    843 }
    844 
    845 /**
    846   Determines if the protocol provided is part of the provided supported protocol list.
    847 
    848   @param[in]  ProtocolList     Supported protocol list to investigate
    849   @param[in]  Protocol         Protocol value to determine if supported
    850 
    851   @return TRUE = protocol is supported, FALSE = protocol is not supported
    852 **/
    853 BOOLEAN
    854 EFIAPI
    855 TcgIsProtocolSupported(
    856   const TCG_SUPPORTED_SECURITY_PROTOCOLS   *ProtocolList,
    857   UINT16                                   Protocol
    858   )
    859 {
    860   UINT16 Index;
    861   UINT16 ListLength;
    862 
    863   ListLength = SwapBytes16(ProtocolList->ListLength_BE);
    864 
    865   if (ListLength > sizeof(ProtocolList->List)) {
    866     DEBUG ((DEBUG_INFO, "WARNING: list Length is larger than max allowed Value; truncating\n"));
    867     ListLength = sizeof(ProtocolList->List);
    868   }
    869 
    870   for (Index = 0; Index < ListLength; Index++) {
    871     if (ProtocolList->List[Index] == Protocol) {
    872       return TRUE;
    873     }
    874   }
    875 
    876   return FALSE;
    877 }
    878 
    879 /**
    880   Check whether lock or not.
    881 
    882   @param     Discovery
    883 
    884   @retval    TRUE if lock, FALSE if not lock.
    885 **/
    886 BOOLEAN
    887 EFIAPI
    888 TcgIsLocked(
    889   const TCG_LEVEL0_DISCOVERY_HEADER         *Discovery
    890   )
    891 {
    892   UINTN Size;
    893   TCG_LOCKING_FEATURE_DESCRIPTOR     *LockDescriptor;
    894 
    895   Size = 0;
    896   LockDescriptor =(TCG_LOCKING_FEATURE_DESCRIPTOR*) TcgGetFeature (Discovery, TCG_FEATURE_LOCKING, &Size);
    897 
    898   if (LockDescriptor != NULL && Size >= sizeof(*LockDescriptor)) {
    899     DEBUG ((DEBUG_INFO, "locked: %d\n", LockDescriptor->Locked));
    900     return LockDescriptor->Locked;
    901   }
    902 
    903   //
    904   // Descriptor was not found
    905   //
    906   return FALSE;
    907 }
    908