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