--- /dev/null
+/** @file\r
+ Implement TPM2 Object related command.\r
+\r
+Copyright (c) 2017, Intel Corporation. All rights reserved. <BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ TPM2_COMMAND_HEADER Header;\r
+ TPMI_DH_OBJECT ObjectHandle;\r
+} TPM2_READ_PUBLIC_COMMAND;\r
+\r
+typedef struct {\r
+ TPM2_RESPONSE_HEADER Header;\r
+ TPM2B_PUBLIC OutPublic;\r
+ TPM2B_NAME Name;\r
+ TPM2B_NAME QualifiedName;\r
+} TPM2_READ_PUBLIC_RESPONSE;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+ This command allows access to the public area of a loaded object.\r
+\r
+ @param[in] ObjectHandle TPM handle of an object\r
+ @param[out] OutPublic Structure containing the public area of an object\r
+ @param[out] Name Name of the object\r
+ @param[out] QualifiedName The Qualified Name of the object\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2ReadPublic (\r
+ IN TPMI_DH_OBJECT ObjectHandle,\r
+ OUT TPM2B_PUBLIC *OutPublic,\r
+ OUT TPM2B_NAME *Name,\r
+ OUT TPM2B_NAME *QualifiedName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TPM2_READ_PUBLIC_COMMAND SendBuffer;\r
+ TPM2_READ_PUBLIC_RESPONSE RecvBuffer;\r
+ UINT32 SendBufferSize;\r
+ UINT32 RecvBufferSize;\r
+ TPM_RC ResponseCode;\r
+ UINT8 *Buffer;\r
+ UINT16 OutPublicSize;\r
+ UINT16 NameSize;\r
+ UINT16 QualifiedNameSize;\r
+\r
+ //\r
+ // Construct command\r
+ //\r
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_ReadPublic);\r
+\r
+ SendBuffer.ObjectHandle = SwapBytes32 (ObjectHandle);\r
+\r
+ SendBufferSize = (UINT32) sizeof (SendBuffer);\r
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
+\r
+ //\r
+ // send Tpm command\r
+ //\r
+ RecvBufferSize = sizeof (RecvBuffer);\r
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
+ if (ResponseCode != TPM_RC_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+ }\r
+ switch (ResponseCode) {\r
+ case TPM_RC_SUCCESS:\r
+ // return data\r
+ break;\r
+ case TPM_RC_SEQUENCE:\r
+ // objectHandle references a sequence object\r
+ return EFI_INVALID_PARAMETER;\r
+ default:\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Basic check\r
+ //\r
+ OutPublicSize = SwapBytes16 (RecvBuffer.OutPublic.size);\r
+ NameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +\r
+ sizeof(UINT16) + OutPublicSize)));\r
+ QualifiedNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +\r
+ sizeof(UINT16) + OutPublicSize +\r
+ sizeof(UINT16) + NameSize)));\r
+\r
+ if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16) + QualifiedNameSize) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize, OutPublicSize, NameSize, QualifiedNameSize));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Return the response\r
+ //\r
+ Buffer = (UINT8 *)&RecvBuffer.OutPublic;\r
+ CopyMem (OutPublic, &RecvBuffer.OutPublic, sizeof(UINT16) + OutPublicSize);\r
+ OutPublic->size = OutPublicSize;\r
+ OutPublic->publicArea.type = SwapBytes16 (OutPublic->publicArea.type);\r
+ OutPublic->publicArea.nameAlg = SwapBytes16 (OutPublic->publicArea.nameAlg);\r
+ WriteUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes)));\r
+ Buffer = (UINT8 *)&RecvBuffer.OutPublic.publicArea.authPolicy;\r
+ OutPublic->publicArea.authPolicy.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.authPolicy.buffer, Buffer, OutPublic->publicArea.authPolicy.size);\r
+ Buffer += OutPublic->publicArea.authPolicy.size;\r
+\r
+ // TPMU_PUBLIC_PARMS\r
+ switch (OutPublic->publicArea.type) {\r
+ case TPM_ALG_KEYEDHASH:\r
+ OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme) {\r
+ case TPM_ALG_HMAC:\r
+ OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_XOR:\r
+ OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.kdf = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ case TPM_ALG_SYMCIPHER:\r
+ OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.symDetail.algorithm) {\r
+ case TPM_ALG_AES:\r
+ OutPublic->publicArea.parameters.symDetail.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.symDetail.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_SM4:\r
+ OutPublic->publicArea.parameters.symDetail.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.symDetail.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_XOR:\r
+ OutPublic->publicArea.parameters.symDetail.keyBits.xor = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ break;\r
+ case TPM_ALG_RSA:\r
+ OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm) {\r
+ case TPM_ALG_AES:\r
+ OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_SM4:\r
+ OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ OutPublic->publicArea.parameters.rsaDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.rsaDetail.scheme.scheme) {\r
+ case TPM_ALG_RSASSA:\r
+ OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsassa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_RSAPSS:\r
+ OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_RSAES:\r
+ break;\r
+ case TPM_ALG_OAEP:\r
+ OutPublic->publicArea.parameters.rsaDetail.scheme.details.oaep.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT32);\r
+ break;\r
+ case TPM_ALG_ECC:\r
+ OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm) {\r
+ case TPM_ALG_AES:\r
+ OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.eccDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_SM4:\r
+ OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.eccDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ OutPublic->publicArea.parameters.eccDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.eccDetail.scheme.scheme) {\r
+ case TPM_ALG_ECDSA:\r
+ OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_ECDAA:\r
+ OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_ECSCHNORR:\r
+ OutPublic->publicArea.parameters.eccDetail.scheme.details.ecSchnorr.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_ECDH:\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ OutPublic->publicArea.parameters.eccDetail.curveID = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ OutPublic->publicArea.parameters.eccDetail.kdf.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ switch (OutPublic->publicArea.parameters.eccDetail.kdf.scheme) {\r
+ case TPM_ALG_MGF1:\r
+ OutPublic->publicArea.parameters.eccDetail.kdf.details.mgf1.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_KDF1_SP800_108:\r
+ OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_KDF1_SP800_56a:\r
+ OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_KDF2:\r
+ OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf2.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ break;\r
+ case TPM_ALG_NULL:\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ // TPMU_PUBLIC_ID\r
+ switch (OutPublic->publicArea.type) {\r
+ case TPM_ALG_KEYEDHASH:\r
+ OutPublic->publicArea.unique.keyedHash.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.unique.keyedHash.buffer, Buffer, OutPublic->publicArea.unique.keyedHash.size);\r
+ Buffer += OutPublic->publicArea.unique.keyedHash.size;\r
+ break;\r
+ case TPM_ALG_SYMCIPHER:\r
+ OutPublic->publicArea.unique.sym.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.unique.sym.buffer, Buffer, OutPublic->publicArea.unique.sym.size);\r
+ Buffer += OutPublic->publicArea.unique.sym.size;\r
+ break;\r
+ case TPM_ALG_RSA:\r
+ OutPublic->publicArea.unique.rsa.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.unique.rsa.buffer, Buffer, OutPublic->publicArea.unique.rsa.size);\r
+ Buffer += OutPublic->publicArea.unique.rsa.size;\r
+ break;\r
+ case TPM_ALG_ECC:\r
+ OutPublic->publicArea.unique.ecc.x.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.unique.ecc.x.buffer, Buffer, OutPublic->publicArea.unique.ecc.x.size);\r
+ Buffer += OutPublic->publicArea.unique.ecc.x.size;\r
+ OutPublic->publicArea.unique.ecc.y.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+ Buffer += sizeof(UINT16);\r
+ CopyMem (OutPublic->publicArea.unique.ecc.y.buffer, Buffer, OutPublic->publicArea.unique.ecc.y.size);\r
+ Buffer += OutPublic->publicArea.unique.ecc.y.size;\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CopyMem (Name->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16), NameSize);\r
+ Name->size = NameSize;\r
+\r
+ CopyMem (QualifiedName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16), QualifiedNameSize);\r
+ QualifiedName->size = QualifiedNameSize;\r
+\r
+ return EFI_SUCCESS;\r
+}\r