TcgStorageCore.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646
  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. //#include <Library/PrintLib.h>
  11. /**
  12. Required to be called before calling any other Tcg functions with the TCG_CREATE_STRUCT.
  13. Initializes the packet variables to NULL. Additionally, the buffer will be memset.
  14. @param [in/out] CreateStruct Structure to initialize
  15. @param [in] Buffer Buffer allocated by client of library. It will contain the Tcg encoded packet. This cannot be null.
  16. @param [in] BufferSize Size of buffer provided. It cannot be 0.
  17. @retval Return the action result.
  18. **/
  19. TCG_RESULT
  20. EFIAPI
  21. TcgInitTcgCreateStruct(
  22. TCG_CREATE_STRUCT *CreateStruct,
  23. VOID *Buffer,
  24. UINT32 BufferSize
  25. )
  26. {
  27. NULL_CHECK(CreateStruct);
  28. NULL_CHECK(Buffer);
  29. if (BufferSize == 0) {
  30. DEBUG ((DEBUG_INFO, "BufferSize=0\n"));
  31. return (TcgResultFailureZeroSize);
  32. }
  33. ZeroMem(Buffer, BufferSize);
  34. CreateStruct->BufferSize = BufferSize;
  35. CreateStruct->Buffer = Buffer;
  36. CreateStruct->ComPacket = NULL;
  37. CreateStruct->CurPacket = NULL;
  38. CreateStruct->CurSubPacket = NULL;
  39. return (TcgResultSuccess);
  40. }
  41. /**
  42. Encodes the ComPacket header to the data structure.
  43. @param[in/out] CreateStruct Structure to initialize
  44. @param[in] ComId ComID of the Tcg ComPacket.
  45. @param[in] ComIdExtension ComID Extension of the Tcg ComPacket.
  46. **/
  47. TCG_RESULT
  48. EFIAPI
  49. TcgStartComPacket(
  50. TCG_CREATE_STRUCT *CreateStruct,
  51. UINT16 ComId,
  52. UINT16 ComIdExtension
  53. )
  54. {
  55. NULL_CHECK(CreateStruct);
  56. if (CreateStruct->ComPacket != NULL ||
  57. CreateStruct->CurPacket != NULL ||
  58. CreateStruct->CurSubPacket != NULL
  59. ) {
  60. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket,
  61. CreateStruct->CurSubPacket));
  62. return (TcgResultFailureInvalidAction);
  63. }
  64. if (sizeof(TCG_COM_PACKET) > CreateStruct->BufferSize) {
  65. DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
  66. return (TcgResultFailureBufferTooSmall);
  67. }
  68. CreateStruct->ComPacket = (TCG_COM_PACKET*)CreateStruct->Buffer;
  69. CreateStruct->ComPacket->ComIDBE = SwapBytes16(ComId);
  70. CreateStruct->ComPacket->ComIDExtensionBE = SwapBytes16(ComIdExtension);
  71. return (TcgResultSuccess);
  72. }
  73. /**
  74. Starts a new ComPacket in the Data structure.
  75. @param [in/out] CreateStruct Structure used to add Tcg Packet
  76. @param[in] Tsn Packet Tper session number
  77. @param[in] Hsn Packet Host session number
  78. @param[in] SeqNumber Packet Sequence Number
  79. @param[in] AckType Packet Acknowledge Type
  80. @param[in] Ack Packet Acknowledge
  81. **/
  82. TCG_RESULT
  83. EFIAPI
  84. TcgStartPacket(
  85. TCG_CREATE_STRUCT *CreateStruct,
  86. UINT32 Tsn,
  87. UINT32 Hsn,
  88. UINT32 SeqNumber,
  89. UINT16 AckType,
  90. UINT32 Ack
  91. )
  92. {
  93. UINT32 AddedSize;
  94. NULL_CHECK(CreateStruct);
  95. AddedSize = 0;
  96. if (CreateStruct->ComPacket == NULL ||
  97. CreateStruct->CurPacket != NULL ||
  98. CreateStruct->CurSubPacket != NULL
  99. ) {
  100. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  101. return (TcgResultFailureInvalidAction);
  102. }
  103. // update TCG_COM_PACKET and packet lengths
  104. AddedSize = sizeof(TCG_PACKET);
  105. if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
  106. DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
  107. return (TcgResultFailureBufferTooSmall);
  108. }
  109. CreateStruct->CurPacket = (TCG_PACKET*)(CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE));
  110. CreateStruct->CurPacket->TperSessionNumberBE = SwapBytes32( Tsn );
  111. CreateStruct->CurPacket->HostSessionNumberBE = SwapBytes32( Hsn );
  112. CreateStruct->CurPacket->SequenceNumberBE = SwapBytes32( SeqNumber );
  113. CreateStruct->CurPacket->AckTypeBE = SwapBytes16( AckType );
  114. CreateStruct->CurPacket->AcknowledgementBE = SwapBytes32( Ack );
  115. CreateStruct->CurPacket->LengthBE = 0;
  116. // update TCG_COM_PACKET Length for next pointer
  117. CreateStruct->ComPacket->LengthBE = SwapBytes32( SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize );
  118. return (TcgResultSuccess);
  119. }
  120. /**
  121. Starts a new SubPacket in the Data structure.
  122. @param[in/out] CreateStruct Structure used to start Tcg SubPacket
  123. @param[in] Kind SubPacket kind
  124. **/
  125. TCG_RESULT
  126. EFIAPI
  127. TcgStartSubPacket(
  128. TCG_CREATE_STRUCT *CreateStruct,
  129. UINT16 Kind
  130. )
  131. {
  132. UINT32 AddedSize;
  133. NULL_CHECK(CreateStruct);
  134. AddedSize = 0;
  135. if (CreateStruct->ComPacket == NULL ||
  136. CreateStruct->CurPacket == NULL ||
  137. CreateStruct->CurSubPacket != NULL
  138. ) {
  139. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  140. return (TcgResultFailureInvalidAction);
  141. }
  142. AddedSize = sizeof(TCG_SUB_PACKET);
  143. if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
  144. DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
  145. return (TcgResultFailureBufferTooSmall);
  146. }
  147. CreateStruct->CurSubPacket = (TCG_SUB_PACKET*)(CreateStruct->CurPacket->Payload + SwapBytes32(CreateStruct->CurPacket->LengthBE));
  148. CreateStruct->CurSubPacket->KindBE = SwapBytes16(Kind);
  149. // update lengths
  150. CreateStruct->CurSubPacket->LengthBE = 0;
  151. // update TCG_COM_PACKET and packet lengths
  152. CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);
  153. CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);
  154. return (TcgResultSuccess);
  155. }
  156. /**
  157. Ends the current SubPacket in the Data structure. This function will also perform the 4-byte padding
  158. required for Subpackets.
  159. @param[in/out] CreateStruct Structure used to end the current Tcg SubPacket
  160. **/
  161. TCG_RESULT
  162. EFIAPI
  163. TcgEndSubPacket(
  164. TCG_CREATE_STRUCT *CreateStruct
  165. )
  166. {
  167. UINT32 PadSize;
  168. NULL_CHECK(CreateStruct);
  169. PadSize = 0;
  170. if (CreateStruct->ComPacket == NULL ||
  171. CreateStruct->CurPacket == NULL ||
  172. CreateStruct->CurSubPacket == NULL
  173. ) {
  174. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  175. return (TcgResultFailureInvalidAction);
  176. }
  177. // align to 4-byte boundaries, so shift padding
  178. // pad Size does not apply to subpacket Length
  179. PadSize = TCG_SUBPACKET_ALIGNMENT - (SwapBytes32(CreateStruct->CurSubPacket->LengthBE) & (TCG_SUBPACKET_ALIGNMENT - 1));
  180. if (PadSize == TCG_SUBPACKET_ALIGNMENT) {
  181. PadSize = 0;
  182. }
  183. if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize) > CreateStruct->BufferSize) {
  184. DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
  185. return (TcgResultFailureBufferTooSmall);
  186. }
  187. CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + PadSize);
  188. CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize);
  189. CreateStruct->CurSubPacket = NULL;
  190. return (TcgResultSuccess);
  191. }
  192. /**
  193. Ends the current Packet in the Data structure.
  194. @param[in/out] CreateStruct Structure used to end the current Tcg Packet
  195. **/
  196. TCG_RESULT
  197. EFIAPI
  198. TcgEndPacket(
  199. TCG_CREATE_STRUCT *CreateStruct
  200. )
  201. {
  202. NULL_CHECK(CreateStruct);
  203. if (CreateStruct->ComPacket == NULL ||
  204. CreateStruct->CurPacket == NULL ||
  205. CreateStruct->CurSubPacket != NULL
  206. ) {
  207. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  208. return (TcgResultFailureInvalidAction);
  209. }
  210. CreateStruct->CurPacket = NULL;
  211. return (TcgResultSuccess);
  212. }
  213. /**
  214. Ends the ComPacket in the Data structure and ret
  215. @param [in/out] CreateStruct Structure used to end the Tcg ComPacket
  216. @param [in/out] Size Describes the Size of the entire ComPacket (Header and payload). Filled out by function.
  217. **/
  218. TCG_RESULT
  219. EFIAPI
  220. TcgEndComPacket(
  221. TCG_CREATE_STRUCT *CreateStruct,
  222. UINT32 *Size
  223. )
  224. {
  225. NULL_CHECK(CreateStruct);
  226. NULL_CHECK(Size);
  227. if (CreateStruct->ComPacket == NULL ||
  228. CreateStruct->CurPacket != NULL ||
  229. CreateStruct->CurSubPacket != NULL
  230. ) {
  231. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  232. return (TcgResultFailureInvalidAction);
  233. }
  234. *Size = SwapBytes32(CreateStruct->ComPacket->LengthBE) + sizeof(*CreateStruct->ComPacket);
  235. CreateStruct->ComPacket = NULL;
  236. return (TcgResultSuccess);
  237. }
  238. /**
  239. Adds raw Data with optional Header
  240. @param CreateStruct The create structure.
  241. @param Header The header structure.
  242. @param HeaderSize The header size.
  243. @param Data The data need to add.
  244. @param DataSize The data size.
  245. @param ByteSwapData Whether byte or swap data.
  246. **/
  247. TCG_RESULT
  248. TcgAddRawTokenData(
  249. TCG_CREATE_STRUCT *CreateStruct,
  250. const VOID *Header,
  251. UINT8 HeaderSize,
  252. const VOID *Data,
  253. UINT32 DataSize,
  254. BOOLEAN ByteSwapData
  255. )
  256. {
  257. UINT32 AddedSize;
  258. UINT8* Dest;
  259. const UINT8* DataBytes;
  260. UINT32 Index;
  261. AddedSize = 0;
  262. Index = 0;
  263. Dest = NULL;
  264. NULL_CHECK(CreateStruct);
  265. if ((HeaderSize != 0 && Header == NULL) ||
  266. (DataSize != 0 && Data == NULL)
  267. ) {
  268. DEBUG ((DEBUG_INFO, "HeaderSize=0x%X Header=%p DataSize=0x%X Data=%p\n", HeaderSize, Header, DataSize, Data));
  269. return (TcgResultFailureNullPointer);
  270. }
  271. if (CreateStruct->ComPacket == NULL ||
  272. CreateStruct->CurPacket == NULL ||
  273. CreateStruct->CurSubPacket == NULL
  274. ) {
  275. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
  276. return (TcgResultFailureInvalidAction);
  277. }
  278. // verify there is enough Buffer Size
  279. AddedSize = HeaderSize + DataSize;
  280. if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
  281. return (TcgResultFailureBufferTooSmall);
  282. }
  283. // Get a pointer to where the new bytes should go
  284. Dest = CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE);
  285. switch (HeaderSize) {
  286. case sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM):
  287. case sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM):
  288. case sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM):
  289. CopyMem(Dest, Header, HeaderSize);
  290. Dest += HeaderSize;
  291. case 0: // no Header is valid
  292. break;
  293. // invalid Header Size
  294. default:
  295. DEBUG ((DEBUG_INFO, "unsupported HeaderSize=%u\n", HeaderSize));
  296. return TcgResultFailure;
  297. }
  298. // copy the Data bytes
  299. if (ByteSwapData) {
  300. DataBytes = (const UINT8*)Data;
  301. for (Index = 0; Index < DataSize; Index++) {
  302. Dest[Index] = DataBytes[DataSize - 1 - Index];
  303. }
  304. } else {
  305. CopyMem(Dest, Data, DataSize);
  306. }
  307. // Update all the packet sizes
  308. CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);
  309. CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);
  310. CreateStruct->CurSubPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurSubPacket->LengthBE) + AddedSize);
  311. return (TcgResultSuccess);
  312. }
  313. /**
  314. Adds a single raw token byte to the Data structure.
  315. @param[in/out] CreateStruct Structure used to add the byte
  316. @param[in] Byte Byte to add
  317. **/
  318. TCG_RESULT
  319. EFIAPI
  320. TcgAddRawByte(
  321. TCG_CREATE_STRUCT *CreateStruct,
  322. UINT8 Byte
  323. )
  324. {
  325. return TcgAddRawTokenData(CreateStruct, NULL, 0, &Byte, 1, FALSE);
  326. }
  327. /**
  328. simple tokens - atoms: tiny, short, medium, long and empty atoms.
  329. tiny atom can be a signed or unsigned integer.
  330. short, medium, long can be a signed or unsigned integer OR a complete or non-final byte sequence.
  331. @param CreateStruct The create structure.
  332. @param Data The data need to add.
  333. @param DataSize The data size.
  334. @param ByteOrInt, Data format is byte or int.
  335. @param SignOrCont sign or cont.
  336. **/
  337. TCG_RESULT
  338. TcgAddAtom(
  339. TCG_CREATE_STRUCT *CreateStruct,
  340. const VOID *Data,
  341. UINT32 DataSize,
  342. UINT8 ByteOrInt,
  343. UINT8 SignOrCont
  344. )
  345. {
  346. const UINT8* DataBytes;
  347. TCG_SIMPLE_TOKEN_TINY_ATOM TinyAtom;
  348. TCG_SIMPLE_TOKEN_SHORT_ATOM ShortAtom;
  349. TCG_SIMPLE_TOKEN_MEDIUM_ATOM MediumAtom;
  350. TCG_SIMPLE_TOKEN_LONG_ATOM LongAtom;
  351. NULL_CHECK(CreateStruct);
  352. if (DataSize == 0) {
  353. if (ByteOrInt == TCG_ATOM_TYPE_INTEGER) {
  354. DEBUG ((DEBUG_INFO, "0-Size integer not allowed\n"));
  355. return TcgResultFailure;
  356. }
  357. } else {
  358. // if DataSize != 0, Data must be valid
  359. NULL_CHECK(Data);
  360. }
  361. // encode Data using the shortest possible atom
  362. DataBytes = (const UINT8*)Data;
  363. if ((DataSize == 1) &&
  364. (ByteOrInt == TCG_ATOM_TYPE_INTEGER) &&
  365. ((SignOrCont != 0 && ((TCG_TOKEN_TINYATOM_SIGNED_MIN_VALUE <= *(INT8*)Data) && (*(INT8*)Data <= TCG_TOKEN_TINYATOM_SIGNED_MAX_VALUE))) ||
  366. (SignOrCont == 0 && ((*DataBytes <= TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE))))
  367. ) {
  368. TinyAtom.TinyAtomBits.IsZero = 0;
  369. TinyAtom.TinyAtomBits.Sign = SignOrCont;
  370. TinyAtom.TinyAtomBits.Data = *DataBytes & TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE;
  371. return TcgAddRawTokenData(CreateStruct, NULL, 0, (UINT8*)&TinyAtom, sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM), FALSE);
  372. }
  373. if (DataSize <= TCG_TOKEN_SHORTATOM_MAX_BYTE_SIZE) {
  374. ShortAtom.ShortAtomBits.IsOne = 1;
  375. ShortAtom.ShortAtomBits.IsZero = 0;
  376. ShortAtom.ShortAtomBits.ByteOrInt = ByteOrInt;
  377. ShortAtom.ShortAtomBits.SignOrCont = SignOrCont;
  378. ShortAtom.ShortAtomBits.Length = DataSize & 0x0F;
  379. return TcgAddRawTokenData(CreateStruct, &ShortAtom, sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
  380. }
  381. if (DataSize <= TCG_TOKEN_MEDIUMATOM_MAX_BYTE_SIZE) {
  382. MediumAtom.MediumAtomBits.IsOne1 = 1;
  383. MediumAtom.MediumAtomBits.IsOne2 = 1;
  384. MediumAtom.MediumAtomBits.IsZero = 0;
  385. MediumAtom.MediumAtomBits.ByteOrInt = ByteOrInt;
  386. MediumAtom.MediumAtomBits.SignOrCont = SignOrCont;
  387. MediumAtom.MediumAtomBits.LengthLow = DataSize & 0xFF;
  388. MediumAtom.MediumAtomBits.LengthHigh = (DataSize >> TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) & TCG_MEDIUM_ATOM_LENGTH_HIGH_MASK;
  389. return TcgAddRawTokenData(CreateStruct, &MediumAtom, sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
  390. }
  391. LongAtom.LongAtomBits.IsOne1 = 1;
  392. LongAtom.LongAtomBits.IsOne2 = 1;
  393. LongAtom.LongAtomBits.IsOne3 = 1;
  394. LongAtom.LongAtomBits.IsZero = 0;
  395. LongAtom.LongAtomBits.ByteOrInt = ByteOrInt;
  396. LongAtom.LongAtomBits.SignOrCont = SignOrCont;
  397. LongAtom.LongAtomBits.LengthLow = DataSize & 0xFF;
  398. LongAtom.LongAtomBits.LengthMid = (DataSize >> TCG_LONG_ATOM_LENGTH_MID_SHIFT) & 0xFF;
  399. LongAtom.LongAtomBits.LengthHigh = (DataSize >> TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) & 0xFF;
  400. return TcgAddRawTokenData(CreateStruct, &LongAtom, sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
  401. }
  402. /**
  403. Adds the Data parameter as a byte sequence to the Data structure.
  404. @param[in/out] CreateStruct Structure used to add the byte sequence
  405. @param[in] Data Byte sequence that will be encoded and copied into Data structure
  406. @param[in] DataSize Length of Data provided
  407. @param[in] Continued TRUE if byte sequence is continued or
  408. FALSE if the Data contains the entire byte sequence to be encoded
  409. **/
  410. TCG_RESULT
  411. EFIAPI
  412. TcgAddByteSequence(
  413. TCG_CREATE_STRUCT *CreateStruct,
  414. const VOID *Data,
  415. UINT32 DataSize,
  416. BOOLEAN Continued
  417. )
  418. {
  419. return TcgAddAtom(CreateStruct, Data, DataSize, TCG_ATOM_TYPE_BYTE, Continued ? 1 : 0);
  420. }
  421. /**
  422. Adds an arbitrary-Length integer to the Data structure.
  423. The integer will be encoded using the shortest possible atom.
  424. @param[in/out] CreateStruct Structure used to add the integer
  425. @param[in] Data Integer in host byte order that will be encoded and copied into Data structure
  426. @param[in] DataSize Length in bytes of the Data provided
  427. @param[in] SignedInteger TRUE if the integer is signed or FALSE if the integer is unsigned
  428. **/
  429. TCG_RESULT
  430. EFIAPI
  431. TcgAddInteger(
  432. TCG_CREATE_STRUCT *CreateStruct,
  433. const VOID *Data,
  434. UINT32 DataSize,
  435. BOOLEAN SignedInteger
  436. )
  437. {
  438. const UINT8* DataBytes;
  439. UINT32 ActualDataSize;
  440. BOOLEAN ValueIsNegative;
  441. NULL_CHECK(CreateStruct);
  442. NULL_CHECK(Data);
  443. if (DataSize == 0) {
  444. DEBUG ((DEBUG_INFO, "invalid DataSize=0\n"));
  445. return TcgResultFailure;
  446. }
  447. DataBytes = (const UINT8*)Data;
  448. // integer should be represented by smallest atom possible
  449. // so calculate real Data Size
  450. ValueIsNegative = SignedInteger && DataBytes[ DataSize - 1 ] & 0x80;
  451. // assumes native Data is little endian
  452. // shorten Data to smallest byte representation
  453. for (ActualDataSize = DataSize; ActualDataSize > 1; ActualDataSize--) {
  454. // ignore sign extended FFs
  455. if (ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0xFF)) {
  456. break;
  457. } else if (!ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0)) {
  458. // ignore extended 00s
  459. break;
  460. }
  461. }
  462. return TcgAddAtom(CreateStruct, Data, ActualDataSize, TCG_ATOM_TYPE_INTEGER, SignedInteger ? 1 : 0);
  463. }
  464. /**
  465. Adds an 8-bit unsigned integer to the Data structure.
  466. @param[in/out] CreateStruct Structure used to add the integer
  467. @param[in] Value Integer Value to add
  468. **/
  469. TCG_RESULT
  470. EFIAPI
  471. TcgAddUINT8(
  472. TCG_CREATE_STRUCT *CreateStruct,
  473. UINT8 Value
  474. )
  475. {
  476. return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
  477. }
  478. /**
  479. Adds a 16-bit unsigned integer to the Data structure.
  480. @param[in/out] CreateStruct Structure used to add the integer
  481. @param[in] Value Integer Value to add
  482. **/
  483. TCG_RESULT
  484. EFIAPI
  485. TcgAddUINT16 (
  486. TCG_CREATE_STRUCT *CreateStruct,
  487. UINT16 Value
  488. )
  489. {
  490. return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
  491. }
  492. /**
  493. Adds a 32-bit unsigned integer to the Data structure.
  494. @param[in/out] CreateStruct Structure used to add the integer
  495. @param[in] Value Integer Value to add
  496. **/
  497. TCG_RESULT
  498. EFIAPI
  499. TcgAddUINT32(
  500. TCG_CREATE_STRUCT *CreateStruct,
  501. UINT32 Value
  502. )
  503. {
  504. return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
  505. }
  506. /**
  507. Adds a 64-bit unsigned integer to the Data structure.
  508. @param[in/out] CreateStruct Structure used to add the integer
  509. @param[in] Value Integer Value to add
  510. **/
  511. TCG_RESULT
  512. EFIAPI
  513. TcgAddUINT64(
  514. TCG_CREATE_STRUCT *CreateStruct,
  515. UINT64 Value
  516. )
  517. {
  518. return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
  519. }
  520. /**
  521. Adds a BOOLEAN to the Data structure.
  522. @param[in/out] CreateStruct Structure used to add the integer
  523. @param[in] Value BOOLEAN Value to add
  524. **/
  525. TCG_RESULT
  526. EFIAPI
  527. TcgAddBOOLEAN(
  528. TCG_CREATE_STRUCT *CreateStruct,
  529. BOOLEAN Value
  530. )
  531. {
  532. return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
  533. }
  534. /**
  535. Add tcg uid info.
  536. @param [in/out] CreateStruct Structure used to add the integer
  537. @param Uid Input uid info.
  538. @retval return the action result.
  539. **/
  540. TCG_RESULT
  541. EFIAPI
  542. TcgAddTcgUid(
  543. TCG_CREATE_STRUCT *CreateStruct,
  544. TCG_UID Uid
  545. )
  546. {
  547. return TcgAddByteSequence(CreateStruct, &Uid, sizeof(TCG_UID), FALSE);
  548. }
  549. /**
  550. Add start list.
  551. @param [in/out] CreateStruct Structure used to add the integer
  552. @retval return the action result.
  553. **/
  554. TCG_RESULT
  555. EFIAPI
  556. TcgAddStartList(
  557. TCG_CREATE_STRUCT *CreateStruct
  558. )
  559. {
  560. return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTLIST);
  561. }
  562. /**
  563. Add end list.
  564. @param [in/out] CreateStruct Structure used to add the integer
  565. @retval return the action result.
  566. **/
  567. TCG_RESULT
  568. EFIAPI
  569. TcgAddEndList(
  570. TCG_CREATE_STRUCT *CreateStruct
  571. )
  572. {
  573. return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDLIST);
  574. }
  575. /**
  576. Add start name.
  577. @param [in/out] CreateStruct Structure used to add the integer
  578. @retval return the action result.
  579. **/
  580. TCG_RESULT
  581. EFIAPI
  582. TcgAddStartName(
  583. TCG_CREATE_STRUCT *CreateStruct
  584. )
  585. {
  586. return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTNAME);
  587. }
  588. /**
  589. Add end name.
  590. @param [in/out] CreateStruct Structure used to add the integer
  591. @retval return the action result.
  592. **/
  593. TCG_RESULT
  594. EFIAPI
  595. TcgAddEndName(
  596. TCG_CREATE_STRUCT *CreateStruct
  597. )
  598. {
  599. return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDNAME);
  600. }
  601. /**
  602. Add end call.
  603. @param [in/out] CreateStruct Structure used to add the integer
  604. @retval return the action result.
  605. **/
  606. TCG_RESULT
  607. EFIAPI
  608. TcgAddCall(
  609. TCG_CREATE_STRUCT *CreateStruct
  610. )
  611. {
  612. return TcgAddRawByte(CreateStruct, TCG_TOKEN_CALL);
  613. }
  614. /**
  615. Add end of data.
  616. @param [in/out] CreateStruct Structure used to add the integer
  617. @retval return the action result.
  618. **/
  619. TCG_RESULT
  620. EFIAPI
  621. TcgAddEndOfData(
  622. TCG_CREATE_STRUCT *CreateStruct
  623. )
  624. {
  625. return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDDATA);
  626. }
  627. /**
  628. Add end of session.
  629. @param [in/out] CreateStruct Structure used to add the integer
  630. @retval return the action result.
  631. **/
  632. TCG_RESULT
  633. EFIAPI
  634. TcgAddEndOfSession(
  635. TCG_CREATE_STRUCT *CreateStruct
  636. )
  637. {
  638. return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDSESSION);
  639. }
  640. /**
  641. Add start transaction.
  642. @param [in/out] CreateStruct Structure used to add the integer
  643. @retval return the action result.
  644. **/
  645. TCG_RESULT
  646. EFIAPI
  647. TcgAddStartTransaction(
  648. TCG_CREATE_STRUCT *CreateStruct
  649. )
  650. {
  651. return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTTRANSACTION);
  652. }
  653. /**
  654. Add end transaction.
  655. @param [in/out] CreateStruct Structure used to add the integer
  656. @retval return the action result.
  657. **/
  658. TCG_RESULT
  659. EFIAPI
  660. TcgAddEndTransaction(
  661. TCG_CREATE_STRUCT *CreateStruct
  662. )
  663. {
  664. return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDTRANSACTION);
  665. }
  666. /**
  667. Initial the tcg parse stucture.
  668. @param ParseStruct Input parse structure.
  669. @param Buffer Input buffer data.
  670. @param BufferSize Input buffer size.
  671. @retval return the action result.
  672. **/
  673. TCG_RESULT
  674. EFIAPI
  675. TcgInitTcgParseStruct(
  676. TCG_PARSE_STRUCT *ParseStruct,
  677. const VOID *Buffer,
  678. UINT32 BufferSize
  679. )
  680. {
  681. UINT32 ComPacketLength;
  682. UINT32 PacketLength;
  683. NULL_CHECK(ParseStruct);
  684. NULL_CHECK(Buffer);
  685. if (BufferSize < sizeof(TCG_COM_PACKET)) {
  686. return (TcgResultFailureBufferTooSmall);
  687. }
  688. ParseStruct->ComPacket = (TCG_COM_PACKET*)Buffer;
  689. ComPacketLength = SwapBytes32(ParseStruct->ComPacket->LengthBE);
  690. if ((BufferSize - sizeof(TCG_COM_PACKET)) < ComPacketLength) {
  691. DEBUG ((DEBUG_INFO, "Buffer %u too small for ComPacket %u\n", BufferSize, ComPacketLength));
  692. return (TcgResultFailureBufferTooSmall);
  693. }
  694. ParseStruct->BufferSize = BufferSize;
  695. ParseStruct->Buffer = Buffer;
  696. ParseStruct->CurPacket = NULL;
  697. ParseStruct->CurSubPacket = NULL;
  698. ParseStruct->CurPtr = NULL;
  699. // if payload > 0, then must have a packet
  700. if (ComPacketLength != 0) {
  701. if (ComPacketLength < sizeof(TCG_PACKET)) {
  702. DEBUG ((DEBUG_INFO, "ComPacket too small for Packet\n"));
  703. return (TcgResultFailureBufferTooSmall);
  704. }
  705. ParseStruct->CurPacket = (TCG_PACKET*)ParseStruct->ComPacket->Payload;
  706. PacketLength = SwapBytes32(ParseStruct->CurPacket->LengthBE);
  707. if (PacketLength > 0) {
  708. if (PacketLength < sizeof(TCG_SUB_PACKET)) {
  709. DEBUG ((DEBUG_INFO, "Packet too small for SubPacket\n"));
  710. return (TcgResultFailureBufferTooSmall);
  711. }
  712. ParseStruct->CurSubPacket = (TCG_SUB_PACKET*)ParseStruct->CurPacket->Payload;
  713. }
  714. }
  715. //TODO should check for method status list at this point?
  716. return (TcgResultSuccess);
  717. }
  718. /**
  719. Get next token info.
  720. @param ParseStruct Input parse structure info.
  721. @param TcgToken return the tcg token info.
  722. @retval return the action result.
  723. **/
  724. TCG_RESULT
  725. EFIAPI
  726. TcgGetNextToken(
  727. TCG_PARSE_STRUCT *ParseStruct,
  728. TCG_TOKEN *TcgToken
  729. )
  730. {
  731. const UINT8* EndOfSubPacket;
  732. UINT8* TokenEnd;
  733. UINT8 Hdr;
  734. TCG_SIMPLE_TOKEN_SHORT_ATOM* TmpShort;
  735. const TCG_SIMPLE_TOKEN_MEDIUM_ATOM* TmpMed;
  736. const TCG_SIMPLE_TOKEN_LONG_ATOM* TmpLong;
  737. NULL_CHECK(ParseStruct);
  738. NULL_CHECK(TcgToken);
  739. if (ParseStruct->ComPacket == NULL ||
  740. ParseStruct->CurPacket == NULL ||
  741. ParseStruct->CurSubPacket == NULL
  742. ) {
  743. DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));
  744. return TcgResultFailureInvalidAction;
  745. }
  746. // initial call, start at sub packet
  747. if (ParseStruct->CurPtr == NULL) {
  748. ParseStruct->CurPtr = ParseStruct->CurSubPacket->Payload;
  749. }
  750. EndOfSubPacket = ParseStruct->CurSubPacket->Payload + SwapBytes32(ParseStruct->CurSubPacket->LengthBE);
  751. TokenEnd = NULL;
  752. // confirmed that subpacket Length falls within end of Buffer and TCG_COM_PACKET,
  753. // so simply need to verify the loop stays within current subpacket
  754. if (ParseStruct->CurPtr >= EndOfSubPacket) {
  755. DEBUG ((DEBUG_INFO, "ParseStruct->CurPtr >= EndOfSubPacket\n"));
  756. return (TcgResultFailureEndBuffer);
  757. }
  758. Hdr = *ParseStruct->CurPtr;
  759. TcgToken->HdrStart = ParseStruct->CurPtr;
  760. // Tiny Atom range
  761. if (Hdr <= 0x7F) {
  762. // tiny atom Header is only 1 byte, so don't need to verify Size before cast and access
  763. TcgToken->Type = TcgTokenTypeTinyAtom;
  764. TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM);
  765. // verify caller will have enough Size to reference token
  766. if (TokenEnd >= EndOfSubPacket) {
  767. DEBUG ((DEBUG_INFO, "Tiny Atom TokenEnd >= EndOfSubPacket\n"));
  768. return (TcgResultFailureEndBuffer);
  769. }
  770. }
  771. // Short Atom Range
  772. else if (0x80 <= Hdr && Hdr <= 0xBF) {
  773. // short atom Header is only 1 byte, so don't need to verify Size before cast and access
  774. TmpShort = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)(ParseStruct->CurPtr);
  775. TcgToken->Type = TcgTokenTypeShortAtom;
  776. TokenEnd = (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM) + TmpShort->ShortAtomBits.Length);
  777. // verify caller will have enough Size to reference token
  778. if (TokenEnd >= EndOfSubPacket) {
  779. DEBUG ((DEBUG_INFO, "Short Atom TokenEnd >= EndOfSubPacket\n"));
  780. return (TcgResultFailureEndBuffer);
  781. }
  782. }
  783. // Medium Atom Range
  784. else if (0xC0 <= Hdr && Hdr <= 0xDF) {
  785. if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) >= EndOfSubPacket) {
  786. return (TcgResultFailureEndBuffer);
  787. }
  788. TmpMed = (const TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)ParseStruct->CurPtr;
  789. TcgToken->Type = TcgTokenTypeMediumAtom;
  790. TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) +
  791. ((TmpMed->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) |
  792. TmpMed->MediumAtomBits.LengthLow);
  793. // verify caller will have enough Size to reference token
  794. if (TokenEnd >= EndOfSubPacket) {
  795. DEBUG ((DEBUG_INFO, "Medium Atom TokenEnd >= EndOfSubPacket\n"));
  796. return (TcgResultFailureEndBuffer);
  797. }
  798. }
  799. // Long Atom Range
  800. else if (0xE0 <= Hdr && Hdr <= 0xE3) {
  801. if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) >= EndOfSubPacket) {
  802. return (TcgResultFailureEndBuffer);
  803. }
  804. TmpLong = (const TCG_SIMPLE_TOKEN_LONG_ATOM*)ParseStruct->CurPtr;
  805. TcgToken->Type = TcgTokenTypeLongAtom;
  806. TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) +
  807. ((TmpLong->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |
  808. (TmpLong->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) |
  809. TmpLong->LongAtomBits.LengthLow);
  810. // verify caller will have enough Size to reference token
  811. if (TokenEnd >= EndOfSubPacket) {
  812. DEBUG ((DEBUG_INFO, "Long Atom TokenEnd >= EndOfSubPacket\n"));
  813. return (TcgResultFailureEndBuffer);
  814. }
  815. } else {
  816. // single byte tokens
  817. switch (Hdr) {
  818. case TCG_TOKEN_STARTLIST:
  819. TcgToken->Type = TcgTokenTypeStartList;
  820. break;
  821. case TCG_TOKEN_ENDLIST:
  822. TcgToken->Type = TcgTokenTypeEndList;
  823. break;
  824. case TCG_TOKEN_STARTNAME:
  825. TcgToken->Type = TcgTokenTypeStartName;
  826. break;
  827. case TCG_TOKEN_ENDNAME:
  828. TcgToken->Type = TcgTokenTypeEndName;
  829. break;
  830. case TCG_TOKEN_CALL:
  831. TcgToken->Type = TcgTokenTypeCall;
  832. break;
  833. case TCG_TOKEN_ENDDATA:
  834. TcgToken->Type = TcgTokenTypeEndOfData;
  835. break;
  836. case TCG_TOKEN_ENDSESSION:
  837. TcgToken->Type = TcgTokenTypeEndOfSession;
  838. break;
  839. case TCG_TOKEN_STARTTRANSACTION:
  840. TcgToken->Type = TcgTokenTypeStartTransaction;
  841. break;
  842. case TCG_TOKEN_ENDTRANSACTION:
  843. TcgToken->Type = TcgTokenTypeEndTransaction;
  844. break;
  845. case TCG_TOKEN_EMPTY:
  846. TcgToken->Type = TcgTokenTypeEmptyAtom;
  847. break;
  848. default:
  849. DEBUG ((DEBUG_INFO, "WARNING: reserved token Type 0x%02X\n", Hdr));
  850. TcgToken->Type = TcgTokenTypeReserved;
  851. break;
  852. }
  853. ParseStruct->CurPtr++;
  854. TokenEnd = TcgToken->HdrStart + 1;
  855. }
  856. // increment curptr for next call
  857. ParseStruct->CurPtr = TokenEnd;
  858. return (TcgResultSuccess);
  859. }
  860. /**
  861. Get atom info.
  862. @param TcgToken Input token info.
  863. @param HeaderLength return the header length.
  864. @param DataLength return the data length.
  865. @param ByteOrInt return the atom Type.
  866. @param SignOrCont return the sign or count info.
  867. @retval return the action result.
  868. **/
  869. TCG_RESULT
  870. EFIAPI
  871. TcgGetAtomInfo(
  872. const TCG_TOKEN *TcgToken,
  873. UINT32 *HeaderLength,
  874. UINT32 *DataLength,
  875. UINT8 *ByteOrInt,
  876. UINT8 *SignOrCont
  877. )
  878. {
  879. TCG_SIMPLE_TOKEN_TINY_ATOM* TinyAtom;
  880. TCG_SIMPLE_TOKEN_SHORT_ATOM* ShortAtom;
  881. TCG_SIMPLE_TOKEN_MEDIUM_ATOM* MediumAtom;
  882. TCG_SIMPLE_TOKEN_LONG_ATOM* LongAtom;
  883. NULL_CHECK(TcgToken);
  884. NULL_CHECK(HeaderLength);
  885. NULL_CHECK(DataLength);
  886. NULL_CHECK(ByteOrInt);
  887. NULL_CHECK(SignOrCont);
  888. switch (TcgToken->Type) {
  889. case TcgTokenTypeTinyAtom: {
  890. TinyAtom = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;
  891. *ByteOrInt = TCG_ATOM_TYPE_INTEGER;
  892. *SignOrCont = TinyAtom->TinyAtomBits.Sign;
  893. *HeaderLength = 0;
  894. *DataLength = 0; // tiny atom must be handled as a special case - Header and Data in the same byte
  895. return TcgResultSuccess;
  896. }
  897. case TcgTokenTypeShortAtom: {
  898. ShortAtom = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)TcgToken->HdrStart;
  899. *ByteOrInt = ShortAtom->ShortAtomBits.ByteOrInt;
  900. *SignOrCont = ShortAtom->ShortAtomBits.SignOrCont;
  901. *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM);
  902. *DataLength = ShortAtom->ShortAtomBits.Length;
  903. return TcgResultSuccess;
  904. }
  905. case TcgTokenTypeMediumAtom: {
  906. MediumAtom = (TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)TcgToken->HdrStart;
  907. *ByteOrInt = MediumAtom->MediumAtomBits.ByteOrInt;
  908. *SignOrCont = MediumAtom->MediumAtomBits.SignOrCont;
  909. *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM);
  910. *DataLength = (MediumAtom->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) | MediumAtom->MediumAtomBits.LengthLow;
  911. return TcgResultSuccess;
  912. }
  913. case TcgTokenTypeLongAtom: {
  914. LongAtom = (TCG_SIMPLE_TOKEN_LONG_ATOM*)TcgToken->HdrStart;
  915. *ByteOrInt = LongAtom->LongAtomBits.ByteOrInt;
  916. *SignOrCont = LongAtom->LongAtomBits.SignOrCont;
  917. *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM);
  918. *DataLength = (LongAtom->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |
  919. (LongAtom->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) |
  920. LongAtom->LongAtomBits.LengthLow;
  921. return TcgResultSuccess;
  922. }
  923. default:
  924. DEBUG ((DEBUG_INFO, "Token Type is not simple atom (%d)\n", TcgToken->Type));
  925. return (TcgResultFailureInvalidType);
  926. }
  927. }
  928. /**
  929. Get token specified value.
  930. @param TcgToken Input token info.
  931. @param Value return the value.
  932. @retval return the action result.
  933. **/
  934. TCG_RESULT
  935. EFIAPI
  936. TcgGetTokenUINT64(
  937. const TCG_TOKEN *TcgToken,
  938. UINT64 *Value
  939. )
  940. {
  941. UINT32 HdrLength;
  942. UINT32 DataLength;
  943. UINT8 ByteOrInt;
  944. UINT8 IsSigned;
  945. TCG_SIMPLE_TOKEN_TINY_ATOM* TmpTiny;
  946. const UINT8* Data;
  947. UINT32 Index;
  948. NULL_CHECK(TcgToken);
  949. NULL_CHECK(Value);
  950. Index = 0;
  951. *Value = 0;
  952. ERROR_CHECK(TcgGetAtomInfo(TcgToken, &HdrLength, &DataLength, &ByteOrInt, &IsSigned));
  953. if (ByteOrInt != TCG_ATOM_TYPE_INTEGER) {
  954. DEBUG ((DEBUG_INFO, "Invalid Type, expected integer not byte sequence\n"));
  955. return TcgResultFailureInvalidType;
  956. }
  957. if (IsSigned != 0) {
  958. DEBUG ((DEBUG_INFO, "Integer is signed, expected unsigned\n"));
  959. return TcgResultFailureInvalidType;
  960. }
  961. // special case for tiny atom
  962. // Header and Data are in one byte, so extract only the Data bitfield
  963. if (TcgToken->Type == TcgTokenTypeTinyAtom) {
  964. TmpTiny = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;
  965. *Value = TmpTiny->TinyAtomBits.Data;
  966. return TcgResultSuccess;
  967. }
  968. if (DataLength > sizeof(UINT64)) {
  969. DEBUG ((DEBUG_INFO, "Length %d is greater than Size of UINT64\n", DataLength));
  970. return TcgResultFailureBufferTooSmall;
  971. }
  972. // read big-endian integer
  973. Data = TcgToken->HdrStart + HdrLength;
  974. for (Index = 0; Index < DataLength; Index++) {
  975. *Value = LShiftU64(*Value, 8) | Data[Index];
  976. }
  977. return TcgResultSuccess;
  978. }
  979. /**
  980. Get token byte sequence.
  981. @param TcgToken Input token info.
  982. @param Length Input the length info.
  983. @retval Return the value data.
  984. **/
  985. UINT8*
  986. EFIAPI
  987. TcgGetTokenByteSequence(
  988. const TCG_TOKEN *TcgToken,
  989. UINT32 *Length
  990. )
  991. {
  992. UINT32 HdrLength;
  993. UINT8 ByteOrInt;
  994. UINT8 SignOrCont;
  995. if (TcgToken == NULL || Length == NULL) {
  996. return NULL;
  997. }
  998. *Length = 0;
  999. if (TcgGetAtomInfo(TcgToken, &HdrLength, Length, &ByteOrInt, &SignOrCont) != TcgResultSuccess) {
  1000. DEBUG ((DEBUG_INFO, "Failed to get simple token info\n"));
  1001. return NULL;
  1002. }
  1003. if (ByteOrInt != TCG_ATOM_TYPE_BYTE) {
  1004. DEBUG ((DEBUG_INFO, "Invalid Type, expected byte sequence not integer\n"));
  1005. return NULL;
  1006. }
  1007. return (TcgToken->HdrStart + HdrLength);
  1008. }
  1009. /**
  1010. Get next specify value.
  1011. @param ParseStruct Input parse structure.
  1012. @param Value Return value.
  1013. @retval return the action result.
  1014. **/
  1015. TCG_RESULT
  1016. EFIAPI
  1017. TcgGetNextUINT8(
  1018. TCG_PARSE_STRUCT *ParseStruct,
  1019. UINT8 *Value
  1020. )
  1021. {
  1022. UINT64 Value64;
  1023. TCG_TOKEN Tok;
  1024. NULL_CHECK(Value);
  1025. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1026. ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
  1027. if (Value64 > MAX_UINT8) {
  1028. return TcgResultFailure;
  1029. }
  1030. *Value = (UINT8)Value64;
  1031. return TcgResultSuccess;
  1032. }
  1033. /**
  1034. Get next specify value.
  1035. @param ParseStruct Input parse structure.
  1036. @param Value Return value.
  1037. @retval return the action result.
  1038. **/
  1039. TCG_RESULT
  1040. EFIAPI
  1041. TcgGetNextUINT16(
  1042. TCG_PARSE_STRUCT *ParseStruct,
  1043. UINT16 *Value
  1044. )
  1045. {
  1046. UINT64 Value64;
  1047. TCG_TOKEN Tok;
  1048. NULL_CHECK(Value);
  1049. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1050. ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
  1051. if (Value64 > MAX_UINT16) {
  1052. return TcgResultFailure;
  1053. }
  1054. *Value = (UINT16)Value64;
  1055. return TcgResultSuccess;
  1056. }
  1057. /**
  1058. Get next specify value.
  1059. @param ParseStruct Input parse structure.
  1060. @param Value Return value.
  1061. @retval return the action result.
  1062. **/
  1063. TCG_RESULT
  1064. EFIAPI
  1065. TcgGetNextUINT32(
  1066. TCG_PARSE_STRUCT *ParseStruct,
  1067. UINT32 *Value
  1068. )
  1069. {
  1070. UINT64 Value64;
  1071. TCG_TOKEN Tok;
  1072. NULL_CHECK(Value);
  1073. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1074. ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
  1075. if (Value64 > MAX_UINT32) {
  1076. return TcgResultFailure;
  1077. }
  1078. *Value = (UINT32)Value64;
  1079. return TcgResultSuccess;
  1080. }
  1081. /**
  1082. Get next specify value.
  1083. @param ParseStruct Input parse structure.
  1084. @param Value Return value.
  1085. @retval return the action result.
  1086. **/
  1087. TCG_RESULT
  1088. EFIAPI
  1089. TcgGetNextUINT64(
  1090. TCG_PARSE_STRUCT *ParseStruct,
  1091. UINT64 *Value
  1092. )
  1093. {
  1094. TCG_TOKEN Tok;
  1095. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1096. ERROR_CHECK(TcgGetTokenUINT64(&Tok, Value));
  1097. return TcgResultSuccess;
  1098. }
  1099. /**
  1100. Get next specify value.
  1101. @param ParseStruct Input parse structure.
  1102. @param Value Return value.
  1103. @retval return the action result.
  1104. **/
  1105. TCG_RESULT
  1106. EFIAPI
  1107. TcgGetNextBOOLEAN(
  1108. TCG_PARSE_STRUCT *ParseStruct,
  1109. BOOLEAN *Value
  1110. )
  1111. {
  1112. UINT64 Value64;
  1113. TCG_TOKEN Tok;
  1114. NULL_CHECK(Value);
  1115. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1116. ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
  1117. if (Value64 > 1) {
  1118. return TcgResultFailure;
  1119. }
  1120. *Value = (BOOLEAN)Value64;
  1121. return TcgResultSuccess;
  1122. }
  1123. /**
  1124. Get next tcg uid info.
  1125. @param ParseStruct Input parse structure.
  1126. @param Uid Get the uid info.
  1127. @retval return the action result.
  1128. **/
  1129. TCG_RESULT
  1130. EFIAPI
  1131. TcgGetNextTcgUid(
  1132. TCG_PARSE_STRUCT *ParseStruct,
  1133. TCG_UID *Uid
  1134. )
  1135. {
  1136. TCG_TOKEN Tok;
  1137. UINT32 Length;
  1138. const UINT8* ByteSeq;
  1139. NULL_CHECK(Uid);
  1140. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1141. ByteSeq = TcgGetTokenByteSequence(&Tok, &Length);
  1142. if (Length != sizeof(TCG_UID)) {
  1143. DEBUG ((DEBUG_INFO, "Token Length %u != TCG_UID Size %u\n", Length, (UINT32)sizeof(TCG_UID)));
  1144. return TcgResultFailure;
  1145. }
  1146. ASSERT (ByteSeq != NULL);
  1147. CopyMem(Uid, ByteSeq, sizeof(TCG_UID));
  1148. return TcgResultSuccess;
  1149. }
  1150. /**
  1151. Get next byte sequence.
  1152. @param ParseStruct Input parse structure.
  1153. @param Data return the data.
  1154. @param Length return the length.
  1155. @retval return the action result.
  1156. **/
  1157. TCG_RESULT
  1158. EFIAPI
  1159. TcgGetNextByteSequence(
  1160. TCG_PARSE_STRUCT *ParseStruct,
  1161. const VOID **Data,
  1162. UINT32 *Length
  1163. )
  1164. {
  1165. TCG_TOKEN Tok;
  1166. const UINT8* Bs;
  1167. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1168. Bs = TcgGetTokenByteSequence(&Tok, Length);
  1169. if (Bs == NULL) {
  1170. return TcgResultFailure;
  1171. }
  1172. *Data = Bs;
  1173. return TcgResultSuccess;
  1174. }
  1175. /**
  1176. Get next token Type.
  1177. @param ParseStruct Input parse structure.
  1178. @param Type Input the type need to check.
  1179. @retval return the action result.
  1180. **/
  1181. TCG_RESULT
  1182. EFIAPI
  1183. TcgGetNextTokenType(
  1184. TCG_PARSE_STRUCT *ParseStruct,
  1185. TCG_TOKEN_TYPE Type
  1186. )
  1187. {
  1188. TCG_TOKEN Tok;
  1189. ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
  1190. if (Tok.Type != Type) {
  1191. DEBUG ((DEBUG_INFO, "expected Type %u, got Type %u\n", Type, Tok.Type));
  1192. return TcgResultFailure;
  1193. }
  1194. return TcgResultSuccess;
  1195. }
  1196. /**
  1197. Get next start list.
  1198. @param ParseStruct Input parse structure.
  1199. @retval return the action result.
  1200. **/
  1201. TCG_RESULT
  1202. EFIAPI
  1203. TcgGetNextStartList(
  1204. TCG_PARSE_STRUCT *ParseStruct
  1205. )
  1206. {
  1207. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartList);
  1208. }
  1209. /**
  1210. Get next end list.
  1211. @param ParseStruct Input parse structure.
  1212. @retval return the action result.
  1213. **/
  1214. TCG_RESULT
  1215. EFIAPI
  1216. TcgGetNextEndList(
  1217. TCG_PARSE_STRUCT *ParseStruct
  1218. )
  1219. {
  1220. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndList);
  1221. }
  1222. /**
  1223. Get next start name.
  1224. @param ParseStruct Input parse structure.
  1225. @retval return the action result.
  1226. **/
  1227. TCG_RESULT
  1228. EFIAPI
  1229. TcgGetNextStartName(
  1230. TCG_PARSE_STRUCT *ParseStruct
  1231. )
  1232. {
  1233. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartName);
  1234. }
  1235. /**
  1236. Get next end name.
  1237. @param ParseStruct Input parse structure.
  1238. @retval return the action result.
  1239. **/
  1240. TCG_RESULT
  1241. EFIAPI
  1242. TcgGetNextEndName(
  1243. TCG_PARSE_STRUCT *ParseStruct
  1244. )
  1245. {
  1246. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndName);
  1247. }
  1248. /**
  1249. Get next call.
  1250. @param ParseStruct Input parse structure.
  1251. @retval return the action result.
  1252. **/
  1253. TCG_RESULT
  1254. EFIAPI
  1255. TcgGetNextCall(
  1256. TCG_PARSE_STRUCT *ParseStruct
  1257. )
  1258. {
  1259. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeCall);
  1260. }
  1261. /**
  1262. Get next end data.
  1263. @param ParseStruct Input parse structure.
  1264. @retval return the action result.
  1265. **/
  1266. TCG_RESULT
  1267. EFIAPI
  1268. TcgGetNextEndOfData(
  1269. TCG_PARSE_STRUCT *ParseStruct
  1270. )
  1271. {
  1272. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfData);
  1273. }
  1274. /**
  1275. Get next end of session.
  1276. @param ParseStruct Input parse structure.
  1277. @retval return the action result.
  1278. **/
  1279. TCG_RESULT
  1280. EFIAPI
  1281. TcgGetNextEndOfSession(
  1282. TCG_PARSE_STRUCT *ParseStruct
  1283. )
  1284. {
  1285. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfSession);
  1286. }
  1287. /**
  1288. Get next start transaction.
  1289. @param ParseStruct Input parse structure.
  1290. @retval return the action result.
  1291. **/
  1292. TCG_RESULT
  1293. EFIAPI
  1294. TcgGetNextStartTransaction(
  1295. TCG_PARSE_STRUCT *ParseStruct
  1296. )
  1297. {
  1298. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartTransaction);
  1299. }
  1300. /**
  1301. Get next end transaction.
  1302. @param ParseStruct Input parse structure.
  1303. @retval return the action result.
  1304. **/
  1305. TCG_RESULT
  1306. EFIAPI
  1307. TcgGetNextEndTransaction(
  1308. TCG_PARSE_STRUCT *ParseStruct
  1309. )
  1310. {
  1311. return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndTransaction);
  1312. }