1 /** @file 2 Implement TPM2 Startup related command. 3 4 Copyright (c) 2013 - 2016, 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 <IndustryStandard/UefiTcgPlatform.h> 16 #include <Library/Tpm2CommandLib.h> 17 #include <Library/Tpm2DeviceLib.h> 18 #include <Library/BaseMemoryLib.h> 19 #include <Library/BaseLib.h> 20 #include <Library/DebugLib.h> 21 22 #pragma pack(1) 23 24 typedef struct { 25 TPM2_COMMAND_HEADER Header; 26 TPM_SU StartupType; 27 } TPM2_STARTUP_COMMAND; 28 29 typedef struct { 30 TPM2_RESPONSE_HEADER Header; 31 } TPM2_STARTUP_RESPONSE; 32 33 typedef struct { 34 TPM2_COMMAND_HEADER Header; 35 TPM_SU ShutdownType; 36 } TPM2_SHUTDOWN_COMMAND; 37 38 typedef struct { 39 TPM2_RESPONSE_HEADER Header; 40 } TPM2_SHUTDOWN_RESPONSE; 41 42 #pragma pack() 43 44 /** 45 Send Startup command to TPM2. 46 47 @param[in] StartupType TPM_SU_CLEAR or TPM_SU_STATE 48 49 @retval EFI_SUCCESS Operation completed successfully. 50 @retval EFI_DEVICE_ERROR Unexpected device behavior. 51 **/ 52 EFI_STATUS 53 EFIAPI 54 Tpm2Startup ( 55 IN TPM_SU StartupType 56 ) 57 { 58 EFI_STATUS Status; 59 TPM2_STARTUP_COMMAND Cmd; 60 TPM2_STARTUP_RESPONSE Res; 61 UINT32 ResultBufSize; 62 TPM_RC ResponseCode; 63 64 Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); 65 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 66 Cmd.Header.commandCode = SwapBytes32(TPM_CC_Startup); 67 Cmd.StartupType = SwapBytes16(StartupType); 68 69 ResultBufSize = sizeof(Res); 70 Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); 71 if (EFI_ERROR(Status)) { 72 return Status; 73 } 74 75 ResponseCode = SwapBytes32(Res.Header.responseCode); 76 switch (ResponseCode) { 77 case TPM_RC_SUCCESS: 78 case TPM_RC_INITIALIZE: 79 // TPM_RC_INITIALIZE can be returned if Tpm2Startup is not required. 80 return EFI_SUCCESS; 81 default: 82 DEBUG ((EFI_D_ERROR, "Tpm2Startup: Response Code error! 0x%08x\r\n", ResponseCode)); 83 return EFI_DEVICE_ERROR; 84 } 85 } 86 87 /** 88 Send Shutdown command to TPM2. 89 90 @param[in] ShutdownType TPM_SU_CLEAR or TPM_SU_STATE. 91 92 @retval EFI_SUCCESS Operation completed successfully. 93 @retval EFI_DEVICE_ERROR Unexpected device behavior. 94 **/ 95 EFI_STATUS 96 EFIAPI 97 Tpm2Shutdown ( 98 IN TPM_SU ShutdownType 99 ) 100 { 101 EFI_STATUS Status; 102 TPM2_SHUTDOWN_COMMAND Cmd; 103 TPM2_SHUTDOWN_RESPONSE Res; 104 UINT32 ResultBufSize; 105 106 Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); 107 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 108 Cmd.Header.commandCode = SwapBytes32(TPM_CC_Shutdown); 109 Cmd.ShutdownType = SwapBytes16(ShutdownType); 110 111 ResultBufSize = sizeof(Res); 112 Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); 113 if (EFI_ERROR(Status)) { 114 return Status; 115 } 116 117 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 118 DEBUG ((EFI_D_ERROR, "Tpm2Shutdown: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 119 return EFI_DEVICE_ERROR; 120 } 121 122 return EFI_SUCCESS; 123 } 124