TianoCore EDK2 master
Loading...
Searching...
No Matches
TcgMor.c
Go to the documentation of this file.
1
13#include "TcgMor.h"
14
15UINT8 mMorControl;
16
24VOID
25EFIAPI
27 IN EFI_EVENT Event,
28 IN VOID *Context
29 )
30{
31 EFI_STATUS Status;
32 UINTN DataSize;
33
34 if (MOR_CLEAR_MEMORY_VALUE (mMorControl) == 0x0) {
35 //
36 // MorControl is expected, directly return to avoid unnecessary variable operation
37 //
38 return;
39 }
40
41 //
42 // Clear MOR_CLEAR_MEMORY_BIT
43 //
44 DEBUG ((DEBUG_INFO, "TcgMor: Clear MorClearMemory bit\n"));
45 mMorControl &= 0xFE;
46
47 DataSize = sizeof (mMorControl);
48 Status = gRT->SetVariable (
50 &gEfiMemoryOverwriteControlDataGuid,
51 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
52 DataSize,
53 &mMorControl
54 );
55 if (EFI_ERROR (Status)) {
56 DEBUG ((DEBUG_ERROR, "TcgMor: Clear MOR_CLEAR_MEMORY_BIT failure, Status = %r\n", Status));
57 }
58}
59
72VOID
75 IN UINT32 MediaId
76 )
77{
78 EFI_STATUS Status;
79 UINT8 *Buffer;
80 UINTN XferSize;
81 UINTN Len;
82 UINTN Index;
83 BOOLEAN TcgFlag;
84 BOOLEAN IeeeFlag;
86
87 Buffer = NULL;
88 TcgFlag = FALSE;
89 IeeeFlag = FALSE;
90
91 //
92 // ATA8-ACS 7.57.6.1 indicates the Transfer Length field requirements a multiple of 512.
93 // If the length of the TRUSTED RECEIVE parameter data is greater than the Transfer Length,
94 // then the device shall return the TRUSTED RECEIVE parameter data truncated to the requested Transfer Length.
95 //
96 Len = ROUNDUP512 (sizeof (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA));
97 Buffer = AllocateZeroPool (Len);
98
99 if (Buffer == NULL) {
100 return;
101 }
102
103 //
104 // When the Security Protocol field is set to 00h, and SP Specific is set to 0000h in a TRUSTED RECEIVE
105 // command, the device basic information data shall be returned.
106 //
107 Status = Ssp->ReceiveData (
108 Ssp,
109 MediaId,
110 100000000, // Timeout 10-sec
111 0, // SecurityProtocol
112 0, // SecurityProtocolSpecificData
113 Len, // PayloadBufferSize,
114 Buffer, // PayloadBuffer
115 &XferSize
116 );
117 if (EFI_ERROR (Status)) {
118 goto Exit;
119 }
120
121 //
122 // In returned data, the ListLength field indicates the total length, in bytes,
123 // of the supported security protocol list.
124 //
126 Len = ROUNDUP512 (
128 (Data->SupportedSecurityListLength[0] << 8) +
129 (Data->SupportedSecurityListLength[1])
130 );
131
132 //
133 // Free original buffer and allocate new buffer.
134 //
135 FreePool (Buffer);
136 Buffer = AllocateZeroPool (Len);
137 if (Buffer == NULL) {
138 return;
139 }
140
141 //
142 // Read full supported security protocol list from device.
143 //
144 Status = Ssp->ReceiveData (
145 Ssp,
146 MediaId,
147 100000000, // Timeout 10-sec
148 0, // SecurityProtocol
149 0, // SecurityProtocolSpecificData
150 Len, // PayloadBufferSize,
151 Buffer, // PayloadBuffer
152 &XferSize
153 );
154
155 if (EFI_ERROR (Status)) {
156 goto Exit;
157 }
158
160 Len = (Data->SupportedSecurityListLength[0] << 8) + Data->SupportedSecurityListLength[1];
161
162 //
163 // Iterate full supported security protocol list to check if TCG or IEEE 1667 protocol
164 // is supported.
165 //
166 for (Index = 0; Index < Len; Index++) {
167 if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_TCG) {
168 //
169 // Found a TCG device.
170 //
171 TcgFlag = TRUE;
172 DEBUG ((DEBUG_INFO, "This device is a TCG protocol device\n"));
173 break;
174 }
175
176 if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_IEEE1667) {
177 //
178 // Found a IEEE 1667 device.
179 //
180 IeeeFlag = TRUE;
181 DEBUG ((DEBUG_INFO, "This device is a IEEE 1667 protocol device\n"));
182 break;
183 }
184 }
185
186 if (!TcgFlag && !IeeeFlag) {
187 DEBUG ((DEBUG_INFO, "Neither a TCG nor IEEE 1667 protocol device is found\n"));
188 goto Exit;
189 }
190
191 if (TcgFlag) {
192 //
193 // As long as TCG protocol is supported, send out a TPer Reset
194 // TCG command to the device via the TrustedSend command with a non-zero Transfer Length.
195 //
196 Status = Ssp->SendData (
197 Ssp,
198 MediaId,
199 100000000, // Timeout 10-sec
200 SECURITY_PROTOCOL_TCG, // SecurityProtocol
201 0x0400, // SecurityProtocolSpecificData
202 512, // PayloadBufferSize,
203 Buffer // PayloadBuffer
204 );
205
206 if (!EFI_ERROR (Status)) {
207 DEBUG ((DEBUG_INFO, "Send TPer Reset Command Successfully !\n"));
208 } else {
209 DEBUG ((DEBUG_INFO, "Send TPer Reset Command Fail !\n"));
210 }
211 }
212
213 if (IeeeFlag) {
214 //
215 // TBD : Perform a TPer Reset via IEEE 1667 Protocol
216 //
217 DEBUG ((DEBUG_INFO, "IEEE 1667 Protocol didn't support yet!\n"));
218 }
219
220Exit:
221
222 if (Buffer != NULL) {
223 FreePool (Buffer);
224 }
225}
226
234VOID
235EFIAPI
237 IN EFI_EVENT Event,
238 IN VOID *Context
239 )
240{
242 EFI_BLOCK_IO_PROTOCOL *BlockIo;
243 EFI_STATUS Status;
244 UINTN HandleCount;
245 EFI_HANDLE *HandleBuffer;
246 UINTN Index;
247
248 //
249 // Locate all SSP protocol instances.
250 //
251 HandleCount = 0;
252 HandleBuffer = NULL;
253
254 Status = gBS->LocateHandleBuffer (
256 &gEfiStorageSecurityCommandProtocolGuid,
257 NULL,
258 &HandleCount,
259 &HandleBuffer
260 );
261
262 if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) {
263 return;
264 }
265
266 for (Index = 0; Index < HandleCount; Index++) {
267 //
268 // Get the SSP interface.
269 //
270 Status = gBS->HandleProtocol (
271 HandleBuffer[Index],
272 &gEfiStorageSecurityCommandProtocolGuid,
273 (VOID **)&Ssp
274 );
275
276 if (EFI_ERROR (Status)) {
277 continue;
278 }
279
280 Status = gBS->HandleProtocol (
281 HandleBuffer[Index],
282 &gEfiBlockIoProtocolGuid,
283 (VOID **)&BlockIo
284 );
285
286 if (EFI_ERROR (Status)) {
287 continue;
288 }
289
290 InitiateTPerReset (Ssp, BlockIo->Media->MediaId);
291 }
292
293 FreePool (HandleBuffer);
294}
295
306EFIAPI
308 IN EFI_HANDLE ImageHandle,
309 IN EFI_SYSTEM_TABLE *SystemTable
310 )
311{
312 EFI_STATUS Status;
313 UINTN DataSize;
314 EFI_EVENT Event;
315
319
320 DataSize = sizeof (mMorControl);
321 Status = gRT->GetVariable (
323 &gEfiMemoryOverwriteControlDataGuid,
324 NULL,
325 &DataSize,
326 &mMorControl
327 );
328 if (EFI_ERROR (Status)) {
329 //
330 // Set default value to 0
331 //
332 mMorControl = 0;
333 Status = gRT->SetVariable (
335 &gEfiMemoryOverwriteControlDataGuid,
336 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
337 DataSize,
338 &mMorControl
339 );
340 DEBUG ((DEBUG_INFO, "TcgMor: Create MOR variable! Status = %r\n", Status));
341 } else {
342 //
343 // Create a Ready To Boot Event and Clear the MorControl bit in the call back function.
344 //
345 DEBUG ((DEBUG_INFO, "TcgMor: Create ReadyToBoot Event for MorControl Bit cleaning!\n"));
347 TPL_CALLBACK,
349 NULL,
350 &Event
351 );
352 if (EFI_ERROR (Status)) {
353 return Status;
354 }
355
356 //
357 // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
358 //
359 DEBUG ((DEBUG_INFO, "TcgMor: Create EndofDxe Event for Mor TPer Reset!\n"));
360 Status = gBS->CreateEventEx (
361 EVT_NOTIFY_SIGNAL,
362 TPL_CALLBACK,
364 NULL,
365 &gEfiEndOfDxeEventGroupGuid,
366 &Event
367 );
368 if (EFI_ERROR (Status)) {
369 return Status;
370 }
371 }
372
373 return Status;
374}
UINT64 UINTN
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define MOR_CLEAR_MEMORY_VALUE(mor)
#define MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME
EFI_STATUS EFIAPI MorDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: TcgMor.c:307
VOID EFIAPI OnReadyToBoot(IN EFI_EVENT Event, IN VOID *Context)
Definition: TcgMor.c:26
VOID InitiateTPerReset(IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Ssp, IN UINT32 MediaId)
Definition: TcgMor.c:73
VOID EFIAPI TPerResetAtEndOfDxe(IN EFI_EVENT Event, IN VOID *Context)
Definition: TcgMor.c:236
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *ReadyToBootEvent)
Definition: UefiNotTiano.c:164
#define EFI_VARIABLE_NON_VOLATILE
@ ByProtocol
Definition: UefiSpec.h:1518