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