]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Help.c
1 /** @file
2 Implement TPM2 help.
3
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <IndustryStandard/UefiTcgPlatform.h>
10 #include <Library/Tpm2CommandLib.h>
11 #include <Library/Tpm2DeviceLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/BaseLib.h>
14 #include <Library/DebugLib.h>
15
16 typedef struct {
17 TPMI_ALG_HASH HashAlgo;
18 UINT16 HashSize;
19 UINT32 HashMask;
20 } INTERNAL_HASH_INFO;
21
22 STATIC INTERNAL_HASH_INFO mHashInfo[] = {
23 { TPM_ALG_SHA1, SHA1_DIGEST_SIZE, HASH_ALG_SHA1 },
24 { TPM_ALG_SHA256, SHA256_DIGEST_SIZE, HASH_ALG_SHA256 },
25 { TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, HASH_ALG_SM3_256 },
26 { TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384 },
27 { TPM_ALG_SHA512, SHA512_DIGEST_SIZE, HASH_ALG_SHA512 },
28 };
29
30 /**
31 Return size of digest.
32
33 @param[in] HashAlgo Hash algorithm
34
35 @return size of digest
36 **/
37 UINT16
38 EFIAPI
39 GetHashSizeFromAlgo (
40 IN TPMI_ALG_HASH HashAlgo
41 )
42 {
43 UINTN Index;
44
45 for (Index = 0; Index < sizeof (mHashInfo)/sizeof (mHashInfo[0]); Index++) {
46 if (mHashInfo[Index].HashAlgo == HashAlgo) {
47 return mHashInfo[Index].HashSize;
48 }
49 }
50
51 return 0;
52 }
53
54 /**
55 Get hash mask from algorithm.
56
57 @param[in] HashAlgo Hash algorithm
58
59 @return Hash mask
60 **/
61 UINT32
62 EFIAPI
63 GetHashMaskFromAlgo (
64 IN TPMI_ALG_HASH HashAlgo
65 )
66 {
67 UINTN Index;
68
69 for (Index = 0; Index < sizeof (mHashInfo)/sizeof (mHashInfo[0]); Index++) {
70 if (mHashInfo[Index].HashAlgo == HashAlgo) {
71 return mHashInfo[Index].HashMask;
72 }
73 }
74
75 return 0;
76 }
77
78 /**
79 Copy AuthSessionIn to TPM2 command buffer.
80
81 @param [in] AuthSessionIn Input AuthSession data
82 @param [out] AuthSessionOut Output AuthSession data in TPM2 command buffer
83
84 @return AuthSession size
85 **/
86 UINT32
87 EFIAPI
88 CopyAuthSessionCommand (
89 IN TPMS_AUTH_COMMAND *AuthSessionIn OPTIONAL,
90 OUT UINT8 *AuthSessionOut
91 )
92 {
93 UINT8 *Buffer;
94
95 Buffer = (UINT8 *)AuthSessionOut;
96
97 //
98 // Add in Auth session
99 //
100 if (AuthSessionIn != NULL) {
101 // sessionHandle
102 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (AuthSessionIn->sessionHandle));
103 Buffer += sizeof (UINT32);
104
105 // nonce
106 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->nonce.size));
107 Buffer += sizeof (UINT16);
108
109 CopyMem (Buffer, AuthSessionIn->nonce.buffer, AuthSessionIn->nonce.size);
110 Buffer += AuthSessionIn->nonce.size;
111
112 // sessionAttributes
113 *(UINT8 *)Buffer = *(UINT8 *)&AuthSessionIn->sessionAttributes;
114 Buffer++;
115
116 // hmac
117 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->hmac.size));
118 Buffer += sizeof (UINT16);
119
120 CopyMem (Buffer, AuthSessionIn->hmac.buffer, AuthSessionIn->hmac.size);
121 Buffer += AuthSessionIn->hmac.size;
122 } else {
123 // sessionHandle
124 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (TPM_RS_PW));
125 Buffer += sizeof (UINT32);
126
127 // nonce = nullNonce
128 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (0));
129 Buffer += sizeof (UINT16);
130
131 // sessionAttributes = 0
132 *(UINT8 *)Buffer = 0x00;
133 Buffer++;
134
135 // hmac = nullAuth
136 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (0));
137 Buffer += sizeof (UINT16);
138 }
139
140 return (UINT32)((UINTN)Buffer - (UINTN)AuthSessionOut);
141 }
142
143 /**
144 Copy AuthSessionIn from TPM2 response buffer.
145
146 @param [in] AuthSessionIn Input AuthSession data in TPM2 response buffer
147 @param [out] AuthSessionOut Output AuthSession data
148
149 @return 0 copy failed
150 else AuthSession size
151 **/
152 UINT32
153 EFIAPI
154 CopyAuthSessionResponse (
155 IN UINT8 *AuthSessionIn,
156 OUT TPMS_AUTH_RESPONSE *AuthSessionOut OPTIONAL
157 )
158 {
159 UINT8 *Buffer;
160 TPMS_AUTH_RESPONSE LocalAuthSessionOut;
161
162 if (AuthSessionOut == NULL) {
163 AuthSessionOut = &LocalAuthSessionOut;
164 }
165
166 Buffer = (UINT8 *)AuthSessionIn;
167
168 // nonce
169 AuthSessionOut->nonce.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
170 Buffer += sizeof (UINT16);
171 if (AuthSessionOut->nonce.size > sizeof (TPMU_HA)) {
172 DEBUG ((DEBUG_ERROR, "CopyAuthSessionResponse - nonce.size error %x\n", AuthSessionOut->nonce.size));
173 return 0;
174 }
175
176 CopyMem (AuthSessionOut->nonce.buffer, Buffer, AuthSessionOut->nonce.size);
177 Buffer += AuthSessionOut->nonce.size;
178
179 // sessionAttributes
180 *(UINT8 *) &AuthSessionOut->sessionAttributes = *(UINT8 *)Buffer;
181 Buffer++;
182
183 // hmac
184 AuthSessionOut->hmac.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
185 Buffer += sizeof (UINT16);
186 if (AuthSessionOut->hmac.size > sizeof (TPMU_HA)) {
187 DEBUG ((DEBUG_ERROR, "CopyAuthSessionResponse - hmac.size error %x\n", AuthSessionOut->hmac.size));
188 return 0;
189 }
190
191 CopyMem (AuthSessionOut->hmac.buffer, Buffer, AuthSessionOut->hmac.size);
192 Buffer += AuthSessionOut->hmac.size;
193
194 return (UINT32)((UINTN)Buffer - (UINTN)AuthSessionIn);
195 }
196
197 /**
198 Return if hash alg is supported in HashAlgorithmMask.
199
200 @param HashAlg Hash algorithm to be checked.
201 @param HashAlgorithmMask Bitfield of allowed hash algorithms.
202
203 @retval TRUE Hash algorithm is supported.
204 @retval FALSE Hash algorithm is not supported.
205 **/
206 BOOLEAN
207 EFIAPI
208 IsHashAlgSupportedInHashAlgorithmMask (
209 IN TPMI_ALG_HASH HashAlg,
210 IN UINT32 HashAlgorithmMask
211 )
212 {
213 switch (HashAlg) {
214 case TPM_ALG_SHA1:
215 if ((HashAlgorithmMask & HASH_ALG_SHA1) != 0) {
216 return TRUE;
217 }
218
219 break;
220 case TPM_ALG_SHA256:
221 if ((HashAlgorithmMask & HASH_ALG_SHA256) != 0) {
222 return TRUE;
223 }
224
225 break;
226 case TPM_ALG_SHA384:
227 if ((HashAlgorithmMask & HASH_ALG_SHA384) != 0) {
228 return TRUE;
229 }
230
231 break;
232 case TPM_ALG_SHA512:
233 if ((HashAlgorithmMask & HASH_ALG_SHA512) != 0) {
234 return TRUE;
235 }
236
237 break;
238 case TPM_ALG_SM3_256:
239 if ((HashAlgorithmMask & HASH_ALG_SM3_256) != 0) {
240 return TRUE;
241 }
242
243 break;
244 }
245
246 return FALSE;
247 }
248
249 /**
250 Copy TPML_DIGEST_VALUES into a buffer
251
252 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
253 @param[in] DigestList TPML_DIGEST_VALUES to be copied.
254 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
255
256 @return The end of buffer to hold TPML_DIGEST_VALUES.
257 **/
258 VOID *
259 EFIAPI
260 CopyDigestListToBuffer (
261 IN OUT VOID *Buffer,
262 IN TPML_DIGEST_VALUES *DigestList,
263 IN UINT32 HashAlgorithmMask
264 )
265 {
266 UINTN Index;
267 UINT16 DigestSize;
268 UINT32 DigestListCount;
269 UINT32 *DigestListCountPtr;
270
271 DigestListCountPtr = (UINT32 *)Buffer;
272 DigestListCount = 0;
273 Buffer = (UINT8 *)Buffer + sizeof (DigestList->count);
274 for (Index = 0; Index < DigestList->count; Index++) {
275 if (!IsHashAlgSupportedInHashAlgorithmMask (DigestList->digests[Index].hashAlg, HashAlgorithmMask)) {
276 DEBUG ((DEBUG_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));
277 continue;
278 }
279
280 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof (DigestList->digests[Index].hashAlg));
281 Buffer = (UINT8 *)Buffer + sizeof (DigestList->digests[Index].hashAlg);
282 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
283 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);
284 Buffer = (UINT8 *)Buffer + DigestSize;
285 DigestListCount++;
286 }
287
288 WriteUnaligned32 (DigestListCountPtr, DigestListCount);
289
290 return Buffer;
291 }
292
293 /**
294 Get TPML_DIGEST_VALUES data size.
295
296 @param[in] DigestList TPML_DIGEST_VALUES data.
297
298 @return TPML_DIGEST_VALUES data size.
299 **/
300 UINT32
301 EFIAPI
302 GetDigestListSize (
303 IN TPML_DIGEST_VALUES *DigestList
304 )
305 {
306 UINTN Index;
307 UINT16 DigestSize;
308 UINT32 TotalSize;
309
310 TotalSize = sizeof (DigestList->count);
311 for (Index = 0; Index < DigestList->count; Index++) {
312 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
313 TotalSize += sizeof (DigestList->digests[Index].hashAlg) + DigestSize;
314 }
315
316 return TotalSize;
317 }
318
319 /**
320 This function get digest from digest list.
321
322 @param[in] HashAlg Digest algorithm
323 @param[in] DigestList Digest list
324 @param[out] Digest Digest
325
326 @retval EFI_SUCCESS Digest is found and returned.
327 @retval EFI_NOT_FOUND Digest is not found.
328 **/
329 EFI_STATUS
330 EFIAPI
331 GetDigestFromDigestList (
332 IN TPMI_ALG_HASH HashAlg,
333 IN TPML_DIGEST_VALUES *DigestList,
334 OUT VOID *Digest
335 )
336 {
337 UINTN Index;
338 UINT16 DigestSize;
339
340 DigestSize = GetHashSizeFromAlgo (HashAlg);
341 for (Index = 0; Index < DigestList->count; Index++) {
342 if (DigestList->digests[Index].hashAlg == HashAlg) {
343 CopyMem (
344 Digest,
345 &DigestList->digests[Index].digest,
346 DigestSize
347 );
348 return EFI_SUCCESS;
349 }
350 }
351
352 return EFI_NOT_FOUND;
353 }