HashLibTpm2.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /** @file
  2. This library uses TPM2 device to calculation hash.
  3. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
  4. (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiPei.h>
  8. #include <Library/BaseLib.h>
  9. #include <Library/BaseMemoryLib.h>
  10. #include <Library/Tpm2CommandLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/MemoryAllocationLib.h>
  13. #include <Library/HashLib.h>
  14. #include <Library/PcdLib.h>
  15. typedef struct {
  16. TPM_ALG_ID AlgoId;
  17. UINT32 Mask;
  18. } TPM2_HASH_MASK;
  19. TPM2_HASH_MASK mTpm2HashMask[] = {
  20. {TPM_ALG_SHA1, HASH_ALG_SHA1},
  21. {TPM_ALG_SHA256, HASH_ALG_SHA256},
  22. {TPM_ALG_SHA384, HASH_ALG_SHA384},
  23. {TPM_ALG_SHA512, HASH_ALG_SHA512},
  24. };
  25. /**
  26. The function get algorithm from hash mask info.
  27. @return Hash algorithm
  28. **/
  29. TPM_ALG_ID
  30. Tpm2GetAlgoFromHashMask (
  31. VOID
  32. )
  33. {
  34. UINT32 HashMask;
  35. UINTN Index;
  36. HashMask = PcdGet32 (PcdTpm2HashMask);
  37. for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {
  38. if (mTpm2HashMask[Index].Mask == HashMask) {
  39. return mTpm2HashMask[Index].AlgoId;
  40. }
  41. }
  42. return TPM_ALG_NULL;
  43. }
  44. /**
  45. Start hash sequence.
  46. @param HashHandle Hash handle.
  47. @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
  48. @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
  49. **/
  50. EFI_STATUS
  51. EFIAPI
  52. HashStart (
  53. OUT HASH_HANDLE *HashHandle
  54. )
  55. {
  56. TPMI_DH_OBJECT SequenceHandle;
  57. EFI_STATUS Status;
  58. TPM_ALG_ID AlgoId;
  59. AlgoId = Tpm2GetAlgoFromHashMask ();
  60. Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);
  61. if (!EFI_ERROR (Status)) {
  62. *HashHandle = (HASH_HANDLE)SequenceHandle;
  63. }
  64. return Status;
  65. }
  66. /**
  67. Update hash sequence data.
  68. @param HashHandle Hash handle.
  69. @param DataToHash Data to be hashed.
  70. @param DataToHashLen Data size.
  71. @retval EFI_SUCCESS Hash sequence updated.
  72. **/
  73. EFI_STATUS
  74. EFIAPI
  75. HashUpdate (
  76. IN HASH_HANDLE HashHandle,
  77. IN VOID *DataToHash,
  78. IN UINTN DataToHashLen
  79. )
  80. {
  81. UINT8 *Buffer;
  82. UINT64 HashLen;
  83. TPM2B_MAX_BUFFER HashBuffer;
  84. EFI_STATUS Status;
  85. Buffer = (UINT8 *)(UINTN)DataToHash;
  86. for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
  87. HashBuffer.size = sizeof(HashBuffer.buffer);
  88. CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
  89. Buffer += sizeof(HashBuffer.buffer);
  90. Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
  91. if (EFI_ERROR(Status)) {
  92. return EFI_DEVICE_ERROR;
  93. }
  94. }
  95. //
  96. // Last one
  97. //
  98. HashBuffer.size = (UINT16)HashLen;
  99. CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
  100. Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
  101. if (EFI_ERROR(Status)) {
  102. return EFI_DEVICE_ERROR;
  103. }
  104. return EFI_SUCCESS;
  105. }
  106. /**
  107. Hash sequence complete and extend to PCR.
  108. @param HashHandle Hash handle.
  109. @param PcrIndex PCR to be extended.
  110. @param DataToHash Data to be hashed.
  111. @param DataToHashLen Data size.
  112. @param DigestList Digest list.
  113. @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
  114. **/
  115. EFI_STATUS
  116. EFIAPI
  117. HashCompleteAndExtend (
  118. IN HASH_HANDLE HashHandle,
  119. IN TPMI_DH_PCR PcrIndex,
  120. IN VOID *DataToHash,
  121. IN UINTN DataToHashLen,
  122. OUT TPML_DIGEST_VALUES *DigestList
  123. )
  124. {
  125. UINT8 *Buffer;
  126. UINT64 HashLen;
  127. TPM2B_MAX_BUFFER HashBuffer;
  128. EFI_STATUS Status;
  129. TPM_ALG_ID AlgoId;
  130. TPM2B_DIGEST Result;
  131. AlgoId = Tpm2GetAlgoFromHashMask ();
  132. Buffer = (UINT8 *)(UINTN)DataToHash;
  133. for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
  134. HashBuffer.size = sizeof(HashBuffer.buffer);
  135. CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
  136. Buffer += sizeof(HashBuffer.buffer);
  137. Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
  138. if (EFI_ERROR(Status)) {
  139. return EFI_DEVICE_ERROR;
  140. }
  141. }
  142. //
  143. // Last one
  144. //
  145. HashBuffer.size = (UINT16)HashLen;
  146. CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
  147. ZeroMem(DigestList, sizeof(*DigestList));
  148. DigestList->count = HASH_COUNT;
  149. if (AlgoId == TPM_ALG_NULL) {
  150. Status = Tpm2EventSequenceComplete (
  151. PcrIndex,
  152. (TPMI_DH_OBJECT)HashHandle,
  153. &HashBuffer,
  154. DigestList
  155. );
  156. } else {
  157. Status = Tpm2SequenceComplete (
  158. (TPMI_DH_OBJECT)HashHandle,
  159. &HashBuffer,
  160. &Result
  161. );
  162. if (EFI_ERROR(Status)) {
  163. return EFI_DEVICE_ERROR;
  164. }
  165. DigestList->count = 1;
  166. DigestList->digests[0].hashAlg = AlgoId;
  167. CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);
  168. Status = Tpm2PcrExtend (
  169. PcrIndex,
  170. DigestList
  171. );
  172. }
  173. if (EFI_ERROR(Status)) {
  174. return EFI_DEVICE_ERROR;
  175. }
  176. return EFI_SUCCESS;
  177. }
  178. /**
  179. Hash data and extend to PCR.
  180. @param PcrIndex PCR to be extended.
  181. @param DataToHash Data to be hashed.
  182. @param DataToHashLen Data size.
  183. @param DigestList Digest list.
  184. @retval EFI_SUCCESS Hash data and DigestList is returned.
  185. **/
  186. EFI_STATUS
  187. EFIAPI
  188. HashAndExtend (
  189. IN TPMI_DH_PCR PcrIndex,
  190. IN VOID *DataToHash,
  191. IN UINTN DataToHashLen,
  192. OUT TPML_DIGEST_VALUES *DigestList
  193. )
  194. {
  195. EFI_STATUS Status;
  196. UINT8 *Buffer;
  197. UINT64 HashLen;
  198. TPMI_DH_OBJECT SequenceHandle;
  199. TPM2B_MAX_BUFFER HashBuffer;
  200. TPM_ALG_ID AlgoId;
  201. TPM2B_EVENT EventData;
  202. TPM2B_DIGEST Result;
  203. DEBUG((EFI_D_VERBOSE, "\n HashAndExtend Entry \n"));
  204. SequenceHandle = 0xFFFFFFFF; // Know bad value
  205. AlgoId = Tpm2GetAlgoFromHashMask ();
  206. if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof(EventData.buffer))) {
  207. EventData.size = (UINT16)DataToHashLen;
  208. CopyMem (EventData.buffer, DataToHash, DataToHashLen);
  209. Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);
  210. if (EFI_ERROR(Status)) {
  211. return EFI_DEVICE_ERROR;
  212. }
  213. return EFI_SUCCESS;
  214. }
  215. Status = Tpm2HashSequenceStart(AlgoId, &SequenceHandle);
  216. if (EFI_ERROR(Status)) {
  217. return EFI_DEVICE_ERROR;
  218. }
  219. DEBUG((EFI_D_VERBOSE, "\n Tpm2HashSequenceStart Success \n"));
  220. Buffer = (UINT8 *)(UINTN)DataToHash;
  221. for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
  222. HashBuffer.size = sizeof(HashBuffer.buffer);
  223. CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
  224. Buffer += sizeof(HashBuffer.buffer);
  225. Status = Tpm2SequenceUpdate(SequenceHandle, &HashBuffer);
  226. if (EFI_ERROR(Status)) {
  227. return EFI_DEVICE_ERROR;
  228. }
  229. }
  230. DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceUpdate Success \n"));
  231. HashBuffer.size = (UINT16)HashLen;
  232. CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
  233. ZeroMem(DigestList, sizeof(*DigestList));
  234. DigestList->count = HASH_COUNT;
  235. if (AlgoId == TPM_ALG_NULL) {
  236. Status = Tpm2EventSequenceComplete (
  237. PcrIndex,
  238. SequenceHandle,
  239. &HashBuffer,
  240. DigestList
  241. );
  242. if (EFI_ERROR(Status)) {
  243. return EFI_DEVICE_ERROR;
  244. }
  245. DEBUG((EFI_D_VERBOSE, "\n Tpm2EventSequenceComplete Success \n"));
  246. } else {
  247. Status = Tpm2SequenceComplete (
  248. SequenceHandle,
  249. &HashBuffer,
  250. &Result
  251. );
  252. if (EFI_ERROR(Status)) {
  253. return EFI_DEVICE_ERROR;
  254. }
  255. DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceComplete Success \n"));
  256. DigestList->count = 1;
  257. DigestList->digests[0].hashAlg = AlgoId;
  258. CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);
  259. Status = Tpm2PcrExtend (
  260. PcrIndex,
  261. DigestList
  262. );
  263. if (EFI_ERROR(Status)) {
  264. return EFI_DEVICE_ERROR;
  265. }
  266. DEBUG((EFI_D_VERBOSE, "\n Tpm2PcrExtend Success \n"));
  267. }
  268. return EFI_SUCCESS;
  269. }
  270. /**
  271. This service register Hash.
  272. @param HashInterface Hash interface
  273. @retval EFI_SUCCESS This hash interface is registered successfully.
  274. @retval EFI_UNSUPPORTED System does not support register this interface.
  275. @retval EFI_ALREADY_STARTED System already register this interface.
  276. **/
  277. EFI_STATUS
  278. EFIAPI
  279. RegisterHashInterfaceLib (
  280. IN HASH_INTERFACE *HashInterface
  281. )
  282. {
  283. return EFI_UNSUPPORTED;
  284. }