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