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