1 /** @file
2 Implement TPM1.2 NV storage related command.
3
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved. <BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <PiPei.h>
17 #include <Library/Tpm12CommandLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/Tpm12DeviceLib.h>
22
23 //
24 // Max TPM NV value length
25 //
26 #define TPMNVVALUELENGTH 1024
27
28 #pragma pack(1)
29
30 typedef struct {
31 TPM_RQU_COMMAND_HDR Hdr;
32 TPM12_NV_DATA_PUBLIC PubInfo;
33 TPM_ENCAUTH EncAuth;
34 } TPM_CMD_NV_DEFINE_SPACE;
35
36 typedef struct {
37 TPM_RQU_COMMAND_HDR Hdr;
38 TPM_NV_INDEX NvIndex;
39 UINT32 Offset;
40 UINT32 DataSize;
41 } TPM_CMD_NV_READ_VALUE;
42
43 typedef struct {
44 TPM_RSP_COMMAND_HDR Hdr;
45 UINT32 DataSize;
46 UINT8 Data[TPMNVVALUELENGTH];
47 } TPM_RSP_NV_READ_VALUE;
48
49 typedef struct {
50 TPM_RQU_COMMAND_HDR Hdr;
51 TPM_NV_INDEX NvIndex;
52 UINT32 Offset;
53 UINT32 DataSize;
54 UINT8 Data[TPMNVVALUELENGTH];
55 } TPM_CMD_NV_WRITE_VALUE;
56
57 #pragma pack()
58
59 /**
60 Send NV DefineSpace command to TPM1.2.
61
62 @param PubInfo The public parameters of the NV area.
63 @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization.
64
65 @retval EFI_SUCCESS Operation completed successfully.
66 @retval EFI_DEVICE_ERROR Unexpected device behavior.
67 **/
68 EFI_STATUS
69 EFIAPI
Tpm12NvDefineSpace(IN TPM12_NV_DATA_PUBLIC * PubInfo,IN TPM_ENCAUTH * EncAuth)70 Tpm12NvDefineSpace (
71 IN TPM12_NV_DATA_PUBLIC *PubInfo,
72 IN TPM_ENCAUTH *EncAuth
73 )
74 {
75 EFI_STATUS Status;
76 TPM_CMD_NV_DEFINE_SPACE Command;
77 TPM_RSP_COMMAND_HDR Response;
78 UINT32 Length;
79
80 //
81 // send Tpm command TPM_ORD_NV_DefineSpace
82 //
83 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
84 Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
85 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace);
86 Command.PubInfo.tag = SwapBytes16 (PubInfo->tag);
87 Command.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex);
88 Command.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect);
89 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0];
90 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1];
91 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2];
92 Command.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease;
93 CopyMem (&Command.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease));
94 Command.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect);
95 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0];
96 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1];
97 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2];
98 Command.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease;
99 CopyMem (&Command.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease));
100 Command.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag);
101 Command.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes);
102 Command.PubInfo.bReadSTClear = PubInfo->bReadSTClear;
103 Command.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear;
104 Command.PubInfo.bWriteDefine = PubInfo->bWriteDefine;
105 Command.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize);
106 CopyMem (&Command.EncAuth, EncAuth, sizeof(*EncAuth));
107 Length = sizeof (Response);
108 Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
109 if (EFI_ERROR (Status)) {
110 return Status;
111 }
112 DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
113 switch (SwapBytes32 (Response.returnCode)) {
114 case TPM_SUCCESS:
115 return EFI_SUCCESS;
116 default:
117 return EFI_DEVICE_ERROR;
118 }
119 }
120
121 /**
122 Send NV ReadValue command to TPM1.2.
123
124 @param NvIndex The index of the area to set.
125 @param Offset The offset into the area.
126 @param DataSize The size of the data area.
127 @param Data The data to set the area to.
128
129 @retval EFI_SUCCESS Operation completed successfully.
130 @retval EFI_DEVICE_ERROR Unexpected device behavior.
131 **/
132 EFI_STATUS
133 EFIAPI
Tpm12NvReadValue(IN TPM_NV_INDEX NvIndex,IN UINT32 Offset,IN OUT UINT32 * DataSize,OUT UINT8 * Data)134 Tpm12NvReadValue (
135 IN TPM_NV_INDEX NvIndex,
136 IN UINT32 Offset,
137 IN OUT UINT32 *DataSize,
138 OUT UINT8 *Data
139 )
140 {
141 EFI_STATUS Status;
142 TPM_CMD_NV_READ_VALUE Command;
143 TPM_RSP_NV_READ_VALUE Response;
144 UINT32 Length;
145
146 //
147 // send Tpm command TPM_ORD_NV_ReadValue
148 //
149 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
150 Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
151 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue);
152 Command.NvIndex = SwapBytes32 (NvIndex);
153 Command.Offset = SwapBytes32 (Offset);
154 Command.DataSize = SwapBytes32 (*DataSize);
155 Length = sizeof (Response);
156 Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
157 if (EFI_ERROR (Status)) {
158 return Status;
159 }
160 DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", SwapBytes32 (Response.Hdr.returnCode)));
161 switch (SwapBytes32 (Response.Hdr.returnCode)) {
162 case TPM_SUCCESS:
163 break;
164 default:
165 return EFI_DEVICE_ERROR;
166 }
167
168 //
169 // Return the response
170 //
171 if (SwapBytes32 (Response.DataSize) > *DataSize) {
172 return EFI_BUFFER_TOO_SMALL;
173 }
174 *DataSize = SwapBytes32 (Response.DataSize);
175 ZeroMem (Data, *DataSize);
176 CopyMem (Data, &Response.Data, *DataSize);
177
178 return EFI_SUCCESS;
179 }
180
181 /**
182 Send NV WriteValue command to TPM1.2.
183
184 @param NvIndex The index of the area to set.
185 @param Offset The offset into the NV Area.
186 @param DataSize The size of the data parameter.
187 @param Data The data to set the area to.
188
189 @retval EFI_SUCCESS Operation completed successfully.
190 @retval EFI_DEVICE_ERROR Unexpected device behavior.
191 **/
192 EFI_STATUS
193 EFIAPI
Tpm12NvWriteValue(IN TPM_NV_INDEX NvIndex,IN UINT32 Offset,IN UINT32 DataSize,IN UINT8 * Data)194 Tpm12NvWriteValue (
195 IN TPM_NV_INDEX NvIndex,
196 IN UINT32 Offset,
197 IN UINT32 DataSize,
198 IN UINT8 *Data
199 )
200 {
201 EFI_STATUS Status;
202 TPM_CMD_NV_WRITE_VALUE Command;
203 UINT32 CommandLength;
204 TPM_RSP_COMMAND_HDR Response;
205 UINT32 ResponseLength;
206
207 if (DataSize > sizeof (Command.Data)) {
208 return EFI_UNSUPPORTED;
209 }
210
211 //
212 // send Tpm command TPM_ORD_NV_WriteValue
213 //
214 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
215 CommandLength = sizeof (Command) - sizeof(Command.Data) + DataSize;
216 Command.Hdr.paramSize = SwapBytes32 (CommandLength);
217 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue);
218 Command.NvIndex = SwapBytes32 (NvIndex);
219 Command.Offset = SwapBytes32 (Offset);
220 Command.DataSize = SwapBytes32 (DataSize);
221 CopyMem (Command.Data, Data, DataSize);
222 ResponseLength = sizeof (Response);
223 Status = Tpm12SubmitCommand (CommandLength, (UINT8 *)&Command, &ResponseLength, (UINT8 *)&Response);
224 if (EFI_ERROR (Status)) {
225 return Status;
226 }
227 DEBUG ((DEBUG_INFO, "Tpm12NvWritedValue - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
228 switch (SwapBytes32 (Response.returnCode)) {
229 case TPM_SUCCESS:
230 return EFI_SUCCESS;
231 default:
232 return EFI_DEVICE_ERROR;
233 }
234 }
235