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
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.
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>
23 TPMI_ALG_HASH HashAlgo
;
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
},
37 Return size of digest.
39 @param[in] HashAlgo Hash algorithm
41 @return size of digest
46 IN TPMI_ALG_HASH HashAlgo
51 for (Index
= 0; Index
< sizeof(mHashInfo
)/sizeof(mHashInfo
[0]); Index
++) {
52 if (mHashInfo
[Index
].HashAlgo
== HashAlgo
) {
53 return mHashInfo
[Index
].HashSize
;
60 Get hash mask from algorithm.
62 @param[in] HashAlgo Hash algorithm
69 IN TPMI_ALG_HASH HashAlgo
74 for (Index
= 0; Index
< sizeof(mHashInfo
)/sizeof(mHashInfo
[0]); Index
++) {
75 if (mHashInfo
[Index
].HashAlgo
== HashAlgo
) {
76 return mHashInfo
[Index
].HashMask
;
83 Copy AuthSessionIn to TPM2 command buffer.
85 @param [in] AuthSessionIn Input AuthSession data
86 @param [out] AuthSessionOut Output AuthSession data in TPM2 command buffer
88 @return AuthSession size
92 CopyAuthSessionCommand (
93 IN TPMS_AUTH_COMMAND
*AuthSessionIn
, OPTIONAL
94 OUT UINT8
*AuthSessionOut
99 Buffer
= (UINT8
*)AuthSessionOut
;
102 // Add in Auth session
104 if (AuthSessionIn
!= NULL
) {
106 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32(AuthSessionIn
->sessionHandle
));
107 Buffer
+= sizeof(UINT32
);
110 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (AuthSessionIn
->nonce
.size
));
111 Buffer
+= sizeof(UINT16
);
113 CopyMem (Buffer
, AuthSessionIn
->nonce
.buffer
, AuthSessionIn
->nonce
.size
);
114 Buffer
+= AuthSessionIn
->nonce
.size
;
117 *(UINT8
*)Buffer
= *(UINT8
*)&AuthSessionIn
->sessionAttributes
;
121 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (AuthSessionIn
->hmac
.size
));
122 Buffer
+= sizeof(UINT16
);
124 CopyMem (Buffer
, AuthSessionIn
->hmac
.buffer
, AuthSessionIn
->hmac
.size
);
125 Buffer
+= AuthSessionIn
->hmac
.size
;
128 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32(TPM_RS_PW
));
129 Buffer
+= sizeof(UINT32
);
132 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(0));
133 Buffer
+= sizeof(UINT16
);
135 // sessionAttributes = 0
136 *(UINT8
*)Buffer
= 0x00;
140 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(0));
141 Buffer
+= sizeof(UINT16
);
144 return (UINT32
)((UINTN
)Buffer
- (UINTN
)AuthSessionOut
);
148 Copy AuthSessionIn from TPM2 response buffer.
150 @param [in] AuthSessionIn Input AuthSession data in TPM2 response buffer
151 @param [out] AuthSessionOut Output AuthSession data
153 @return 0 copy failed
154 else AuthSession size
158 CopyAuthSessionResponse (
159 IN UINT8
*AuthSessionIn
,
160 OUT TPMS_AUTH_RESPONSE
*AuthSessionOut OPTIONAL
164 TPMS_AUTH_RESPONSE LocalAuthSessionOut
;
166 if (AuthSessionOut
== NULL
) {
167 AuthSessionOut
= &LocalAuthSessionOut
;
170 Buffer
= (UINT8
*)AuthSessionIn
;
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
));
180 CopyMem (AuthSessionOut
->nonce
.buffer
, Buffer
, AuthSessionOut
->nonce
.size
);
181 Buffer
+= AuthSessionOut
->nonce
.size
;
184 *(UINT8
*)&AuthSessionOut
->sessionAttributes
= *(UINT8
*)Buffer
;
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
));
195 CopyMem (AuthSessionOut
->hmac
.buffer
, Buffer
, AuthSessionOut
->hmac
.size
);
196 Buffer
+= AuthSessionOut
->hmac
.size
;
198 return (UINT32
)((UINTN
)Buffer
- (UINTN
)AuthSessionIn
);
202 Return if hash alg is supported in HashAlgorithmMask.
204 @param HashAlg Hash algorithm to be checked.
205 @param HashAlgorithmMask Bitfield of allowed hash algorithms.
207 @retval TRUE Hash algorithm is supported.
208 @retval FALSE Hash algorithm is not supported.
212 IsHashAlgSupportedInHashAlgorithmMask(
213 IN TPMI_ALG_HASH HashAlg
,
214 IN UINT32 HashAlgorithmMask
219 if ((HashAlgorithmMask
& HASH_ALG_SHA1
) != 0) {
224 if ((HashAlgorithmMask
& HASH_ALG_SHA256
) != 0) {
229 if ((HashAlgorithmMask
& HASH_ALG_SHA384
) != 0) {
234 if ((HashAlgorithmMask
& HASH_ALG_SHA512
) != 0) {
238 case TPM_ALG_SM3_256
:
239 if ((HashAlgorithmMask
& HASH_ALG_SM3_256
) != 0) {
249 Copy TPML_DIGEST_VALUES into a buffer
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.
255 @return The end of buffer to hold TPML_DIGEST_VALUES.
259 CopyDigestListToBuffer (
261 IN TPML_DIGEST_VALUES
*DigestList
,
262 IN UINT32 HashAlgorithmMask
267 UINT32 DigestListCount
;
268 UINT32
*DigestListCountPtr
;
270 DigestListCountPtr
= (UINT32
*) Buffer
;
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
));
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
;
285 WriteUnaligned32 (DigestListCountPtr
, DigestListCount
);
291 Get TPML_DIGEST_VALUES data size.
293 @param[in] DigestList TPML_DIGEST_VALUES data.
295 @return TPML_DIGEST_VALUES data size.
300 IN TPML_DIGEST_VALUES
*DigestList
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
;
317 This function get digest from digest list.
319 @param[in] HashAlg Digest algorithm
320 @param[in] DigestList Digest list
321 @param[out] Digest Digest
323 @retval EFI_SUCCESS Digest is found and returned.
324 @retval EFI_NOT_FOUND Digest is not found.
328 GetDigestFromDigestList (
329 IN TPMI_ALG_HASH HashAlg
,
330 IN TPML_DIGEST_VALUES
*DigestList
,
337 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
338 for (Index
= 0; Index
< DigestList
->count
; Index
++) {
339 if (DigestList
->digests
[Index
].hashAlg
== HashAlg
) {
342 &DigestList
->digests
[Index
].digest
,
349 return EFI_NOT_FOUND
;