]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibTdx/HashLibTdx.c
Security: Add HashLibTdx
[mirror_edk2.git] / SecurityPkg / Library / HashLibTdx / HashLibTdx.c
1 /** @file
2 This library is HashLib for Tdx.
3
4 Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiPei.h>
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/PcdLib.h>
14 #include <Library/HashLib.h>
15 #include <Library/TdxLib.h>
16 #include <Protocol/CcMeasurement.h>
17
18 EFI_GUID mSha384Guid = HASH_ALGORITHM_SHA384_GUID;
19
20 //
21 // Currently TDX supports SHA384.
22 //
23 HASH_INTERFACE mHashInterface = {
24 { 0 }, NULL, NULL, NULL
25 };
26
27 UINTN mHashInterfaceCount = 0;
28
29 /**
30 Start hash sequence.
31
32 @param HashHandle Hash handle.
33
34 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
35 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
36 **/
37 EFI_STATUS
38 EFIAPI
39 HashStart (
40 OUT HASH_HANDLE *HashHandle
41 )
42 {
43 HASH_HANDLE HashCtx;
44
45 if (mHashInterfaceCount == 0) {
46 ASSERT (FALSE);
47 return EFI_UNSUPPORTED;
48 }
49
50 HashCtx = 0;
51 mHashInterface.HashInit (&HashCtx);
52
53 *HashHandle = HashCtx;
54
55 return EFI_SUCCESS;
56 }
57
58 /**
59 Update hash sequence data.
60
61 @param HashHandle Hash handle.
62 @param DataToHash Data to be hashed.
63 @param DataToHashLen Data size.
64
65 @retval EFI_SUCCESS Hash sequence updated.
66 **/
67 EFI_STATUS
68 EFIAPI
69 HashUpdate (
70 IN HASH_HANDLE HashHandle,
71 IN VOID *DataToHash,
72 IN UINTN DataToHashLen
73 )
74 {
75 if (mHashInterfaceCount == 0) {
76 ASSERT (FALSE);
77 return EFI_UNSUPPORTED;
78 }
79
80 mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen);
81
82 return EFI_SUCCESS;
83 }
84
85 /**
86 Hash sequence complete and extend to PCR.
87
88 @param HashHandle Hash handle.
89 @param PcrIndex PCR to be extended.
90 @param DataToHash Data to be hashed.
91 @param DataToHashLen Data size.
92 @param DigestList Digest list.
93
94 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
95 **/
96 EFI_STATUS
97 EFIAPI
98 HashCompleteAndExtend (
99 IN HASH_HANDLE HashHandle,
100 IN TPMI_DH_PCR PcrIndex,
101 IN VOID *DataToHash,
102 IN UINTN DataToHashLen,
103 OUT TPML_DIGEST_VALUES *DigestList
104 )
105 {
106 TPML_DIGEST_VALUES Digest;
107 EFI_STATUS Status;
108
109 if (mHashInterfaceCount == 0) {
110 ASSERT (FALSE);
111 return EFI_UNSUPPORTED;
112 }
113
114 ZeroMem (DigestList, sizeof (*DigestList));
115
116 mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen);
117 mHashInterface.HashFinal (HashHandle, &Digest);
118
119 CopyMem (
120 &DigestList->digests[0],
121 &Digest.digests[0],
122 sizeof (Digest.digests[0])
123 );
124 DigestList->count++;
125
126 ASSERT (DigestList->count == 1 && DigestList->digests[0].hashAlg == TPM_ALG_SHA384);
127
128 Status = TdExtendRtmr (
129 (UINT32 *)DigestList->digests[0].digest.sha384,
130 SHA384_DIGEST_SIZE,
131 (UINT8)PcrIndex
132 );
133
134 ASSERT (!EFI_ERROR (Status));
135 return Status;
136 }
137
138 /**
139 Hash data and extend to RTMR.
140
141 @param PcrIndex PCR to be extended.
142 @param DataToHash Data to be hashed.
143 @param DataToHashLen Data size.
144 @param DigestList Digest list.
145
146 @retval EFI_SUCCESS Hash data and DigestList is returned.
147 **/
148 EFI_STATUS
149 EFIAPI
150 HashAndExtend (
151 IN TPMI_DH_PCR PcrIndex,
152 IN VOID *DataToHash,
153 IN UINTN DataToHashLen,
154 OUT TPML_DIGEST_VALUES *DigestList
155 )
156 {
157 HASH_HANDLE HashHandle;
158 EFI_STATUS Status;
159
160 if (mHashInterfaceCount == 0) {
161 ASSERT (FALSE);
162 return EFI_UNSUPPORTED;
163 }
164
165 ASSERT (TdIsEnabled ());
166
167 HashStart (&HashHandle);
168 HashUpdate (HashHandle, DataToHash, DataToHashLen);
169 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
170
171 return Status;
172 }
173
174 /**
175 This service register Hash.
176
177 @param HashInterface Hash interface
178
179 @retval EFI_SUCCESS This hash interface is registered successfully.
180 @retval EFI_UNSUPPORTED System does not support register this interface.
181 @retval EFI_ALREADY_STARTED System already register this interface.
182 **/
183 EFI_STATUS
184 EFIAPI
185 RegisterHashInterfaceLib (
186 IN HASH_INTERFACE *HashInterface
187 )
188 {
189 ASSERT (TdIsEnabled ());
190
191 //
192 // Only SHA384 is allowed.
193 //
194 if (!CompareGuid (&mSha384Guid, &HashInterface->HashGuid)) {
195 return EFI_UNSUPPORTED;
196 }
197
198 if (mHashInterfaceCount != 0) {
199 ASSERT (FALSE);
200 return EFI_OUT_OF_RESOURCES;
201 }
202
203 CopyMem (&mHashInterface, HashInterface, sizeof (*HashInterface));
204 mHashInterfaceCount++;
205
206 return EFI_SUCCESS;
207 }