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