1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
/** @file
Implement TPM2 Session related command.
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/Tpm2CommandLib.h>
#include <Library/Tpm2DeviceLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#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++;
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 ((DEBUG_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 ((DEBUG_ERROR, "Tpm2StartAuthSession - RecvBufferSize Error - %x\n", RecvBufferSize));
return EFI_DEVICE_ERROR;
}
if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
DEBUG ((DEBUG_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);
if (NonceTPM->size > sizeof (TPMU_HA)) {
DEBUG ((DEBUG_ERROR, "Tpm2StartAuthSession - NonceTPM->size error %x\n", NonceTPM->size));
return EFI_DEVICE_ERROR;
}
CopyMem (NonceTPM->buffer, &RecvBuffer.NonceTPM.buffer, NonceTPM->size);
return EFI_SUCCESS;
}
|