]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / TcgStorageOpalLib / TcgStorageOpalCore.c
1 /** @file
2 Public API for Opal Core library.
3
4 Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Uefi.h>
10 #include <Library/BaseLib.h>
11 #include <Library/TimerLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/TcgStorageOpalLib.h>
15
16 #include "TcgStorageOpalLibInternal.h"
17
18 #pragma pack(1)
19 typedef struct {
20 UINT8 HardwareReset : 1;
21 UINT8 Reserved : 7;
22 } TCG_BLOCK_SID_CLEAR_EVENTS;
23 #pragma pack()
24
25 #define TRUSTED_COMMAND_TIMEOUT_NS ((UINT64) 5 * ((UINT64)(1000000)) * 1000) // 5 seconds
26 #define BUFFER_SIZE 512
27
28 /**
29 The function performs a Trusted Send of a Buffer containing a TCG_COM_PACKET.
30
31 @param[in] Sscp The input Ssc Protocol.
32 @param[in] MediaId The input Media id info used by Ssc Protocol.
33 @param[in] SecurityProtocol Security Protocol
34 @param[in] SpSpecific Security Protocol Specific
35 @param[in] TransferLength Transfer Length of Buffer (in bytes) - always a multiple of 512
36 @param[in] Buffer Address of Data to transfer
37 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
38
39 **/
40 TCG_RESULT
41 OpalTrustedSend (
42 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp,
43 UINT32 MediaId,
44 UINT8 SecurityProtocol,
45 UINT16 SpSpecific,
46 UINTN TransferLength,
47 VOID *Buffer,
48 UINTN BufferSize
49 )
50 {
51 UINTN TransferLength512;
52 EFI_STATUS Status;
53
54 //
55 // Round transferLength up to a 512-byte multiple
56 //
57 TransferLength512 = (TransferLength + 511) & ~(UINTN)511;
58
59 if (TransferLength512 > BufferSize) {
60 return TcgResultFailureBufferTooSmall;
61 }
62
63 ZeroMem ((UINT8 *)Buffer + TransferLength, TransferLength512 - TransferLength);
64
65 Status = Sscp->SendData (
66 Sscp,
67 MediaId,
68 TRUSTED_COMMAND_TIMEOUT_NS,
69 SecurityProtocol,
70 SwapBytes16 (SpSpecific),
71 TransferLength512,
72 Buffer
73 );
74
75 return Status == EFI_SUCCESS ? TcgResultSuccess : TcgResultFailure;
76 }
77
78 /**
79
80 The function performs a Trusted Receive of a Buffer containing a TCG_COM_PACKET.
81
82 @param[in] Sscp The input Ssc Protocol.
83 @param[in] MediaId The input Media id info used by Ssc Protocol.
84 @param[in] SecurityProtocol Security Protocol
85 @param[in] SpSpecific Security Protocol Specific
86 @param[in] Buffer Address of Data to transfer
87 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
88 @param[in] EstimateTimeCost Estimate the time needed.
89
90 **/
91 TCG_RESULT
92 OpalTrustedRecv (
93 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp,
94 UINT32 MediaId,
95 UINT8 SecurityProtocol,
96 UINT16 SpSpecific,
97 VOID *Buffer,
98 UINTN BufferSize,
99 UINT32 EstimateTimeCost
100 )
101 {
102 UINTN TransferLength512;
103 UINT32 Tries;
104 TCG_COM_PACKET *ComPacket;
105 UINT32 Length;
106 UINT32 OutstandingData;
107 EFI_STATUS Status;
108 UINTN TransferSize;
109
110 //
111 // Round Buffer Size down to a 512-byte multiple
112 //
113 TransferLength512 = BufferSize & ~(UINTN)511;
114 Tries = 0;
115 ComPacket = NULL;
116 Length = 0;
117 OutstandingData = 0;
118
119 if (TransferLength512 < sizeof (TCG_COM_PACKET)) {
120 DEBUG ((DEBUG_INFO, "transferLength %u too small for ComPacket\n", TransferLength512));
121 return TcgResultFailureBufferTooSmall;
122 }
123
124 //
125 // Some devices respond with Length = 0 and OutstandingData = 1 to indicate that processing is not yet completed,
126 // so we need to retry the IF-RECV to get the actual Data.
127 // See TCG Core Spec v2 Table 45 IF-RECV ComPacket Field Values Summary
128 // This is an arbitrary number of retries, not from the spec.
129 //
130 // if user input estimate time cost(second level) value bigger than 10s, base on user input value to wait.
131 // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms = 10s
132 //
133 if (EstimateTimeCost > 10) {
134 Tries = EstimateTimeCost * 500; // 500 = 1000 * 1000 / 2000;
135 } else {
136 Tries = 5000;
137 }
138
139 while ((Tries--) > 0) {
140 ZeroMem (Buffer, BufferSize);
141 TransferSize = 0;
142
143 Status = Sscp->ReceiveData (
144 Sscp,
145 MediaId,
146 TRUSTED_COMMAND_TIMEOUT_NS,
147 SecurityProtocol,
148 SwapBytes16 (SpSpecific),
149 TransferLength512,
150 Buffer,
151 &TransferSize
152 );
153 if (EFI_ERROR (Status)) {
154 return TcgResultFailure;
155 }
156
157 if ((SecurityProtocol != TCG_OPAL_SECURITY_PROTOCOL_1) && (SecurityProtocol != TCG_OPAL_SECURITY_PROTOCOL_2)) {
158 return TcgResultSuccess;
159 }
160
161 if (SpSpecific == TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY) {
162 return TcgResultSuccess;
163 }
164
165 ComPacket = (TCG_COM_PACKET *)Buffer;
166 Length = SwapBytes32 (ComPacket->LengthBE);
167 OutstandingData = SwapBytes32 (ComPacket->OutstandingDataBE);
168
169 if ((Length != 0) && (OutstandingData == 0)) {
170 return TcgResultSuccess;
171 }
172
173 //
174 // Delay for 2 ms
175 //
176 MicroSecondDelay (2000);
177 }
178
179 return TcgResultFailure;
180 }
181
182 /**
183 The function performs send, recv, check comIDs, check method status action.
184
185 @param[in] Session OPAL_SESSION related to this method..
186 @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512
187 @param[in] Buffer Address of Data to transfer
188 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
189 @param[in] ParseStruct Structure used to parse received TCG response.
190 @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
191 @param[in] EstimateTimeCost Estimate the time need to for the method.
192 **/
193 TCG_RESULT
194 EFIAPI
195 OpalPerformMethod (
196 OPAL_SESSION *Session,
197 UINT32 SendSize,
198 VOID *Buffer,
199 UINT32 BufferSize,
200 TCG_PARSE_STRUCT *ParseStruct,
201 UINT8 *MethodStatus,
202 UINT32 EstimateTimeCost
203 )
204 {
205 NULL_CHECK (Session);
206 NULL_CHECK (MethodStatus);
207
208 ERROR_CHECK (
209 OpalTrustedSend (
210 Session->Sscp,
211 Session->MediaId,
212 TCG_OPAL_SECURITY_PROTOCOL_1,
213 Session->OpalBaseComId,
214 SendSize,
215 Buffer,
216 BufferSize
217 )
218 );
219
220 ERROR_CHECK (
221 OpalTrustedRecv (
222 Session->Sscp,
223 Session->MediaId,
224 TCG_OPAL_SECURITY_PROTOCOL_1,
225 Session->OpalBaseComId,
226 Buffer,
227 BufferSize,
228 EstimateTimeCost
229 )
230 );
231
232 ERROR_CHECK (TcgInitTcgParseStruct (ParseStruct, Buffer, BufferSize));
233 ERROR_CHECK (TcgCheckComIds (ParseStruct, Session->OpalBaseComId, Session->ComIdExtension));
234 ERROR_CHECK (TcgGetMethodStatus (ParseStruct, MethodStatus));
235
236 return TcgResultSuccess;
237 }
238
239 /**
240 Trig the block sid action.
241
242 @param[in] Session OPAL_SESSION related to this method..
243 @param[in] HardwareReset Whether need to do hardware reset.
244
245 **/
246 TCG_RESULT
247 EFIAPI
248 OpalBlockSid (
249 OPAL_SESSION *Session,
250 BOOLEAN HardwareReset
251 )
252 {
253 UINT8 Buffer[BUFFER_SIZE];
254 TCG_BLOCK_SID_CLEAR_EVENTS *ClearEvents;
255
256 NULL_CHECK (Session);
257
258 //
259 // Set Hardware Reset bit
260 //
261 ClearEvents = (TCG_BLOCK_SID_CLEAR_EVENTS *)&Buffer[0];
262
263 ClearEvents->Reserved = 0;
264 ClearEvents->HardwareReset = HardwareReset;
265
266 return (OpalTrustedSend (
267 Session->Sscp,
268 Session->MediaId,
269 TCG_OPAL_SECURITY_PROTOCOL_2,
270 TCG_BLOCKSID_COMID, // hardcode ComID 0x0005
271 1,
272 Buffer,
273 BUFFER_SIZE
274 ));
275 }
276
277 /**
278
279 Reverts device using Admin SP Revert method.
280
281 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
282
283 **/
284 TCG_RESULT
285 EFIAPI
286 OpalPsidRevert (
287 OPAL_SESSION *AdminSpSession
288 )
289 {
290 //
291 // Now that base comid is known, start Session
292 // we'll attempt to start Session as PSID authority
293 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
294 //
295 TCG_CREATE_STRUCT CreateStruct;
296 TCG_PARSE_STRUCT ParseStruct;
297 UINT32 Size;
298 UINT8 Buffer[BUFFER_SIZE];
299 UINT8 MethodStatus;
300
301 NULL_CHECK (AdminSpSession);
302
303 //
304 // Send Revert action on Admin SP
305 //
306 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buffer, BUFFER_SIZE));
307 ERROR_CHECK (TcgStartComPacket (&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));
308 ERROR_CHECK (TcgStartPacket (&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));
309 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
310 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_ADMIN_SP_REVERT_METHOD));
311 ERROR_CHECK (TcgStartParameters (&CreateStruct));
312 ERROR_CHECK (TcgEndParameters (&CreateStruct));
313 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
314 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
315 ERROR_CHECK (TcgEndPacket (&CreateStruct));
316 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
317
318 //
319 // Send Revert Method Call
320 //
321 ERROR_CHECK (OpalPerformMethod (AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));
322 METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
323
324 return TcgResultSuccess;
325 }
326
327 /**
328
329 Reverts device using Admin SP Revert method.
330
331 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
332 @param[in] EstimateTimeCost Estimate the time needed.
333
334 **/
335 TCG_RESULT
336 OpalPyrite2PsidRevert (
337 OPAL_SESSION *AdminSpSession,
338 UINT32 EstimateTimeCost
339 )
340 {
341 //
342 // Now that base comid is known, start Session
343 // we'll attempt to start Session as PSID authority
344 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
345 //
346 TCG_CREATE_STRUCT CreateStruct;
347 TCG_PARSE_STRUCT ParseStruct;
348 UINT32 Size;
349 UINT8 Buffer[BUFFER_SIZE];
350 UINT8 MethodStatus;
351
352 NULL_CHECK (AdminSpSession);
353
354 //
355 // Send Revert action on Admin SP
356 //
357 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buffer, BUFFER_SIZE));
358 ERROR_CHECK (TcgStartComPacket (&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));
359 ERROR_CHECK (TcgStartPacket (&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));
360 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
361 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_ADMIN_SP_REVERT_METHOD));
362 ERROR_CHECK (TcgStartParameters (&CreateStruct));
363 ERROR_CHECK (TcgEndParameters (&CreateStruct));
364 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
365 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
366 ERROR_CHECK (TcgEndPacket (&CreateStruct));
367 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
368
369 //
370 // Send Revert Method Call
371 //
372 ERROR_CHECK (OpalPerformMethod (AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, EstimateTimeCost));
373 METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
374
375 return TcgResultSuccess;
376 }
377
378 /**
379
380 The function fills in the provided Buffer with the level 0 discovery Header
381 of the device specified.
382
383 @param[in] Session OPAL_SESSION data.
384 @param[in] BufferSize Size of Buffer provided (in bytes)
385 @param[in] BuffAddress Buffer address to fill with Level 0 Discovery response
386
387 **/
388 TCG_RESULT
389 EFIAPI
390 OpalRetrieveLevel0DiscoveryHeader (
391 OPAL_SESSION *Session,
392 UINTN BufferSize,
393 VOID *BuffAddress
394 )
395 {
396 return (OpalTrustedRecv (
397 Session->Sscp,
398 Session->MediaId,
399 TCG_OPAL_SECURITY_PROTOCOL_1, // SP
400 TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY, // SP_Specific
401 BuffAddress,
402 BufferSize,
403 0
404 ));
405 }
406
407 /**
408
409 The function fills in the provided Buffer with the supported protocol list
410 of the device specified.
411
412 @param[in] Session OPAL_SESSION data.
413 @param[in] BufferSize Size of Buffer provided (in bytes)
414 @param[in] BuffAddress Buffer address to fill with security protocol list
415
416 **/
417 TCG_RESULT
418 EFIAPI
419 OpalRetrieveSupportedProtocolList (
420 OPAL_SESSION *Session,
421 UINTN BufferSize,
422 VOID *BuffAddress
423 )
424 {
425 return (OpalTrustedRecv (
426 Session->Sscp,
427 Session->MediaId,
428 TCG_SECURITY_PROTOCOL_INFO, // SP
429 TCG_SP_SPECIFIC_PROTOCOL_LIST, // SP_Specific
430 BuffAddress,
431 BufferSize,
432 0
433 ));
434 }
435
436 /**
437 Starts a session with a security provider (SP).
438
439 If a session is started successfully, the caller must end the session with OpalEndSession when finished
440 performing Opal actions.
441
442 @param[in/out] Session OPAL_SESSION to initialize.
443 @param[in] SpId Security provider ID to start the session with.
444 @param[in] Write Whether the session should be read-only (FALSE) or read/write (TRUE).
445 @param[in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
446 @param[in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge will be sent.
447 @param[in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority will be sent.
448 @param[in/out] MethodStatus Status of the StartSession method; only valid if TcgResultSuccess is returned.
449
450 @return TcgResultSuccess indicates that the function completed without any internal errors.
451 The caller must inspect the MethodStatus field to determine whether the method completed successfully.
452
453 **/
454 TCG_RESULT
455 EFIAPI
456 OpalStartSession (
457 OPAL_SESSION *Session,
458 TCG_UID SpId,
459 BOOLEAN Write,
460 UINT32 HostChallengeLength,
461 const VOID *HostChallenge,
462 TCG_UID HostSigningAuthority,
463 UINT8 *MethodStatus
464 )
465 {
466 TCG_CREATE_STRUCT CreateStruct;
467 TCG_PARSE_STRUCT ParseStruct;
468 UINT32 Size;
469 UINT8 Buf[BUFFER_SIZE];
470 UINT16 ComIdExtension;
471 UINT32 HostSessionId;
472
473 ComIdExtension = 0;
474 HostSessionId = 1;
475
476 NULL_CHECK (Session);
477 NULL_CHECK (MethodStatus);
478
479 Session->ComIdExtension = ComIdExtension;
480 Session->HostSessionId = HostSessionId;
481
482 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
483 ERROR_CHECK (
484 TcgCreateStartSession (
485 &CreateStruct,
486 &Size,
487 Session->OpalBaseComId,
488 ComIdExtension,
489 HostSessionId,
490 SpId,
491 Write,
492 HostChallengeLength,
493 HostChallenge,
494 HostSigningAuthority
495 )
496 );
497 ERROR_CHECK (OpalPerformMethod (Session, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
498 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
499 return TcgResultSuccess; // return early if method failed - user must check MethodStatus
500 }
501
502 if (TcgParseSyncSession (&ParseStruct, Session->OpalBaseComId, ComIdExtension, HostSessionId, &Session->TperSessionId) != TcgResultSuccess) {
503 OpalEndSession (Session);
504 return TcgResultFailure;
505 }
506
507 return TcgResultSuccess;
508 }
509
510 /**
511 Close a session opened with OpalStartSession.
512
513 @param[in/out] Session OPAL_SESSION to end.
514
515 **/
516 TCG_RESULT
517 EFIAPI
518 OpalEndSession (
519 OPAL_SESSION *Session
520 )
521 {
522 UINT8 Buffer[BUFFER_SIZE];
523 TCG_CREATE_STRUCT CreateStruct;
524 UINT32 Size;
525 TCG_PARSE_STRUCT ParseStruct;
526
527 NULL_CHECK (Session);
528 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buffer, sizeof (Buffer)));
529 ERROR_CHECK (
530 TcgCreateEndSession (
531 &CreateStruct,
532 &Size,
533 Session->OpalBaseComId,
534 Session->ComIdExtension,
535 Session->HostSessionId,
536 Session->TperSessionId
537 )
538 );
539
540 ERROR_CHECK (
541 OpalTrustedSend (
542 Session->Sscp,
543 Session->MediaId,
544 TCG_OPAL_SECURITY_PROTOCOL_1,
545 Session->OpalBaseComId,
546 Size,
547 Buffer,
548 sizeof (Buffer)
549 )
550 );
551
552 ERROR_CHECK (
553 OpalTrustedRecv (
554 Session->Sscp,
555 Session->MediaId,
556 TCG_OPAL_SECURITY_PROTOCOL_1,
557 Session->OpalBaseComId,
558 Buffer,
559 sizeof (Buffer),
560 0
561 )
562 );
563
564 ERROR_CHECK (TcgInitTcgParseStruct (&ParseStruct, Buffer, sizeof (Buffer)));
565 ERROR_CHECK (TcgCheckComIds (&ParseStruct, Session->OpalBaseComId, Session->ComIdExtension));
566
567 ERROR_CHECK (TcgGetNextEndOfSession (&ParseStruct));
568 return TcgResultSuccess;
569 }
570
571 /**
572
573 The function retrieves the MSID from the device specified
574
575 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
576 @param[in] MsidBufferSize Allocated Buffer Size (in bytes) for MSID allocated by caller
577 @param[in] Msid Variable Length byte sequence representing MSID of device
578 @param[in] MsidLength Actual Length of MSID retrieved from device
579
580 **/
581 TCG_RESULT
582 EFIAPI
583 OpalGetMsid (
584 OPAL_SESSION *AdminSpSession,
585 UINT32 MsidBufferSize,
586 UINT8 *Msid,
587 UINT32 *MsidLength
588 )
589 {
590 //
591 // now that base comid is known, start Session
592 // we'll attempt to start Session as PSID authority
593 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
594 //
595 TCG_CREATE_STRUCT CreateStruct;
596 TCG_PARSE_STRUCT ParseStruct;
597 UINT32 Size;
598 UINT8 MethodStatus;
599 UINT32 Col;
600 const VOID *RecvMsid;
601 UINT8 Buffer[BUFFER_SIZE];
602
603 NULL_CHECK (AdminSpSession);
604 NULL_CHECK (Msid);
605 NULL_CHECK (MsidLength);
606
607 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buffer, BUFFER_SIZE));
608 ERROR_CHECK (TcgStartComPacket (&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));
609 ERROR_CHECK (TcgStartPacket (&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));
610 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
611 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_UID_ADMIN_SP_C_PIN_MSID, TCG_UID_METHOD_GET));
612 ERROR_CHECK (TcgStartParameters (&CreateStruct));
613 ERROR_CHECK (TcgAddStartList (&CreateStruct));
614 ERROR_CHECK (TcgAddStartName (&CreateStruct));
615 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));
616 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_ADMIN_SP_PIN_COL));
617 ERROR_CHECK (TcgAddEndName (&CreateStruct));
618 ERROR_CHECK (TcgAddStartName (&CreateStruct));
619 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));
620 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_ADMIN_SP_PIN_COL));
621 ERROR_CHECK (TcgAddEndName (&CreateStruct));
622 ERROR_CHECK (TcgAddEndList (&CreateStruct));
623 ERROR_CHECK (TcgEndParameters (&CreateStruct));
624 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
625 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
626 ERROR_CHECK (TcgEndPacket (&CreateStruct));
627 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
628
629 //
630 // Send MSID Method Call
631 //
632 ERROR_CHECK (OpalPerformMethod (AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));
633 METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
634
635 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
636 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
637 ERROR_CHECK (TcgGetNextStartName (&ParseStruct));
638 ERROR_CHECK (TcgGetNextUINT32 (&ParseStruct, &Col));
639 ERROR_CHECK (TcgGetNextByteSequence (&ParseStruct, &RecvMsid, MsidLength));
640 ERROR_CHECK (TcgGetNextEndName (&ParseStruct));
641 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
642 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
643 ERROR_CHECK (TcgGetNextEndOfData (&ParseStruct));
644
645 if (Col != OPAL_ADMIN_SP_PIN_COL) {
646 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMIN_SP_PIN_COL));
647 return TcgResultFailure;
648 }
649
650 if (RecvMsid == NULL) {
651 return TcgResultFailure;
652 }
653
654 if (MsidBufferSize < *MsidLength) {
655 DEBUG ((DEBUG_INFO, "Buffer too small MsidBufferSize: %d MsidLength: %d\n", MsidBufferSize, *MsidLength));
656 return TcgResultFailureBufferTooSmall;
657 }
658
659 //
660 // copy msid into Buffer
661 //
662 CopyMem (Msid, RecvMsid, *MsidLength);
663 return TcgResultSuccess;
664 }
665
666 /**
667
668 The function retrieves the MSID from the device specified
669
670 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY
671 @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism that the device will use for Revert/RevertSP calls.
672
673 **/
674 TCG_RESULT
675 OpalPyrite2GetActiveDataRemovalMechanism (
676 IN OPAL_SESSION *AdminSpSession,
677 OUT UINT8 *ActiveDataRemovalMechanism
678 )
679 {
680 TCG_CREATE_STRUCT CreateStruct;
681 TCG_PARSE_STRUCT ParseStruct;
682 UINT32 Size;
683 UINT8 MethodStatus;
684 UINT32 Col;
685 UINT8 RecvActiveDataRemovalMechanism;
686 UINT8 Buffer[BUFFER_SIZE];
687
688 NULL_CHECK (AdminSpSession);
689 NULL_CHECK (ActiveDataRemovalMechanism);
690
691 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buffer, BUFFER_SIZE));
692 ERROR_CHECK (TcgStartComPacket (&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));
693 ERROR_CHECK (TcgStartPacket (&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));
694 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
695 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_UID_ADMIN_SP_DATA_REMOVAL_MECHANISM, TCG_UID_METHOD_GET));
696 ERROR_CHECK (TcgStartParameters (&CreateStruct));
697 ERROR_CHECK (TcgAddStartList (&CreateStruct));
698 ERROR_CHECK (TcgAddStartName (&CreateStruct));
699 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));
700 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));
701 ERROR_CHECK (TcgAddEndName (&CreateStruct));
702 ERROR_CHECK (TcgAddStartName (&CreateStruct));
703 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));
704 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));
705 ERROR_CHECK (TcgAddEndName (&CreateStruct));
706 ERROR_CHECK (TcgAddEndList (&CreateStruct));
707 ERROR_CHECK (TcgEndParameters (&CreateStruct));
708 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
709 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
710 ERROR_CHECK (TcgEndPacket (&CreateStruct));
711 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
712
713 //
714 // Send Get Active Data Removal Mechanism Method Call
715 //
716 ERROR_CHECK (OpalPerformMethod (AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));
717 METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
718
719 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
720 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
721 ERROR_CHECK (TcgGetNextStartName (&ParseStruct));
722 ERROR_CHECK (TcgGetNextUINT32 (&ParseStruct, &Col));
723 ERROR_CHECK (TcgGetNextUINT8 (&ParseStruct, &RecvActiveDataRemovalMechanism));
724 ERROR_CHECK (TcgGetNextEndName (&ParseStruct));
725 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
726 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
727 ERROR_CHECK (TcgGetNextEndOfData (&ParseStruct));
728
729 if (Col != OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL) {
730 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));
731 return TcgResultFailure;
732 }
733
734 if (RecvActiveDataRemovalMechanism >= ResearvedMechanism) {
735 return TcgResultFailure;
736 }
737
738 //
739 // Copy active data removal mechanism into Buffer
740 //
741 CopyMem (ActiveDataRemovalMechanism, &RecvActiveDataRemovalMechanism, sizeof (RecvActiveDataRemovalMechanism));
742 return TcgResultSuccess;
743 }
744
745 /**
746
747 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
748 to keep the user Data is set to True, otherwise the optional parameter is not provided.
749
750 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
751 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
752 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
753
754 **/
755 TCG_RESULT
756 EFIAPI
757 OpalAdminRevert (
758 OPAL_SESSION *LockingSpSession,
759 BOOLEAN KeepUserData,
760 UINT8 *MethodStatus
761 )
762 {
763 UINT8 Buf[BUFFER_SIZE];
764 TCG_CREATE_STRUCT CreateStruct;
765 UINT32 Size;
766 TCG_PARSE_STRUCT ParseStruct;
767 TCG_RESULT Ret;
768
769 NULL_CHECK (LockingSpSession);
770 NULL_CHECK (MethodStatus);
771
772 //
773 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
774 //
775 if (KeepUserData) {
776 //
777 // set readlocked and writelocked to false
778 //
779 Ret = OpalUpdateGlobalLockingRange (
780 LockingSpSession,
781 FALSE,
782 FALSE,
783 MethodStatus
784 );
785
786 if ((Ret != TcgResultSuccess) || (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
787 //
788 // bail out
789 //
790 return Ret;
791 }
792 }
793
794 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
795 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
796 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
797 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
798 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCKING_SP_REVERTSP_METHOD));
799 ERROR_CHECK (TcgStartParameters (&CreateStruct));
800
801 if (KeepUserData) {
802 //
803 // optional parameter to keep Data after revert
804 //
805 ERROR_CHECK (TcgAddStartName (&CreateStruct));
806 ERROR_CHECK (TcgAddUINT32 (&CreateStruct, 0x060000)); // weird Value but that's what spec says
807 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, KeepUserData));
808 ERROR_CHECK (TcgAddEndName (&CreateStruct));
809 }
810
811 ERROR_CHECK (TcgEndParameters (&CreateStruct));
812 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
813 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
814 ERROR_CHECK (TcgEndPacket (&CreateStruct));
815 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
816
817 //
818 // Send RevertSP method call
819 //
820 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
821
822 //
823 // Session is immediately ended by device after successful revertsp, so no need to end Session
824 //
825 if (*MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {
826 //
827 // Caller should take ownership again
828 //
829 return TcgResultSuccess;
830 } else {
831 //
832 // End Session
833 //
834 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus
835 }
836
837 return TcgResultSuccess;
838 }
839
840 /**
841
842 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
843 to keep the user Data is set to True, otherwise the optional parameter is not provided.
844
845 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
846 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
847 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
848 @param[in] EstimateTimeCost Estimate the time needed.
849
850 **/
851 TCG_RESULT
852 OpalPyrite2AdminRevert (
853 OPAL_SESSION *LockingSpSession,
854 BOOLEAN KeepUserData,
855 UINT8 *MethodStatus,
856 UINT32 EstimateTimeCost
857 )
858 {
859 UINT8 Buf[BUFFER_SIZE];
860 TCG_CREATE_STRUCT CreateStruct;
861 UINT32 Size;
862 TCG_PARSE_STRUCT ParseStruct;
863 TCG_RESULT Ret;
864
865 NULL_CHECK (LockingSpSession);
866 NULL_CHECK (MethodStatus);
867
868 //
869 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
870 //
871 if (KeepUserData) {
872 //
873 // set readlocked and writelocked to false
874 //
875 Ret = OpalUpdateGlobalLockingRange (
876 LockingSpSession,
877 FALSE,
878 FALSE,
879 MethodStatus
880 );
881
882 if ((Ret != TcgResultSuccess) || (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
883 //
884 // bail out
885 //
886 return Ret;
887 }
888 }
889
890 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
891 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
892 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
893 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
894 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCKING_SP_REVERTSP_METHOD));
895 ERROR_CHECK (TcgStartParameters (&CreateStruct));
896
897 if (KeepUserData) {
898 //
899 // optional parameter to keep Data after revert
900 //
901 ERROR_CHECK (TcgAddStartName (&CreateStruct));
902 ERROR_CHECK (TcgAddUINT32 (&CreateStruct, 0x060000)); // weird Value but that's what spec says
903 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, KeepUserData));
904 ERROR_CHECK (TcgAddEndName (&CreateStruct));
905 }
906
907 ERROR_CHECK (TcgEndParameters (&CreateStruct));
908 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
909 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
910 ERROR_CHECK (TcgEndPacket (&CreateStruct));
911 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
912
913 //
914 // Send RevertSP method call
915 //
916 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, EstimateTimeCost));
917
918 //
919 // Session is immediately ended by device after successful revertsp, so no need to end Session
920 //
921 if (*MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {
922 //
923 // Caller should take ownership again
924 //
925 return TcgResultSuccess;
926 } else {
927 //
928 // End Session
929 //
930 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus
931 }
932
933 return TcgResultSuccess;
934 }
935
936 /**
937
938 The function activates the Locking SP.
939 Once activated, per Opal spec, the ADMIN SP SID PIN is copied over to the ADMIN1 LOCKING SP PIN.
940 If the Locking SP is already enabled, then TcgResultSuccess is returned and no action occurs.
941
942 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY to activate Locking SP
943 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
944
945 **/
946 TCG_RESULT
947 EFIAPI
948 OpalActivateLockingSp (
949 OPAL_SESSION *AdminSpSession,
950 UINT8 *MethodStatus
951 )
952 {
953 UINT8 Buf[BUFFER_SIZE];
954 TCG_CREATE_STRUCT CreateStruct;
955 UINT32 Size;
956 TCG_PARSE_STRUCT ParseStruct;
957
958 NULL_CHECK (AdminSpSession);
959 NULL_CHECK (MethodStatus);
960
961 //
962 // Call Activate method on Locking SP
963 //
964 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
965 ERROR_CHECK (TcgStartComPacket (&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));
966 ERROR_CHECK (TcgStartPacket (&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));
967 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
968 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_UID_LOCKING_SP, OPAL_ADMIN_SP_ACTIVATE_METHOD));
969 ERROR_CHECK (TcgStartParameters (&CreateStruct));
970 ERROR_CHECK (TcgEndParameters (&CreateStruct));
971 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
972 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
973 ERROR_CHECK (TcgEndPacket (&CreateStruct));
974 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
975
976 //
977 // Send Activate method call
978 //
979 ERROR_CHECK (OpalPerformMethod (AdminSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
980 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus
981
982 return TcgResultSuccess;
983 }
984
985 /**
986
987 The function sets the PIN column of the specified cpinRowUid (authority) with the newPin Value.
988
989 @param[in/out] Session OPAL_SESSION to set password
990 @param[in] CpinRowUid UID of row (authority) to update PIN column
991 @param[in] NewPin New Pin to set for cpinRowUid specified
992 @param[in] NewPinLength Length in bytes of newPin
993 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
994
995 **/
996 TCG_RESULT
997 EFIAPI
998 OpalSetPassword (
999 OPAL_SESSION *Session,
1000 TCG_UID CpinRowUid,
1001 const VOID *NewPin,
1002 UINT32 NewPinLength,
1003 UINT8 *MethodStatus
1004 )
1005 {
1006 UINT8 Buf[BUFFER_SIZE];
1007 TCG_CREATE_STRUCT CreateStruct;
1008 TCG_PARSE_STRUCT ParseStruct;
1009 UINT32 Size;
1010
1011 NULL_CHECK (Session);
1012 NULL_CHECK (NewPin);
1013 NULL_CHECK (MethodStatus);
1014
1015 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1016 ERROR_CHECK (
1017 TcgCreateSetCPin (
1018 &CreateStruct,
1019 &Size,
1020 Session->OpalBaseComId,
1021 Session->ComIdExtension,
1022 Session->TperSessionId,
1023 Session->HostSessionId,
1024 CpinRowUid,
1025 NewPin,
1026 NewPinLength
1027 )
1028 );
1029
1030 ERROR_CHECK (OpalPerformMethod (Session, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1031 // exit with success on method failure - user must inspect MethodStatus
1032 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess);
1033
1034 return TcgResultSuccess;
1035 }
1036
1037 /**
1038
1039 The function sets the Enabled column to TRUE for the authorityUid provided and updates the PIN column for the cpinRowUid provided
1040 using the newPin provided. AuthorityUid and cpinRowUid should describe the same authority.
1041
1042 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to update
1043 @param[in] CpinRowUid Row UID of C_PIN table of Locking SP to update PIN
1044 @param[in] AuthorityUid UID of Locking SP authority to update Pin column with
1045 @param[in] NewPin New Password used to set Pin column
1046 @param[in] NewPinLength Length in bytes of new password
1047 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1048
1049 **/
1050 TCG_RESULT
1051 EFIAPI
1052 OpalSetLockingSpAuthorityEnabledAndPin (
1053 OPAL_SESSION *LockingSpSession,
1054 TCG_UID CpinRowUid,
1055 TCG_UID AuthorityUid,
1056 const VOID *NewPin,
1057 UINT32 NewPinLength,
1058 UINT8 *MethodStatus
1059 )
1060 {
1061 UINT8 Buf[BUFFER_SIZE];
1062 TCG_CREATE_STRUCT CreateStruct;
1063 TCG_PARSE_STRUCT ParseStruct;
1064 UINT32 Size;
1065 TCG_UID ActiveKey;
1066 TCG_RESULT Ret;
1067
1068 NULL_CHECK (LockingSpSession);
1069 NULL_CHECK (NewPin);
1070 NULL_CHECK (MethodStatus);
1071
1072 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1073 ERROR_CHECK (
1074 TcgSetAuthorityEnabled (
1075 &CreateStruct,
1076 &Size,
1077 LockingSpSession->OpalBaseComId,
1078 LockingSpSession->ComIdExtension,
1079 LockingSpSession->TperSessionId,
1080 LockingSpSession->HostSessionId,
1081 AuthorityUid,
1082 TRUE
1083 )
1084 );
1085
1086 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1087
1088 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
1089 DEBUG ((DEBUG_INFO, "Send Set Authority error\n"));
1090 return TcgResultFailure;
1091 }
1092
1093 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1094
1095 ERROR_CHECK (
1096 TcgCreateSetCPin (
1097 &CreateStruct,
1098 &Size,
1099 LockingSpSession->OpalBaseComId,
1100 LockingSpSession->ComIdExtension,
1101 LockingSpSession->TperSessionId,
1102 LockingSpSession->HostSessionId,
1103 CpinRowUid,
1104 NewPin,
1105 NewPinLength
1106 )
1107 );
1108
1109 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1110
1111 //
1112 // allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked
1113 //
1114 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1115 ERROR_CHECK (
1116 TcgCreateSetAce (
1117 &CreateStruct,
1118 &Size,
1119 LockingSpSession->OpalBaseComId,
1120 LockingSpSession->ComIdExtension,
1121 LockingSpSession->TperSessionId,
1122 LockingSpSession->HostSessionId,
1123 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_RDLOCKED,
1124 OPAL_LOCKING_SP_USER1_AUTHORITY,
1125 TCG_ACE_EXPRESSION_OR,
1126 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1127 )
1128 );
1129
1130 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1131
1132 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
1133 DEBUG ((DEBUG_INFO, "Update ACE for RDLOCKED failed\n"));
1134 return TcgResultFailure;
1135 }
1136
1137 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1138 ERROR_CHECK (
1139 TcgCreateSetAce (
1140 &CreateStruct,
1141 &Size,
1142 LockingSpSession->OpalBaseComId,
1143 LockingSpSession->ComIdExtension,
1144 LockingSpSession->TperSessionId,
1145 LockingSpSession->HostSessionId,
1146 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_WRLOCKED,
1147 OPAL_LOCKING_SP_USER1_AUTHORITY,
1148 TCG_ACE_EXPRESSION_OR,
1149 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1150 )
1151 );
1152
1153 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1154
1155 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
1156 DEBUG ((DEBUG_INFO, "Update ACE for WRLOCKED failed\n"));
1157 return TcgResultFailure;
1158 }
1159
1160 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1161 ERROR_CHECK (OpalCreateRetrieveGlobalLockingRangeActiveKey (LockingSpSession, &CreateStruct, &Size));
1162 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1163
1164 //
1165 // For Pyrite type SSC, it not supports Active Key.
1166 // So here add check logic before enable it.
1167 //
1168 Ret = OpalParseRetrieveGlobalLockingRangeActiveKey (&ParseStruct, &ActiveKey);
1169 if (Ret == TcgResultSuccess) {
1170 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1171 ERROR_CHECK (
1172 TcgCreateSetAce (
1173 &CreateStruct,
1174 &Size,
1175 LockingSpSession->OpalBaseComId,
1176 LockingSpSession->ComIdExtension,
1177 LockingSpSession->TperSessionId,
1178 LockingSpSession->HostSessionId,
1179 (ActiveKey == OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY) ? OPAL_LOCKING_SP_ACE_K_AES_256_GLOBALRANGE_GENKEY : OPAL_LOCKING_SP_ACE_K_AES_128_GLOBALRANGE_GENKEY,
1180 OPAL_LOCKING_SP_USER1_AUTHORITY,
1181 TCG_ACE_EXPRESSION_OR,
1182 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1183 )
1184 );
1185
1186 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1187
1188 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
1189 DEBUG ((DEBUG_INFO, "Update ACE for GLOBALRANGE_GENKEY failed\n"));
1190 //
1191 // Disable user1 if all permissions are not granted.
1192 //
1193 return TcgResultFailure;
1194 }
1195 }
1196
1197 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1198 ERROR_CHECK (
1199 TcgCreateSetAce (
1200 &CreateStruct,
1201 &Size,
1202 LockingSpSession->OpalBaseComId,
1203 LockingSpSession->ComIdExtension,
1204 LockingSpSession->TperSessionId,
1205 LockingSpSession->HostSessionId,
1206 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL,
1207 OPAL_LOCKING_SP_USER1_AUTHORITY,
1208 TCG_ACE_EXPRESSION_OR,
1209 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1210 )
1211 );
1212
1213 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1214
1215 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
1216 DEBUG ((DEBUG_INFO, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL failed\n"));
1217 return TcgResultFailure;
1218 }
1219
1220 return TcgResultSuccess;
1221 }
1222
1223 /**
1224
1225 The function sets the Enabled column to FALSE for the USER1 authority.
1226
1227 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to disable User1
1228 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1229
1230 **/
1231 TCG_RESULT
1232 EFIAPI
1233 OpalDisableUser (
1234 OPAL_SESSION *LockingSpSession,
1235 UINT8 *MethodStatus
1236 )
1237 {
1238 UINT8 Buf[BUFFER_SIZE];
1239 TCG_CREATE_STRUCT CreateStruct;
1240 TCG_PARSE_STRUCT ParseStruct;
1241 UINT32 Size;
1242
1243 NULL_CHECK (LockingSpSession);
1244 NULL_CHECK (MethodStatus);
1245
1246 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1247 ERROR_CHECK (
1248 TcgSetAuthorityEnabled (
1249 &CreateStruct,
1250 &Size,
1251 LockingSpSession->OpalBaseComId,
1252 LockingSpSession->ComIdExtension,
1253 LockingSpSession->TperSessionId,
1254 LockingSpSession->HostSessionId,
1255 OPAL_LOCKING_SP_USER1_AUTHORITY,
1256 FALSE
1257 )
1258 );
1259
1260 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1261
1262 return TcgResultSuccess;
1263 }
1264
1265 /**
1266
1267 The function retrieves the active key of the global locking range
1268 and calls the GenKey method on the active key retrieved.
1269
1270 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1271 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1272
1273 **/
1274 TCG_RESULT
1275 EFIAPI
1276 OpalGlobalLockingRangeGenKey (
1277 OPAL_SESSION *LockingSpSession,
1278 UINT8 *MethodStatus
1279 )
1280 {
1281 UINT8 Buf[BUFFER_SIZE];
1282 TCG_CREATE_STRUCT CreateStruct;
1283 TCG_PARSE_STRUCT ParseStruct;
1284 UINT32 Size;
1285 TCG_UID ActiveKey;
1286
1287 NULL_CHECK (LockingSpSession);
1288 NULL_CHECK (MethodStatus);
1289
1290 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1291 //
1292 // retrieve the activekey in order to know which globalrange key to generate
1293 //
1294 ERROR_CHECK (OpalCreateRetrieveGlobalLockingRangeActiveKey (LockingSpSession, &CreateStruct, &Size));
1295 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1296
1297 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess);
1298
1299 ERROR_CHECK (OpalParseRetrieveGlobalLockingRangeActiveKey (&ParseStruct, &ActiveKey));
1300
1301 //
1302 // call genkey on ActiveKey UID
1303 //
1304 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1305 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
1306 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
1307 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
1308 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, ActiveKey, TCG_UID_METHOD_GEN_KEY));
1309 ERROR_CHECK (TcgStartParameters (&CreateStruct));
1310 ERROR_CHECK (TcgEndParameters (&CreateStruct));
1311 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
1312 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
1313 ERROR_CHECK (TcgEndPacket (&CreateStruct));
1314 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
1315
1316 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1317
1318 return TcgResultSuccess;
1319 }
1320
1321 /**
1322
1323 The function updates the ReadLocked and WriteLocked columns of the Global Locking Range.
1324 This function is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns
1325 (not ReadLockEnabled and WriteLockEnabled columns).
1326
1327 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1328 @param[in] ReadLocked Value to set ReadLocked column for Global Locking Range
1329 @param[in] WriteLocked Value to set WriteLocked column for Global Locking Range
1330 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1331
1332 **/
1333 TCG_RESULT
1334 EFIAPI
1335 OpalUpdateGlobalLockingRange (
1336 OPAL_SESSION *LockingSpSession,
1337 BOOLEAN ReadLocked,
1338 BOOLEAN WriteLocked,
1339 UINT8 *MethodStatus
1340 )
1341 {
1342 UINT8 Buf[BUFFER_SIZE];
1343 TCG_CREATE_STRUCT CreateStruct;
1344 TCG_PARSE_STRUCT ParseStruct;
1345 UINT32 Size;
1346
1347 NULL_CHECK (LockingSpSession);
1348 NULL_CHECK (MethodStatus);
1349
1350 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1351
1352 //
1353 // set global locking range values
1354 //
1355 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
1356 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
1357 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
1358 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE, TCG_UID_METHOD_SET));
1359 ERROR_CHECK (TcgStartParameters (&CreateStruct));
1360 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1361 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x01)); // "Values"
1362 ERROR_CHECK (TcgAddStartList (&CreateStruct));
1363
1364 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1365 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x07)); // "ReadLocked"
1366 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, ReadLocked));
1367 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1368
1369 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1370 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x08)); // "WriteLocked"
1371 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, WriteLocked));
1372 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1373
1374 ERROR_CHECK (TcgAddEndList (&CreateStruct));
1375 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1376 ERROR_CHECK (TcgEndParameters (&CreateStruct));
1377 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
1378 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
1379 ERROR_CHECK (TcgEndPacket (&CreateStruct));
1380 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
1381
1382 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1383 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess);
1384
1385 return TcgResultSuccess;
1386 }
1387
1388 /**
1389
1390 The function updates the RangeStart, RangeLength, ReadLockedEnabled, WriteLockedEnabled, ReadLocked and WriteLocked columns
1391 of the specified Locking Range. This function requires admin authority of a locking SP session.
1392
1393 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1394 @param[in] LockingRangeUid Locking range UID to set values
1395 @param[in] RangeStart Value to set RangeStart column for Locking Range
1396 @param[in] RangeLength Value to set RangeLength column for Locking Range
1397 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range
1398 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range
1399 @param[in] ReadLocked Value to set ReadLocked column for Locking Range
1400 @param[in] WriteLocked Value to set WriteLocked column for Locking Range
1401 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1402
1403 **/
1404 TCG_RESULT
1405 EFIAPI
1406 OpalSetLockingRange (
1407 OPAL_SESSION *LockingSpSession,
1408 TCG_UID LockingRangeUid,
1409 UINT64 RangeStart,
1410 UINT64 RangeLength,
1411 BOOLEAN ReadLockEnabled,
1412 BOOLEAN WriteLockEnabled,
1413 BOOLEAN ReadLocked,
1414 BOOLEAN WriteLocked,
1415 UINT8 *MethodStatus
1416 )
1417 {
1418 UINT8 Buf[BUFFER_SIZE];
1419 TCG_CREATE_STRUCT CreateStruct;
1420 TCG_PARSE_STRUCT ParseStruct;
1421 UINT32 Size;
1422
1423 NULL_CHECK (LockingSpSession);
1424 NULL_CHECK (MethodStatus);
1425
1426 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1427
1428 //
1429 // set locking range values
1430 //
1431 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
1432 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
1433 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
1434 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, LockingRangeUid, TCG_UID_METHOD_SET));
1435 ERROR_CHECK (TcgStartParameters (&CreateStruct));
1436 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1437 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x01)); // "Values"
1438 ERROR_CHECK (TcgAddStartList (&CreateStruct));
1439
1440 //
1441 // range start and range Length only apply to non-global locking ranges
1442 //
1443 if (LockingRangeUid != OPAL_LOCKING_SP_LOCKING_GLOBALRANGE) {
1444 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1445 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x03)); // "RangeStart"
1446 ERROR_CHECK (TcgAddUINT64 (&CreateStruct, RangeStart));
1447 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1448
1449 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1450 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x04)); // "RangeLength"
1451 ERROR_CHECK (TcgAddUINT64 (&CreateStruct, RangeLength));
1452 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1453 }
1454
1455 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1456 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x05)); // "ReadLockEnabled"
1457 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, ReadLockEnabled));
1458 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1459
1460 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1461 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x06)); // "WriteLockEnabled"
1462 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, WriteLockEnabled));
1463 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1464
1465 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1466 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x07)); // "ReadLocked"
1467 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, ReadLocked));
1468 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1469
1470 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1471 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, 0x08)); // "WriteLocked"
1472 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct, WriteLocked));
1473 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1474
1475 ERROR_CHECK (TcgAddEndList (&CreateStruct));
1476 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1477 ERROR_CHECK (TcgEndParameters (&CreateStruct));
1478 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
1479 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
1480 ERROR_CHECK (TcgEndPacket (&CreateStruct));
1481 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
1482
1483 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, MethodStatus, 0));
1484 // Exit with success on method failure - user must inspect MethodStatus
1485 METHOD_STATUS_ERROR_CHECK (*MethodStatus, TcgResultSuccess);
1486
1487 return TcgResultSuccess;
1488 }
1489
1490 /**
1491
1492 The function populates the CreateStruct with a payload that will retrieve the global locking range active key.
1493 It is intended to be called with a session that is already started with a valid credential.
1494 The function does not send the payload.
1495
1496 @param[in] Session OPAL_SESSION to populate command for, needs ComId
1497 @param[in/out] CreateStruct Structure to populate with encoded TCG command
1498 @param[in/out] Size Size in bytes of the command created.
1499
1500 **/
1501 TCG_RESULT
1502 EFIAPI
1503 OpalCreateRetrieveGlobalLockingRangeActiveKey (
1504 const OPAL_SESSION *Session,
1505 TCG_CREATE_STRUCT *CreateStruct,
1506 UINT32 *Size
1507 )
1508 {
1509 NULL_CHECK (Session);
1510 NULL_CHECK (CreateStruct);
1511 NULL_CHECK (Size);
1512
1513 // Retrieve the activekey in order to know which globalrange key to generate
1514 ERROR_CHECK (TcgStartComPacket (CreateStruct, Session->OpalBaseComId, Session->ComIdExtension));
1515 ERROR_CHECK (TcgStartPacket (CreateStruct, Session->TperSessionId, Session->HostSessionId, 0x0, 0x0, 0x0));
1516 ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
1517 ERROR_CHECK (TcgStartMethodCall (CreateStruct, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE, TCG_UID_METHOD_GET));
1518 ERROR_CHECK (TcgStartParameters (CreateStruct));
1519 ERROR_CHECK (TcgAddStartList (CreateStruct));
1520 ERROR_CHECK (TcgAddStartName (CreateStruct));
1521 ERROR_CHECK (TcgAddUINT8 (CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));
1522 ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x0A)); // ActiveKey
1523 ERROR_CHECK (TcgAddEndName (CreateStruct));
1524 ERROR_CHECK (TcgAddStartName (CreateStruct));
1525 ERROR_CHECK (TcgAddUINT8 (CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));
1526 ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x0A));
1527 ERROR_CHECK (TcgAddEndName (CreateStruct));
1528 ERROR_CHECK (TcgAddEndList (CreateStruct));
1529 ERROR_CHECK (TcgEndParameters (CreateStruct));
1530 ERROR_CHECK (TcgEndMethodCall (CreateStruct));
1531 ERROR_CHECK (TcgEndSubPacket (CreateStruct));
1532 ERROR_CHECK (TcgEndPacket (CreateStruct));
1533 ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
1534
1535 return TcgResultSuccess;
1536 }
1537
1538 /**
1539
1540 The function acquires the activeKey specified for the Global Locking Range from the ParseStruct.
1541
1542 @param[in] ParseStruct Structure that contains the device's response with the activekey
1543 @param[in/out] ActiveKey The UID of the active key retrieved
1544
1545 **/
1546 TCG_RESULT
1547 EFIAPI
1548 OpalParseRetrieveGlobalLockingRangeActiveKey (
1549 TCG_PARSE_STRUCT *ParseStruct,
1550 TCG_UID *ActiveKey
1551 )
1552 {
1553 UINT32 ColumnName;
1554
1555 NULL_CHECK (ParseStruct);
1556 NULL_CHECK (ActiveKey);
1557
1558 // parse response
1559 ERROR_CHECK (TcgGetNextStartList (ParseStruct));
1560 ERROR_CHECK (TcgGetNextStartList (ParseStruct));
1561 ERROR_CHECK (TcgGetNextStartName (ParseStruct));
1562 ERROR_CHECK (TcgGetNextUINT32 (ParseStruct, &ColumnName));
1563 ERROR_CHECK (TcgGetNextTcgUid (ParseStruct, ActiveKey));
1564 ERROR_CHECK (TcgGetNextEndName (ParseStruct));
1565 ERROR_CHECK (TcgGetNextEndList (ParseStruct));
1566 ERROR_CHECK (TcgGetNextEndList (ParseStruct));
1567 ERROR_CHECK (TcgGetNextEndOfData (ParseStruct));
1568
1569 if (ColumnName != 0x0A) {
1570 DEBUG ((DEBUG_INFO, "Unexpected column name %u (exp 0x0A)\n", ColumnName));
1571 return TcgResultFailure;
1572 }
1573
1574 if ((*ActiveKey != OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY) && (*ActiveKey != OPAL_LOCKING_SP_K_AES_128_GLOBALRANGE_KEY)) {
1575 DEBUG ((DEBUG_INFO, "Unexpected gen key %u (exp %u or %u)\n", *ActiveKey, OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY, OPAL_LOCKING_SP_K_AES_128_GLOBALRANGE_KEY));
1576 return TcgResultFailure;
1577 }
1578
1579 return TcgResultSuccess;
1580 }
1581
1582 /**
1583
1584 The function retrieves the TryLimit column for the specified rowUid (authority).
1585
1586 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve try limit
1587 @param[in] RowUid Row UID of the Locking SP C_PIN table to retrieve TryLimit column
1588 @param[in/out] TryLimit Value from TryLimit column
1589
1590 **/
1591 TCG_RESULT
1592 EFIAPI
1593 OpalGetTryLimit (
1594 OPAL_SESSION *LockingSpSession,
1595 TCG_UID RowUid,
1596 UINT32 *TryLimit
1597 )
1598 {
1599 TCG_CREATE_STRUCT CreateStruct;
1600 TCG_PARSE_STRUCT ParseStruct;
1601 UINT32 Size;
1602 UINT8 MethodStatus;
1603 UINT8 Buf[BUFFER_SIZE];
1604 UINT32 Col;
1605
1606 NULL_CHECK (LockingSpSession);
1607 NULL_CHECK (TryLimit);
1608
1609 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct, Buf, sizeof (Buf)));
1610 ERROR_CHECK (TcgStartComPacket (&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));
1611 ERROR_CHECK (TcgStartPacket (&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));
1612 ERROR_CHECK (TcgStartSubPacket (&CreateStruct, 0x0));
1613 ERROR_CHECK (TcgStartMethodCall (&CreateStruct, RowUid, TCG_UID_METHOD_GET));
1614 ERROR_CHECK (TcgStartParameters (&CreateStruct));
1615 ERROR_CHECK (TcgAddStartList (&CreateStruct));
1616 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1617 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));
1618 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));
1619 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1620 ERROR_CHECK (TcgAddStartName (&CreateStruct));
1621 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));
1622 ERROR_CHECK (TcgAddUINT8 (&CreateStruct, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));
1623 ERROR_CHECK (TcgAddEndName (&CreateStruct));
1624 ERROR_CHECK (TcgAddEndList (&CreateStruct));
1625 ERROR_CHECK (TcgEndParameters (&CreateStruct));
1626 ERROR_CHECK (TcgEndMethodCall (&CreateStruct));
1627 ERROR_CHECK (TcgEndSubPacket (&CreateStruct));
1628 ERROR_CHECK (TcgEndPacket (&CreateStruct));
1629 ERROR_CHECK (TcgEndComPacket (&CreateStruct, &Size));
1630
1631 ERROR_CHECK (OpalPerformMethod (LockingSpSession, Size, Buf, sizeof (Buf), &ParseStruct, &MethodStatus, 0));
1632 METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
1633
1634 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
1635 ERROR_CHECK (TcgGetNextStartList (&ParseStruct));
1636 ERROR_CHECK (TcgGetNextStartName (&ParseStruct));
1637 ERROR_CHECK (TcgGetNextUINT32 (&ParseStruct, &Col));
1638 ERROR_CHECK (TcgGetNextUINT32 (&ParseStruct, TryLimit));
1639 ERROR_CHECK (TcgGetNextEndName (&ParseStruct));
1640 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
1641 ERROR_CHECK (TcgGetNextEndList (&ParseStruct));
1642 ERROR_CHECK (TcgGetNextEndOfData (&ParseStruct));
1643
1644 if (Col != OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL) {
1645 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));
1646 return TcgResultFailure;
1647 }
1648
1649 return TcgResultSuccess;
1650 }
1651
1652 /**
1653
1654 Get the support attribute info.
1655
1656 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1657 @param[out] SupportedAttributes Return the support attribute info.
1658 @param[out] OpalBaseComId Return the base com id info.
1659
1660 **/
1661 TCG_RESULT
1662 EFIAPI
1663 OpalGetSupportedAttributesInfo (
1664 IN OPAL_SESSION *Session,
1665 OUT OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
1666 OUT UINT16 *OpalBaseComId
1667 )
1668 {
1669 UINT8 Buffer[BUFFER_SIZE];
1670 TCG_SUPPORTED_SECURITY_PROTOCOLS *SupportedProtocols;
1671 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;
1672 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;
1673 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat2;
1674 UINTN Size;
1675 UINTN Size2;
1676
1677 NULL_CHECK (Session);
1678 NULL_CHECK (SupportedAttributes);
1679 NULL_CHECK (OpalBaseComId);
1680
1681 ZeroMem (Buffer, BUFFER_SIZE);
1682 ZeroMem (SupportedAttributes, sizeof (OPAL_DISK_SUPPORT_ATTRIBUTE));
1683 ASSERT (sizeof (Buffer) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS));
1684
1685 //
1686 // Retrieve supported protocols verify security protocol 1 is supported
1687 //
1688 SupportedProtocols = (TCG_SUPPORTED_SECURITY_PROTOCOLS *)Buffer;
1689
1690 //
1691 // Get list of supported protocols
1692 //
1693 if (OpalRetrieveSupportedProtocolList (Session, sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS), SupportedProtocols) == TcgResultFailure) {
1694 DEBUG ((DEBUG_INFO, "OpalRetrieveSupportedProtocolList failed\n"));
1695 return TcgResultFailure;
1696 }
1697
1698 SupportedAttributes->Sp1 = TcgIsProtocolSupported (SupportedProtocols, TCG_OPAL_SECURITY_PROTOCOL_1);
1699 SupportedAttributes->Sp2 = TcgIsProtocolSupported (SupportedProtocols, TCG_OPAL_SECURITY_PROTOCOL_2);
1700 SupportedAttributes->SpIeee1667 = TcgIsProtocolSupported (SupportedProtocols, TCG_SECURITY_PROTOCOL_IEEE_1667);
1701
1702 DEBUG ((
1703 DEBUG_INFO,
1704 "Supported Protocols: Sp1 %d Sp2: %d SpIeee1667 %d \n",
1705 SupportedAttributes->Sp1,
1706 SupportedAttributes->Sp2,
1707 SupportedAttributes->SpIeee1667
1708 ));
1709
1710 //
1711 // Perform level 0 discovery and assign desired feature info to Opal Disk structure
1712 //
1713 ZeroMem (Buffer, BUFFER_SIZE);
1714 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {
1715 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1716 return TcgResultFailure;
1717 }
1718
1719 //
1720 // Check for required feature descriptors
1721 //
1722 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER *)Buffer;
1723
1724 Size = 0;
1725 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_V2_0_0, &Size);
1726 SupportedAttributes->OpalSsc2 = (Feat != NULL);
1727
1728 *OpalBaseComId = TCG_RESERVED_COMID;
1729
1730 //
1731 // Check Opal SCC V2 has valid settings for SID C_PIN on revert
1732 //
1733 if (SupportedAttributes->OpalSsc2 && (Size >= sizeof (OPAL_SSCV2_FEATURE_DESCRIPTOR))) {
1734 //
1735 // Want opposite polarity b/c Value is greater than a bit, but we only care about non-zero vs zero
1736 //
1737 SupportedAttributes->InitCpinIndicator = (Feat->OpalSscV2.InitialCPINSIDPIN == 0);
1738 SupportedAttributes->CpinUponRevert = (Feat->OpalSscV2.CPINSIDPINRevertBehavior == 0);
1739 DEBUG ((
1740 DEBUG_INFO,
1741 "Opal SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1742 SupportedAttributes->InitCpinIndicator,
1743 SupportedAttributes->CpinUponRevert
1744 ));
1745 *OpalBaseComId = SwapBytes16 (Feat->OpalSscV2.BaseComdIdBE);
1746 }
1747
1748 Size = 0;
1749 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_LITE, &Size);
1750 SupportedAttributes->OpalSscLite = (Feat != NULL);
1751
1752 if ((Feat != NULL) && (Size >= sizeof (OPAL_SSCLITE_FEATURE_DESCRIPTOR))) {
1753 if (*OpalBaseComId == TCG_RESERVED_COMID) {
1754 //
1755 // Pin values used always match up with ComId used
1756 //
1757 *OpalBaseComId = SwapBytes16 (Feat->OpalSscLite.BaseComdIdBE);
1758 SupportedAttributes->InitCpinIndicator = (Feat->OpalSscV2.InitialCPINSIDPIN == 0);
1759 SupportedAttributes->CpinUponRevert = (Feat->OpalSscV2.CPINSIDPINRevertBehavior == 0);
1760 DEBUG ((
1761 DEBUG_INFO,
1762 "Opal SSC Lite InitCpinIndicator %d CpinUponRevert %d \n",
1763 SupportedAttributes->InitCpinIndicator,
1764 SupportedAttributes->CpinUponRevert
1765 ));
1766 }
1767 }
1768
1769 //
1770 // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 feature data.
1771 // so here try to get data from pyrite 2.0 feature data first.
1772 //
1773 Size = 0;
1774 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC, &Size);
1775 Size2 = 0;
1776 Feat2 = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC_V2_0_0, &Size2);
1777 if ((Feat2 != NULL) && (Size2 >= sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTOR))) {
1778 SupportedAttributes->PyriteSscV2 = TRUE;
1779 if (*OpalBaseComId == TCG_RESERVED_COMID) {
1780 *OpalBaseComId = SwapBytes16 (Feat2->PyriteSscV2.BaseComdIdBE);
1781 SupportedAttributes->InitCpinIndicator = (Feat2->PyriteSscV2.InitialCPINSIDPIN == 0);
1782 SupportedAttributes->CpinUponRevert = (Feat2->PyriteSscV2.CPINSIDPINRevertBehavior == 0);
1783 DEBUG ((
1784 DEBUG_INFO,
1785 "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1786 SupportedAttributes->InitCpinIndicator,
1787 SupportedAttributes->CpinUponRevert
1788 ));
1789 }
1790 } else {
1791 SupportedAttributes->PyriteSsc = (Feat != NULL);
1792 if ((Feat != NULL) && (Size >= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR))) {
1793 if (*OpalBaseComId == TCG_RESERVED_COMID) {
1794 *OpalBaseComId = SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE);
1795 SupportedAttributes->InitCpinIndicator = (Feat->PyriteSsc.InitialCPINSIDPIN == 0);
1796 SupportedAttributes->CpinUponRevert = (Feat->PyriteSsc.CPINSIDPINRevertBehavior == 0);
1797 DEBUG ((
1798 DEBUG_INFO,
1799 "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",
1800 SupportedAttributes->InitCpinIndicator,
1801 SupportedAttributes->CpinUponRevert
1802 ));
1803 }
1804 }
1805 }
1806
1807 Size = 0;
1808 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_V1_0_0, &Size);
1809 SupportedAttributes->OpalSsc1 = (Feat != NULL);
1810 if ((Feat != NULL) && (Size >= sizeof (OPAL_SSCV1_FEATURE_DESCRIPTOR))) {
1811 if (*OpalBaseComId == TCG_RESERVED_COMID) {
1812 *OpalBaseComId = SwapBytes16 (Feat->OpalSscV1.BaseComdIdBE);
1813 }
1814 }
1815
1816 Size = 0;
1817 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size);
1818 if ((Feat != NULL) && (Size >= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR))) {
1819 SupportedAttributes->MediaEncryption = Feat->Locking.MediaEncryption;
1820 DEBUG ((DEBUG_INFO, "SupportedAttributes->MediaEncryption 0x%X \n", SupportedAttributes->MediaEncryption));
1821 }
1822
1823 Size = 0;
1824 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_BLOCK_SID, &Size);
1825 if ((Feat != NULL) && (Size >= sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR))) {
1826 SupportedAttributes->BlockSid = TRUE;
1827 DEBUG ((DEBUG_INFO, "BlockSid Supported!!! Current Status is 0x%X \n", Feat->BlockSid.SIDBlockedState));
1828 } else {
1829 DEBUG ((DEBUG_INFO, "BlockSid Unsupported!!!"));
1830 }
1831
1832 Size = 0;
1833 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_DATA_REMOVAL, &Size);
1834 if ((Feat != NULL) && (Size >= sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR))) {
1835 SupportedAttributes->DataRemoval = TRUE;
1836 DEBUG ((DEBUG_INFO, "DataRemoval Feature Supported!\n"));
1837 DEBUG ((DEBUG_INFO, "Operation Processing = 0x%x\n", Feat->DataRemoval.OperationProcessing));
1838 DEBUG ((DEBUG_INFO, "RemovalMechanism = 0x%x\n", Feat->DataRemoval.RemovalMechanism));
1839 DEBUG ((DEBUG_INFO, "BIT0 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit0, SwapBytes16 (Feat->DataRemoval.TimeBit0)));
1840 DEBUG ((DEBUG_INFO, "BIT1 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit1, SwapBytes16 (Feat->DataRemoval.TimeBit1)));
1841 DEBUG ((DEBUG_INFO, "BIT2 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit2, SwapBytes16 (Feat->DataRemoval.TimeBit2)));
1842 DEBUG ((DEBUG_INFO, "BIT3 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit3, SwapBytes16 (Feat->DataRemoval.TimeBit3)));
1843 DEBUG ((DEBUG_INFO, "BIT4 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit4, SwapBytes16 (Feat->DataRemoval.TimeBit4)));
1844 }
1845
1846 DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId));
1847
1848 return TcgResultSuccess;
1849 }
1850
1851 /**
1852
1853 Get the support attribute info.
1854
1855 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1856 @param[in/out] LockingFeature Return the Locking info.
1857
1858 **/
1859 TCG_RESULT
1860 EFIAPI
1861 OpalGetLockingInfo (
1862 OPAL_SESSION *Session,
1863 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature
1864 )
1865 {
1866 UINT8 Buffer[BUFFER_SIZE];
1867 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;
1868 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;
1869 UINTN Size;
1870
1871 NULL_CHECK (Session);
1872 NULL_CHECK (LockingFeature);
1873
1874 ZeroMem (Buffer, BUFFER_SIZE);
1875 ASSERT (sizeof (Buffer) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS));
1876
1877 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {
1878 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1879 return TcgResultFailure;
1880 }
1881
1882 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER *)Buffer;
1883
1884 Size = 0;
1885 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size);
1886 if ((Feat != NULL) && (Size >= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR))) {
1887 CopyMem (LockingFeature, &Feat->Locking, sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR));
1888 }
1889
1890 return TcgResultSuccess;
1891 }
1892
1893 /**
1894
1895 Get the descriptor for the specific feature code.
1896
1897 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1898 @param[in] FeatureCode The feature code user request.
1899 @param[in, out] DataSize The data size.
1900 @param[out] Data The data buffer used to save the feature descriptor.
1901
1902 **/
1903 TCG_RESULT
1904 OpalGetFeatureDescriptor (
1905 IN OPAL_SESSION *Session,
1906 IN UINT16 FeatureCode,
1907 IN OUT UINTN *DataSize,
1908 OUT VOID *Data
1909 )
1910 {
1911 UINT8 Buffer[BUFFER_SIZE];
1912 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;
1913 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;
1914 UINTN Size;
1915
1916 NULL_CHECK (Session);
1917 NULL_CHECK (DataSize);
1918 NULL_CHECK (Data);
1919
1920 ZeroMem (Buffer, BUFFER_SIZE);
1921 ASSERT (sizeof (Buffer) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS));
1922
1923 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {
1924 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1925 return TcgResultFailure;
1926 }
1927
1928 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER *)Buffer;
1929
1930 Size = 0;
1931 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR *)TcgGetFeature (DiscoveryHeader, FeatureCode, &Size);
1932 if (Feat != NULL) {
1933 if (Size > *DataSize) {
1934 *DataSize = Size;
1935 return TcgResultFailureBufferTooSmall;
1936 }
1937
1938 *DataSize = Size;
1939 CopyMem (Data, Feat, Size);
1940 }
1941
1942 return TcgResultSuccess;
1943 }
1944
1945 /**
1946
1947 The function determines whether or not all of the requirements for the Opal Feature (not full specification)
1948 are met by the specified device.
1949
1950 @param[in] SupportedAttributes Opal device attribute.
1951
1952 **/
1953 BOOLEAN
1954 EFIAPI
1955 OpalFeatureSupported (
1956 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes
1957 )
1958 {
1959 NULL_CHECK (SupportedAttributes);
1960
1961 if (SupportedAttributes->Sp1 == 0) {
1962 return FALSE;
1963 }
1964
1965 if ((SupportedAttributes->OpalSscLite == 0) &&
1966 (SupportedAttributes->OpalSsc1 == 0) &&
1967 (SupportedAttributes->OpalSsc2 == 0) &&
1968 (SupportedAttributes->PyriteSsc == 0) &&
1969 (SupportedAttributes->PyriteSscV2 == 0)
1970 )
1971 {
1972 return FALSE;
1973 }
1974
1975 return TRUE;
1976 }
1977
1978 /**
1979
1980 The function returns whether or not the device is Opal Enabled.
1981 TRUE means that the device is partially or fully locked.
1982 This will perform a Level 0 Discovery and parse the locking feature descriptor
1983
1984 @param[in] SupportedAttributes Opal device attribute.
1985 @param[in] LockingFeature Opal device locking status.
1986
1987
1988 **/
1989 BOOLEAN
1990 EFIAPI
1991 OpalFeatureEnabled (
1992 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
1993 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature
1994 )
1995 {
1996 NULL_CHECK (SupportedAttributes);
1997 NULL_CHECK (LockingFeature);
1998
1999 if (!OpalFeatureSupported (SupportedAttributes)) {
2000 return FALSE;
2001 }
2002
2003 if (LockingFeature->LockingSupported && LockingFeature->LockingEnabled) {
2004 return TRUE;
2005 }
2006
2007 return FALSE;
2008 }
2009
2010 /**
2011
2012 The function returns whether or not the device is Opal Locked.
2013 TRUE means that the device is partially or fully locked.
2014 This will perform a Level 0 Discovery and parse the locking feature descriptor
2015
2016 @param[in] SupportedAttributes Opal device attribute.
2017 @param[in] LockingFeature Opal device locking status.
2018
2019 **/
2020 BOOLEAN
2021 OpalDeviceLocked (
2022 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
2023 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature
2024 )
2025 {
2026 NULL_CHECK (SupportedAttributes);
2027 NULL_CHECK (LockingFeature);
2028
2029 if (!OpalFeatureEnabled (SupportedAttributes, LockingFeature)) {
2030 return FALSE;
2031 }
2032
2033 return LockingFeature->Locked;
2034 }