1 /** @file
2   Implement TPM1.2 Startup related command.
3 
4 Copyright (c) 2013, 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 <Uefi.h>
16 #include <IndustryStandard/Tpm12.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/Tpm12DeviceLib.h>
20 
21 #pragma pack(1)
22 
23 typedef struct {
24   TPM_RQU_COMMAND_HDR   Hdr;
25   TPM_STARTUP_TYPE      TpmSt;
26 } TPM_CMD_START_UP;
27 
28 typedef struct {
29   TPM_RSP_COMMAND_HDR   Hdr;
30 } TPM_RSP_START_UP;
31 
32 typedef struct {
33   TPM_RQU_COMMAND_HDR   Hdr;
34 } TPM_CMD_SAVE_STATE;
35 
36 typedef struct {
37   TPM_RSP_COMMAND_HDR   Hdr;
38 } TPM_RSP_SAVE_STATE;
39 
40 #pragma pack()
41 
42 /**
43   Send Startup command to TPM1.2.
44 
45   @param TpmSt           Startup Type.
46 
47   @retval EFI_SUCCESS      Operation completed successfully.
48   @retval EFI_DEVICE_ERROR Unexpected device behavior.
49 **/
50 EFI_STATUS
51 EFIAPI
Tpm12Startup(IN TPM_STARTUP_TYPE TpmSt)52 Tpm12Startup (
53   IN TPM_STARTUP_TYPE          TpmSt
54   )
55 {
56   EFI_STATUS                        Status;
57   UINT32                            TpmRecvSize;
58   UINT32                            TpmSendSize;
59   TPM_CMD_START_UP                  SendBuffer;
60   TPM_RSP_START_UP                  RecvBuffer;
61   UINT32                            ReturnCode;
62 
63   //
64   // send Tpm command TPM_ORD_Startup
65   //
66   TpmRecvSize               = sizeof (TPM_RSP_START_UP);
67   TpmSendSize               = sizeof (TPM_CMD_START_UP);
68   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
69   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
70   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Startup);
71   SendBuffer.TpmSt          = SwapBytes16 (TpmSt);
72 
73   Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);
74   if (EFI_ERROR (Status)) {
75     return Status;
76   }
77   ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);
78   switch (ReturnCode) {
79   case TPM_SUCCESS:
80   case TPM_INVALID_POSTINIT:
81     // In warm reset, TPM may response TPM_INVALID_POSTINIT
82     return EFI_SUCCESS;
83   default:
84     return EFI_DEVICE_ERROR;
85   }
86 }
87 
88 /**
89   Send SaveState command to TPM1.2.
90 
91   @retval EFI_SUCCESS      Operation completed successfully.
92   @retval EFI_DEVICE_ERROR Unexpected device behavior.
93 **/
94 EFI_STATUS
95 EFIAPI
Tpm12SaveState(VOID)96 Tpm12SaveState (
97   VOID
98   )
99 {
100   EFI_STATUS                        Status;
101   UINT32                            TpmRecvSize;
102   UINT32                            TpmSendSize;
103   TPM_CMD_SAVE_STATE                SendBuffer;
104   TPM_RSP_SAVE_STATE                RecvBuffer;
105   UINT32                            ReturnCode;
106 
107   //
108   // send Tpm command TPM_ORD_SaveState
109   //
110   TpmRecvSize               = sizeof (TPM_RSP_SAVE_STATE);
111   TpmSendSize               = sizeof (TPM_CMD_SAVE_STATE);
112   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
113   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
114   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_SaveState);
115 
116   Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);
117   if (EFI_ERROR (Status)) {
118     return Status;
119   }
120   ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);
121   switch (ReturnCode) {
122   case TPM_SUCCESS:
123     return EFI_SUCCESS;
124   default:
125     return EFI_DEVICE_ERROR;
126   }
127 }
128