• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
TcgMethodStatusString(UINT8 MethodStatus)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
TcgStartMethodCall(TCG_CREATE_STRUCT * CreateStruct,TCG_UID InvokingId,TCG_UID MethodId)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
TcgStartParameters(TCG_CREATE_STRUCT * CreateStruct)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
TcgEndParameters(TCG_CREATE_STRUCT * CreateStruct)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
TcgEndMethodCall(TCG_CREATE_STRUCT * CreateStruct)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
TcgGetComIds(const TCG_PARSE_STRUCT * ParseStruct,UINT16 * ComId,UINT16 * ComIdExtension)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
TcgCheckComIds(const TCG_PARSE_STRUCT * ParseStruct,UINT16 ExpectedComId,UINT16 ExpectedComIdExtension)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
TcgGetMethodStatus(const TCG_PARSE_STRUCT * ParseStruct,UINT8 * MethodStatus)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
TcgTokenTypeString(TCG_TOKEN_TYPE Type)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
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)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
TcgParseSyncSession(const TCG_PARSE_STRUCT * ParseStruct,UINT16 ComId,UINT16 ComIdExtension,UINT32 HostSessionId,UINT32 * TperSessionId)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
TcgCreateEndSession(TCG_CREATE_STRUCT * CreateStruct,UINT32 * Size,UINT16 ComId,UINT16 ComIdExtension,UINT32 HostSessionId,UINT32 TpSessionId)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
TcgStartMethodSet(TCG_CREATE_STRUCT * CreateStruct,TCG_UID Row,UINT32 ColumnNumber)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
TcgEndMethodSet(TCG_CREATE_STRUCT * CreateStruct)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
TcgCreateSetCPin(TCG_CREATE_STRUCT * CreateStruct,UINT32 * Size,UINT16 ComId,UINT16 ComIdExtension,UINT32 TperSession,UINT32 HostSession,TCG_UID SidRow,const VOID * Password,UINT32 PasswordSize)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
TcgSetAuthorityEnabled(TCG_CREATE_STRUCT * CreateStruct,UINT32 * Size,UINT16 ComId,UINT16 ComIdExtension,UINT32 TperSession,UINT32 HostSession,TCG_UID AuthorityUid,BOOLEAN Enabled)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
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)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
TcgEnumLevel0Discovery(const TCG_LEVEL0_DISCOVERY_HEADER * DiscoveryHeader,TCG_LEVEL0_ENUM_CALLBACK Callback,VOID * Context)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
TcgFindFeatureCallback(const TCG_LEVEL0_DISCOVERY_HEADER * DiscoveryHeader,TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER * Feature,UINTN FeatureSize,VOID * Context)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
TcgGetFeature(const TCG_LEVEL0_DISCOVERY_HEADER * DiscoveryHeader,UINT16 FeatureCode,UINTN * FeatureSize)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
TcgIsProtocolSupported(const TCG_SUPPORTED_SECURITY_PROTOCOLS * ProtocolList,UINT16 Protocol)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
TcgIsLocked(const TCG_LEVEL0_DISCOVERY_HEADER * Discovery)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