From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../Library/Tpm2CommandLib/Tpm2Object.c | 379 +++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100644 roms/edk2/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c (limited to 'roms/edk2/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c') diff --git a/roms/edk2/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c b/roms/edk2/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c new file mode 100644 index 000000000..f5301f04d --- /dev/null +++ b/roms/edk2/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c @@ -0,0 +1,379 @@ +/** @file + Implement TPM2 Object related command. + +Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#pragma pack(1) + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_DH_OBJECT ObjectHandle; +} TPM2_READ_PUBLIC_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; + TPM2B_PUBLIC OutPublic; + TPM2B_NAME Name; + TPM2B_NAME QualifiedName; +} TPM2_READ_PUBLIC_RESPONSE; + +#pragma pack() + +/** + This command allows access to the public area of a loaded object. + + @param[in] ObjectHandle TPM handle of an object + @param[out] OutPublic Structure containing the public area of an object + @param[out] Name Name of the object + @param[out] QualifiedName The Qualified Name of the object + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2ReadPublic ( + IN TPMI_DH_OBJECT ObjectHandle, + OUT TPM2B_PUBLIC *OutPublic, + OUT TPM2B_NAME *Name, + OUT TPM2B_NAME *QualifiedName + ) +{ + EFI_STATUS Status; + TPM2_READ_PUBLIC_COMMAND SendBuffer; + TPM2_READ_PUBLIC_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + TPM_RC ResponseCode; + UINT8 *Buffer; + UINT16 OutPublicSize; + UINT16 NameSize; + UINT16 QualifiedNameSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_ReadPublic); + + SendBuffer.ObjectHandle = SwapBytes32 (ObjectHandle); + + SendBufferSize = (UINT32) sizeof (SendBuffer); + SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize); + + // + // send Tpm command + // + RecvBufferSize = sizeof (RecvBuffer); + Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer); + if (EFI_ERROR (Status)) { + return Status; + } + + if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode); + if (ResponseCode != TPM_RC_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + } + switch (ResponseCode) { + case TPM_RC_SUCCESS: + // return data + break; + case TPM_RC_SEQUENCE: + // objectHandle references a sequence object + return EFI_INVALID_PARAMETER; + default: + return EFI_DEVICE_ERROR; + } + + // + // Basic check + // + OutPublicSize = SwapBytes16 (RecvBuffer.OutPublic.size); + if (OutPublicSize > sizeof(TPMT_PUBLIC)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - OutPublicSize error %x\n", OutPublicSize)); + return EFI_DEVICE_ERROR; + } + + NameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + + sizeof(UINT16) + OutPublicSize))); + if (NameSize > sizeof(TPMU_NAME)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - NameSize error %x\n", NameSize)); + return EFI_DEVICE_ERROR; + } + + QualifiedNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + + sizeof(UINT16) + OutPublicSize + + sizeof(UINT16) + NameSize))); + if (QualifiedNameSize > sizeof(TPMU_NAME)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - QualifiedNameSize error %x\n", QualifiedNameSize)); + return EFI_DEVICE_ERROR; + } + + if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16) + QualifiedNameSize) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize, OutPublicSize, NameSize, QualifiedNameSize)); + return EFI_DEVICE_ERROR; + } + + // + // Return the response + // + Buffer = (UINT8 *)&RecvBuffer.OutPublic; + CopyMem (OutPublic, &RecvBuffer.OutPublic, sizeof(UINT16) + OutPublicSize); + OutPublic->size = OutPublicSize; + OutPublic->publicArea.type = SwapBytes16 (OutPublic->publicArea.type); + OutPublic->publicArea.nameAlg = SwapBytes16 (OutPublic->publicArea.nameAlg); + WriteUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes))); + Buffer = (UINT8 *)&RecvBuffer.OutPublic.publicArea.authPolicy; + OutPublic->publicArea.authPolicy.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if (OutPublic->publicArea.authPolicy.size > sizeof(TPMU_HA)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - authPolicy.size error %x\n", OutPublic->publicArea.authPolicy.size)); + return EFI_DEVICE_ERROR; + } + + CopyMem (OutPublic->publicArea.authPolicy.buffer, Buffer, OutPublic->publicArea.authPolicy.size); + Buffer += OutPublic->publicArea.authPolicy.size; + + // TPMU_PUBLIC_PARMS + switch (OutPublic->publicArea.type) { + case TPM_ALG_KEYEDHASH: + OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme) { + case TPM_ALG_HMAC: + OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_XOR: + OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.kdf = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + default: + return EFI_UNSUPPORTED; + } + case TPM_ALG_SYMCIPHER: + OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.symDetail.algorithm) { + case TPM_ALG_AES: + OutPublic->publicArea.parameters.symDetail.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.symDetail.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_SM4: + OutPublic->publicArea.parameters.symDetail.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.symDetail.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_XOR: + OutPublic->publicArea.parameters.symDetail.keyBits.xor = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + break; + case TPM_ALG_RSA: + OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm) { + case TPM_ALG_AES: + OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_SM4: + OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + OutPublic->publicArea.parameters.rsaDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.rsaDetail.scheme.scheme) { + case TPM_ALG_RSASSA: + OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsassa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_RSAPSS: + OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_RSAES: + break; + case TPM_ALG_OAEP: + OutPublic->publicArea.parameters.rsaDetail.scheme.details.oaep.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT32); + break; + case TPM_ALG_ECC: + OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm) { + case TPM_ALG_AES: + OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.eccDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_SM4: + OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.eccDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + OutPublic->publicArea.parameters.eccDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.eccDetail.scheme.scheme) { + case TPM_ALG_ECDSA: + OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_ECDAA: + OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_ECSCHNORR: + OutPublic->publicArea.parameters.eccDetail.scheme.details.ecSchnorr.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_ECDH: + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + OutPublic->publicArea.parameters.eccDetail.curveID = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + OutPublic->publicArea.parameters.eccDetail.kdf.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + switch (OutPublic->publicArea.parameters.eccDetail.kdf.scheme) { + case TPM_ALG_MGF1: + OutPublic->publicArea.parameters.eccDetail.kdf.details.mgf1.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_KDF1_SP800_108: + OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_KDF1_SP800_56a: + OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_KDF2: + OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf2.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_NULL: + break; + default: + return EFI_UNSUPPORTED; + } + break; + default: + return EFI_UNSUPPORTED; + } + + // TPMU_PUBLIC_ID + switch (OutPublic->publicArea.type) { + case TPM_ALG_KEYEDHASH: + OutPublic->publicArea.unique.keyedHash.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if(OutPublic->publicArea.unique.keyedHash.size > sizeof(TPMU_HA)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - keyedHash.size error %x\n", OutPublic->publicArea.unique.keyedHash.size)); + return EFI_DEVICE_ERROR; + } + CopyMem (OutPublic->publicArea.unique.keyedHash.buffer, Buffer, OutPublic->publicArea.unique.keyedHash.size); + Buffer += OutPublic->publicArea.unique.keyedHash.size; + break; + case TPM_ALG_SYMCIPHER: + OutPublic->publicArea.unique.sym.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if(OutPublic->publicArea.unique.sym.size > sizeof(TPMU_HA)) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - sym.size error %x\n", OutPublic->publicArea.unique.sym.size)); + return EFI_DEVICE_ERROR; + } + CopyMem (OutPublic->publicArea.unique.sym.buffer, Buffer, OutPublic->publicArea.unique.sym.size); + Buffer += OutPublic->publicArea.unique.sym.size; + break; + case TPM_ALG_RSA: + OutPublic->publicArea.unique.rsa.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if(OutPublic->publicArea.unique.rsa.size > MAX_RSA_KEY_BYTES) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - rsa.size error %x\n", OutPublic->publicArea.unique.rsa.size)); + return EFI_DEVICE_ERROR; + } + CopyMem (OutPublic->publicArea.unique.rsa.buffer, Buffer, OutPublic->publicArea.unique.rsa.size); + Buffer += OutPublic->publicArea.unique.rsa.size; + break; + case TPM_ALG_ECC: + OutPublic->publicArea.unique.ecc.x.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if (OutPublic->publicArea.unique.ecc.x.size > MAX_ECC_KEY_BYTES) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - ecc.x.size error %x\n", OutPublic->publicArea.unique.ecc.x.size)); + return EFI_DEVICE_ERROR; + } + CopyMem (OutPublic->publicArea.unique.ecc.x.buffer, Buffer, OutPublic->publicArea.unique.ecc.x.size); + Buffer += OutPublic->publicArea.unique.ecc.x.size; + OutPublic->publicArea.unique.ecc.y.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + if (OutPublic->publicArea.unique.ecc.y.size > MAX_ECC_KEY_BYTES) { + DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - ecc.y.size error %x\n", OutPublic->publicArea.unique.ecc.y.size)); + return EFI_DEVICE_ERROR; + } + CopyMem (OutPublic->publicArea.unique.ecc.y.buffer, Buffer, OutPublic->publicArea.unique.ecc.y.size); + Buffer += OutPublic->publicArea.unique.ecc.y.size; + break; + default: + return EFI_UNSUPPORTED; + } + + CopyMem (Name->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16), NameSize); + Name->size = NameSize; + + CopyMem (QualifiedName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16), QualifiedNameSize); + QualifiedName->size = QualifiedNameSize; + + return EFI_SUCCESS; +} -- cgit 1.2.3-korg