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