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