From 967eaccaaa9aa22893882806124c3c7f7abb927b Mon Sep 17 00:00:00 2001 From: "Yao, Jiewen" Date: Fri, 12 Dec 2014 04:34:19 +0000 Subject: Add TPM2 commands which might be used in field upgrade. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Dong, Guo" Reviewed-by: "Long, Qin" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16505 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/Tpm2CommandLib/Tpm2CommandLib.inf | 3 + SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c | 86 ++++++ .../Tpm2CommandLib/Tpm2EnhancedAuthorization.c | 299 +++++++++++++++++++++ SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c | 96 +++++++ SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c | 169 ++++++++++++ 5 files changed, 653 insertions(+) create mode 100644 SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c create mode 100644 SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c create mode 100644 SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c (limited to 'SecurityPkg/Library') diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf b/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf index bc95ce7fa6..740af3f72b 100644 --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf @@ -35,6 +35,9 @@ Tpm2Hierarchy.c Tpm2NVStorage.c Tpm2Startup.c + Tpm2Session.c + Tpm2Context.c + Tpm2EnhancedAuthorization.c Tpm2Test.c Tpm2DictionaryAttack.c Tpm2Miscellaneous.c diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c new file mode 100644 index 0000000000..02a250127a --- /dev/null +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c @@ -0,0 +1,86 @@ +/** @file + Implement TPM2 Context related command. + +Copyright (c) 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include + +#pragma pack(1) + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_DH_CONTEXT FlushHandle; +} TPM2_FLUSH_CONTEXT_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; +} TPM2_FLUSH_CONTEXT_RESPONSE; + +#pragma pack() + +/** + This command causes all context associated with a loaded object or session to be removed from TPM memory. + + @param[in] FlushHandle The handle of the item to flush. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. +**/ +EFI_STATUS +EFIAPI +Tpm2FlushContext ( + IN TPMI_DH_CONTEXT FlushHandle + ) +{ + EFI_STATUS Status; + TPM2_FLUSH_CONTEXT_COMMAND SendBuffer; + TPM2_FLUSH_CONTEXT_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_FlushContext); + + SendBuffer.FlushHandle = SwapBytes32 (FlushHandle); + + 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 ((EFI_D_ERROR, "Tpm2FlushContext - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2FlushContext - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c new file mode 100644 index 0000000000..e302d53561 --- /dev/null +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c @@ -0,0 +1,299 @@ +/** @file + Implement TPM2 EnhancedAuthorization related command. + +Copyright (c) 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include + +#pragma pack(1) + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_DH_ENTITY AuthHandle; + TPMI_SH_POLICY PolicySession; + UINT32 AuthSessionSize; + TPMS_AUTH_COMMAND AuthSession; + TPM2B_NONCE NonceTPM; + TPM2B_DIGEST CpHashA; + TPM2B_NONCE PolicyRef; + INT32 Expiration; +} TPM2_POLICY_SECRET_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; + UINT32 AuthSessionSize; + TPM2B_TIMEOUT Timeout; + TPMT_TK_AUTH PolicyTicket; + TPMS_AUTH_RESPONSE AuthSession; +} TPM2_POLICY_SECRET_RESPONSE; + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_SH_POLICY PolicySession; + TPM_CC Code; +} TPM2_POLICY_COMMAND_CODE_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; +} TPM2_POLICY_COMMAND_CODE_RESPONSE; + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_SH_POLICY PolicySession; +} TPM2_POLICY_GET_DIGEST_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; + TPM2B_DIGEST PolicyHash; +} TPM2_POLICY_GET_DIGEST_RESPONSE; + +#pragma pack() + +/** + This command includes a secret-based authorization to a policy. + The caller proves knowledge of the secret value using an authorization + session using the authValue associated with authHandle. + + @param[in] AuthHandle Handle for an entity providing the authorization + @param[in] PolicySession Handle for the policy session being extended. + @param[in] AuthSession Auth Session context + @param[in] NonceTPM The policy nonce for the session. + @param[in] CpHashA Digest of the command parameters to which this authorization is limited. + @param[in] PolicyRef A reference to a policy relating to the authorization. + @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated. + @param[out] Timeout Time value used to indicate to the TPM when the ticket expires. + @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. +**/ +EFI_STATUS +EFIAPI +Tpm2PolicySecret ( + IN TPMI_DH_ENTITY AuthHandle, + IN TPMI_SH_POLICY PolicySession, + IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL + IN TPM2B_NONCE *NonceTPM, + IN TPM2B_DIGEST *CpHashA, + IN TPM2B_NONCE *PolicyRef, + IN INT32 Expiration, + OUT TPM2B_TIMEOUT *Timeout, + OUT TPMT_TK_AUTH *PolicyTicket + ) +{ + EFI_STATUS Status; + TPM2_POLICY_SECRET_COMMAND SendBuffer; + TPM2_POLICY_SECRET_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + UINT8 *Buffer; + UINT32 SessionInfoSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicySecret); + SendBuffer.AuthHandle = SwapBytes32 (AuthHandle); + SendBuffer.PolicySession = SwapBytes32 (PolicySession); + + // + // Add in Auth session + // + Buffer = (UINT8 *)&SendBuffer.AuthSession; + + // sessionInfoSize + SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); + Buffer += SessionInfoSize; + SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize); + + // + // Real data + // + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NonceTPM->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size); + Buffer += NonceTPM->size; + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, CpHashA->buffer, CpHashA->size); + Buffer += CpHashA->size; + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size); + Buffer += PolicyRef->size; + + WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration)); + Buffer += sizeof(UINT32); + + SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&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 ((EFI_D_ERROR, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + // + // Return the response + // + Buffer = (UINT8 *)&RecvBuffer.Timeout; + Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + CopyMem (Timeout->buffer, Buffer, Timeout->size); + + PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer)); + Buffer += sizeof(UINT32); + PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer)); + Buffer += sizeof(UINT16); + CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size); + + return EFI_SUCCESS; +} + +/** + This command indicates that the authorization will be limited to a specific command code. + + @param[in] PolicySession Handle for the policy session being extended. + @param[in] Code The allowed commandCode. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. +**/ +EFI_STATUS +EFIAPI +Tpm2PolicyCommandCode ( + IN TPMI_SH_POLICY PolicySession, + IN TPM_CC Code + ) +{ + EFI_STATUS Status; + TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer; + TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode); + + SendBuffer.PolicySession = SwapBytes32 (PolicySession); + SendBuffer.Code = SwapBytes32 (Code); + + 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 ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This command returns the current policyDigest of the session. This command allows the TPM + to be used to perform the actions required to precompute the authPolicy for an object. + + @param[in] PolicySession Handle for the policy session. + @param[out] PolicyHash the current value of the policyHash of policySession. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. +**/ +EFI_STATUS +EFIAPI +Tpm2PolicyGetDigest ( + IN TPMI_SH_POLICY PolicySession, + OUT TPM2B_DIGEST *PolicyHash + ) +{ + EFI_STATUS Status; + TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer; + TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest); + + SendBuffer.PolicySession = SwapBytes32 (PolicySession); + + 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 ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + // + // Return the response + // + PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size); + CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size); + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c index 9eb4c9c384..1c33c2de2a 100644 --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c @@ -21,6 +21,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #pragma pack(1) +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_RH_HIERARCHY AuthHandle; + UINT32 AuthSessionSize; + TPMS_AUTH_COMMAND AuthSession; + TPM2B_DIGEST AuthPolicy; + TPMI_ALG_HASH HashAlg; +} TPM2_SET_PRIMARY_POLICY_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; + UINT32 AuthSessionSize; + TPMS_AUTH_RESPONSE AuthSession; +} TPM2_SET_PRIMARY_POLICY_RESPONSE; + typedef struct { TPM2_COMMAND_HEADER Header; TPMI_RH_CLEAR AuthHandle; @@ -105,6 +120,87 @@ typedef struct { #pragma pack() +/** + This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the + storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy). + + @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated + @param[in] AuthSession Auth Session context + @param[in] AuthPolicy An authorization policy hash + @param[in] HashAlg The hash algorithm to use for the policy + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2SetPrimaryPolicy ( + IN TPMI_RH_HIERARCHY_AUTH AuthHandle, + IN TPMS_AUTH_COMMAND *AuthSession, + IN TPM2B_DIGEST *AuthPolicy, + IN TPMI_ALG_HASH HashAlg + ) +{ + EFI_STATUS Status; + TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer; + TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + UINT8 *Buffer; + UINT32 SessionInfoSize; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetPrimaryPolicy); + + SendBuffer.AuthHandle = SwapBytes32 (AuthHandle); + + // + // Add in Auth session + // + Buffer = (UINT8 *)&SendBuffer.AuthSession; + + // sessionInfoSize + SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); + Buffer += SessionInfoSize; + SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize); + + // + // Real data + // + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(AuthPolicy->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size); + Buffer += AuthPolicy->size; + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg)); + Buffer += sizeof(UINT16); + + SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&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 ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + /** This command removes all TPM context associated with a specific Owner. diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c new file mode 100644 index 0000000000..2cbc6272d0 --- /dev/null +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c @@ -0,0 +1,169 @@ +/** @file + Implement TPM2 Session related command. + +Copyright (c) 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include + +#pragma pack(1) + +typedef struct { + TPM2_COMMAND_HEADER Header; + TPMI_DH_OBJECT TpmKey; + TPMI_DH_ENTITY Bind; + TPM2B_NONCE NonceCaller; + TPM2B_ENCRYPTED_SECRET Salt; + TPM_SE SessionType; + TPMT_SYM_DEF Symmetric; + TPMI_ALG_HASH AuthHash; +} TPM2_START_AUTH_SESSION_COMMAND; + +typedef struct { + TPM2_RESPONSE_HEADER Header; + TPMI_SH_AUTH_SESSION SessionHandle; + TPM2B_NONCE NonceTPM; +} TPM2_START_AUTH_SESSION_RESPONSE; + +#pragma pack() + +/** + This command is used to start an authorization session using alternative methods of + establishing the session key (sessionKey) that is used for authorization and encrypting value. + + @param[in] TpmKey Handle of a loaded decrypt key used to encrypt salt. + @param[in] Bind Entity providing the authValue. + @param[in] NonceCaller Initial nonceCaller, sets nonce size for the session. + @param[in] Salt Value encrypted according to the type of tpmKey. + @param[in] SessionType Indicates the type of the session. + @param[in] Symmetric The algorithm and key size for parameter encryption. + @param[in] AuthHash Hash algorithm to use for the session. + @param[out] SessionHandle Handle for the newly created session. + @param[out] NonceTPM The initial nonce from the TPM, used in the computation of the sessionKey. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. +**/ +EFI_STATUS +EFIAPI +Tpm2StartAuthSession ( + IN TPMI_DH_OBJECT TpmKey, + IN TPMI_DH_ENTITY Bind, + IN TPM2B_NONCE *NonceCaller, + IN TPM2B_ENCRYPTED_SECRET *Salt, + IN TPM_SE SessionType, + IN TPMT_SYM_DEF *Symmetric, + IN TPMI_ALG_HASH AuthHash, + OUT TPMI_SH_AUTH_SESSION *SessionHandle, + OUT TPM2B_NONCE *NonceTPM + ) +{ + EFI_STATUS Status; + TPM2_START_AUTH_SESSION_COMMAND SendBuffer; + TPM2_START_AUTH_SESSION_RESPONSE RecvBuffer; + UINT32 SendBufferSize; + UINT32 RecvBufferSize; + UINT8 *Buffer; + + // + // Construct command + // + SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); + SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_StartAuthSession); + + SendBuffer.TpmKey = SwapBytes32 (TpmKey); + SendBuffer.Bind = SwapBytes32 (Bind); + Buffer = (UINT8 *)&SendBuffer.NonceCaller; + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NonceCaller->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, NonceCaller->buffer, NonceCaller->size); + Buffer += NonceCaller->size; + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Salt->size)); + Buffer += sizeof(UINT16); + CopyMem (Buffer, Salt->secret, Salt->size); + Buffer += Salt->size; + + *(TPM_SE *)Buffer = SessionType; + Buffer += sizeof(UINT8); + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->algorithm)); + Buffer += sizeof(UINT16); + switch (Symmetric->algorithm) { + case TPM_ALG_NULL: + break; + case TPM_ALG_AES: + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.aes)); + Buffer += sizeof(UINT16); + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.aes)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_SM4: + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.SM4)); + Buffer += sizeof(UINT16); + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.SM4)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_SYMCIPHER: + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.sym)); + Buffer += sizeof(UINT16); + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.sym)); + Buffer += sizeof(UINT16); + break; + case TPM_ALG_XOR: + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.xor)); + Buffer += sizeof(UINT16); + break; + default: + ASSERT (FALSE); + DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - Symmetric->algorithm - %x\n", Symmetric->algorithm)); + return EFI_UNSUPPORTED; + } + + WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthHash)); + Buffer += sizeof(UINT16); + + SendBufferSize = (UINT32) ((UINTN)Buffer - (UINTN)&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 ((EFI_D_ERROR, "Tpm2StartAuthSession - RecvBufferSize Error - %x\n", RecvBufferSize)); + return EFI_DEVICE_ERROR; + } + if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); + return EFI_DEVICE_ERROR; + } + + // + // Return the response + // + *SessionHandle = SwapBytes32 (RecvBuffer.SessionHandle); + NonceTPM->size = SwapBytes16 (RecvBuffer.NonceTPM.size); + CopyMem (NonceTPM->buffer, &RecvBuffer.NonceTPM.buffer, NonceTPM->size); + + return EFI_SUCCESS; +} -- cgit v1.2.3