]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
SecurityPkg: Replace BSD License with BSD+Patent License
[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 DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
107 switch (SwapBytes32 (Response.returnCode)) {
108 case TPM_SUCCESS:
109 return EFI_SUCCESS;
110 default:
111 return EFI_DEVICE_ERROR;
112 }
113 }
114
115 /**
116 Send NV ReadValue command to TPM1.2.
117
118 @param NvIndex The index of the area to set.
119 @param Offset The offset into the area.
120 @param DataSize The size of the data area.
121 @param Data The data to set the area to.
122
123 @retval EFI_SUCCESS Operation completed successfully.
124 @retval EFI_DEVICE_ERROR Unexpected device behavior.
125 **/
126 EFI_STATUS
127 EFIAPI
128 Tpm12NvReadValue (
129 IN TPM_NV_INDEX NvIndex,
130 IN UINT32 Offset,
131 IN OUT UINT32 *DataSize,
132 OUT UINT8 *Data
133 )
134 {
135 EFI_STATUS Status;
136 TPM_CMD_NV_READ_VALUE Command;
137 TPM_RSP_NV_READ_VALUE Response;
138 UINT32 Length;
139
140 //
141 // send Tpm command TPM_ORD_NV_ReadValue
142 //
143 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
144 Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
145 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue);
146 Command.NvIndex = SwapBytes32 (NvIndex);
147 Command.Offset = SwapBytes32 (Offset);
148 Command.DataSize = SwapBytes32 (*DataSize);
149 Length = sizeof (Response);
150 Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
151 if (EFI_ERROR (Status)) {
152 return Status;
153 }
154 DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", SwapBytes32 (Response.Hdr.returnCode)));
155 switch (SwapBytes32 (Response.Hdr.returnCode)) {
156 case TPM_SUCCESS:
157 break;
158 default:
159 return EFI_DEVICE_ERROR;
160 }
161
162 //
163 // Return the response
164 //
165 if (SwapBytes32 (Response.DataSize) > *DataSize) {
166 return EFI_BUFFER_TOO_SMALL;
167 }
168 *DataSize = SwapBytes32 (Response.DataSize);
169 ZeroMem (Data, *DataSize);
170 CopyMem (Data, &Response.Data, *DataSize);
171
172 return EFI_SUCCESS;
173 }
174
175 /**
176 Send NV WriteValue command to TPM1.2.
177
178 @param NvIndex The index of the area to set.
179 @param Offset The offset into the NV Area.
180 @param DataSize The size of the data parameter.
181 @param Data The data to set the area to.
182
183 @retval EFI_SUCCESS Operation completed successfully.
184 @retval EFI_DEVICE_ERROR Unexpected device behavior.
185 **/
186 EFI_STATUS
187 EFIAPI
188 Tpm12NvWriteValue (
189 IN TPM_NV_INDEX NvIndex,
190 IN UINT32 Offset,
191 IN UINT32 DataSize,
192 IN UINT8 *Data
193 )
194 {
195 EFI_STATUS Status;
196 TPM_CMD_NV_WRITE_VALUE Command;
197 UINT32 CommandLength;
198 TPM_RSP_COMMAND_HDR Response;
199 UINT32 ResponseLength;
200
201 if (DataSize > sizeof (Command.Data)) {
202 return EFI_UNSUPPORTED;
203 }
204
205 //
206 // send Tpm command TPM_ORD_NV_WriteValue
207 //
208 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
209 CommandLength = sizeof (Command) - sizeof(Command.Data) + DataSize;
210 Command.Hdr.paramSize = SwapBytes32 (CommandLength);
211 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue);
212 Command.NvIndex = SwapBytes32 (NvIndex);
213 Command.Offset = SwapBytes32 (Offset);
214 Command.DataSize = SwapBytes32 (DataSize);
215 CopyMem (Command.Data, Data, DataSize);
216 ResponseLength = sizeof (Response);
217 Status = Tpm12SubmitCommand (CommandLength, (UINT8 *)&Command, &ResponseLength, (UINT8 *)&Response);
218 if (EFI_ERROR (Status)) {
219 return Status;
220 }
221 DEBUG ((DEBUG_INFO, "Tpm12NvWritedValue - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
222 switch (SwapBytes32 (Response.returnCode)) {
223 case TPM_SUCCESS:
224 return EFI_SUCCESS;
225 default:
226 return EFI_DEVICE_ERROR;
227 }
228 }