TcgStorageUtil.c 30 KB

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