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
Tpm2Startup(IN TPM_SU StartupType)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
Tpm2Shutdown(IN TPM_SU ShutdownType)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