1 /** @file 2 Utility functions used by TPM PEI driver. 3 4 Copyright (c) 2005 - 2015, 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 9 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. 12 13 **/ 14 15 #include "TpmComm.h" 16 17 /** 18 Send a command to TPM for execution and return response data. 19 20 @param[in] PeiServices Describes the list of possible PEI Services. 21 @param[in] TisReg TPM register space base address. 22 @param[in] BufferIn Buffer for command data. 23 @param[in] SizeIn Size of command data. 24 @param[in, out] BufferOut Buffer for response data. 25 @param[in, out] SizeOut size of response data. 26 27 @retval EFI_SUCCESS Operation completed successfully. 28 @retval EFI_TIMEOUT The register can't run into the expected status in time. 29 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 30 @retval EFI_DEVICE_ERROR Unexpected device behavior. 31 32 **/ 33 EFI_STATUS 34 TisTpmCommand ( 35 IN EFI_PEI_SERVICES **PeiServices, 36 IN TIS_PC_REGISTERS_PTR TisReg, 37 IN UINT8 *BufferIn, 38 IN UINT32 SizeIn, 39 IN OUT UINT8 *BufferOut, 40 IN OUT UINT32 *SizeOut 41 ); 42 43 /** 44 Send TPM_Startup command to TPM. 45 46 @param[in] PeiServices Describes the list of possible PEI Services. 47 @param[in] TpmHandle TPM handle. 48 @param[in] BootMode Boot mode. 49 50 @retval EFI_SUCCESS Operation completed successfully. 51 @retval EFI_TIMEOUT The register can't run into the expected status in time. 52 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 53 @retval EFI_DEVICE_ERROR Unexpected device behavior. 54 55 **/ 56 EFI_STATUS 57 TpmCommStartup ( 58 IN EFI_PEI_SERVICES **PeiServices, 59 IN TIS_TPM_HANDLE TpmHandle, 60 IN EFI_BOOT_MODE BootMode 61 ) 62 { 63 EFI_STATUS Status; 64 TPM_STARTUP_TYPE TpmSt; 65 UINT32 TpmRecvSize; 66 UINT32 TpmSendSize; 67 TPM_CMD_START_UP SendBuffer; 68 UINT8 RecvBuffer[20]; 69 70 TpmSt = TPM_ST_CLEAR; 71 if (BootMode == BOOT_ON_S3_RESUME) { 72 TpmSt = TPM_ST_STATE; 73 } 74 // 75 // send Tpm command TPM_ORD_Startup 76 // 77 TpmRecvSize = 20; 78 TpmSendSize = sizeof (TPM_CMD_START_UP); 79 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 80 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); 81 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup); 82 SendBuffer.TpmSt = SwapBytes16 (TpmSt); 83 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); 84 return Status; 85 } 86 87 /** 88 Send TPM_ContinueSelfTest command to TPM. 89 90 @param[in] PeiServices Describes the list of possible PEI Services. 91 @param[in] TpmHandle TPM handle. 92 93 @retval EFI_SUCCESS Operation completed successfully. 94 @retval EFI_TIMEOUT The register can't run into the expected status in time. 95 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 96 @retval EFI_DEVICE_ERROR Unexpected device behavior. 97 98 **/ 99 EFI_STATUS 100 TpmCommContinueSelfTest ( 101 IN EFI_PEI_SERVICES **PeiServices, 102 IN TIS_TPM_HANDLE TpmHandle 103 ) 104 { 105 EFI_STATUS Status; 106 UINT32 TpmRecvSize; 107 UINT32 TpmSendSize; 108 TPM_CMD_SELF_TEST SendBuffer; 109 UINT8 RecvBuffer[20]; 110 111 // 112 // send Tpm command TPM_ORD_ContinueSelfTest 113 // 114 TpmRecvSize = 20; 115 TpmSendSize = sizeof (TPM_CMD_SELF_TEST); 116 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 117 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); 118 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ContinueSelfTest); 119 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); 120 return Status; 121 } 122 123 /** 124 Get TPM capability flags. 125 126 @param[in] PeiServices Describes the list of possible PEI Services. 127 @param[in] TpmHandle TPM handle. 128 @param[out] Deactivated Returns deactivated flag. 129 @param[out] LifetimeLock Returns physicalPresenceLifetimeLock permanent flag. 130 @param[out] CmdEnable Returns physicalPresenceCMDEnable permanent flag. 131 132 @retval EFI_SUCCESS Operation completed successfully. 133 @retval EFI_TIMEOUT The register can't run into the expected status in time. 134 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 135 @retval EFI_DEVICE_ERROR Unexpected device behavior. 136 137 **/ 138 EFI_STATUS 139 TpmCommGetCapability ( 140 IN EFI_PEI_SERVICES **PeiServices, 141 IN TIS_TPM_HANDLE TpmHandle, 142 OUT BOOLEAN *Deactivated, OPTIONAL 143 OUT BOOLEAN *LifetimeLock, OPTIONAL 144 OUT BOOLEAN *CmdEnable OPTIONAL 145 ) 146 { 147 EFI_STATUS Status; 148 UINT32 TpmRecvSize; 149 UINT32 TpmSendSize; 150 TPM_CMD_GET_CAPABILITY SendBuffer; 151 UINT8 RecvBuffer[40]; 152 TPM_PERMANENT_FLAGS *TpmPermanentFlags; 153 154 // 155 // send Tpm command TPM_ORD_GetCapability 156 // 157 TpmRecvSize = 40; 158 TpmSendSize = sizeof (TPM_CMD_GET_CAPABILITY); 159 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 160 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); 161 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_GetCapability); 162 SendBuffer.Capability = SwapBytes32 (TPM_CAP_FLAG); 163 SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT)); 164 SendBuffer.CapabilityFlag = SwapBytes32 (TPM_CAP_FLAG_PERMANENT); 165 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); 166 if (EFI_ERROR (Status)) { 167 return Status; 168 } 169 TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)]; 170 if (Deactivated != NULL) { 171 *Deactivated = TpmPermanentFlags->deactivated; 172 } 173 174 if (LifetimeLock != NULL) { 175 *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock; 176 } 177 178 if (CmdEnable != NULL) { 179 *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable; 180 } 181 return Status; 182 } 183 184 /** 185 Extend a TPM PCR. 186 187 @param[in] PeiServices Describes the list of possible PEI Services. 188 @param[in] TpmHandle TPM handle. 189 @param[in] DigestToExtend The 160 bit value representing the event to be recorded. 190 @param[in] PcrIndex The PCR to be updated. 191 @param[out] NewPcrValue New PCR value after extend. 192 193 @retval EFI_SUCCESS Operation completed successfully. 194 @retval EFI_TIMEOUT The register can't run into the expected status in time. 195 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 196 @retval EFI_DEVICE_ERROR Unexpected device behavior. 197 198 **/ 199 EFI_STATUS 200 TpmCommExtend ( 201 IN EFI_PEI_SERVICES **PeiServices, 202 IN TIS_TPM_HANDLE TpmHandle, 203 IN TPM_DIGEST *DigestToExtend, 204 IN TPM_PCRINDEX PcrIndex, 205 OUT TPM_DIGEST *NewPcrValue 206 ) 207 { 208 EFI_STATUS Status; 209 UINT32 TpmSendSize; 210 UINT32 TpmRecvSize; 211 TPM_CMD_EXTEND SendBuffer; 212 UINT8 RecvBuffer[10 + sizeof(TPM_DIGEST)]; 213 214 // 215 // send Tpm command TPM_ORD_Extend 216 // 217 TpmRecvSize = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST); 218 TpmSendSize = sizeof (TPM_CMD_EXTEND); 219 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 220 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); 221 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Extend); 222 SendBuffer.PcrIndex = SwapBytes32 (PcrIndex); 223 CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST)); 224 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); 225 if (EFI_ERROR (Status)) { 226 return Status; 227 } 228 229 if(NewPcrValue != NULL) { 230 CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST)); 231 } 232 233 return Status; 234 } 235 236 237 /** 238 Send TSC_PhysicalPresence command to TPM. 239 240 @param[in] PeiServices Describes the list of possible PEI Services. 241 @param[in] TpmHandle TPM handle. 242 @param[in] PhysicalPresence The state to set the TPMs Physical Presence flags. 243 244 @retval EFI_SUCCESS Operation completed successfully. 245 @retval EFI_TIMEOUT The register can't run into the expected status in time. 246 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 247 @retval EFI_DEVICE_ERROR Unexpected device behavior. 248 249 **/ 250 EFI_STATUS 251 TpmCommPhysicalPresence ( 252 IN EFI_PEI_SERVICES **PeiServices, 253 IN TIS_TPM_HANDLE TpmHandle, 254 IN TPM_PHYSICAL_PRESENCE PhysicalPresence 255 ) 256 { 257 EFI_STATUS Status; 258 UINT32 TpmSendSize; 259 UINT32 TpmRecvSize; 260 TPM_CMD_PHYSICAL_PRESENCE SendBuffer; 261 UINT8 RecvBuffer[10]; 262 263 // 264 // send Tpm command TSC_ORD_PhysicalPresence 265 // 266 TpmRecvSize = 10; 267 TpmSendSize = sizeof (TPM_CMD_PHYSICAL_PRESENCE); 268 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 269 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); 270 SendBuffer.Hdr.ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence); 271 SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence); 272 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); 273 return Status; 274 } 275