2 Public API for Opal Core library.
4 Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
16 #include "TcgStorageOpalLibInternal.h"
20 UINT8 HardwareReset
: 1;
22 } TCG_BLOCK_SID_CLEAR_EVENTS
;
25 #define TRUSTED_COMMAND_TIMEOUT_NS ((UINT64) 5 * ((UINT64)(1000000)) * 1000) // 5 seconds
26 #define BUFFER_SIZE 512
29 The function performs a Trusted Send of a Buffer containing a TCG_COM_PACKET.
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.
42 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Sscp
,
44 UINT8 SecurityProtocol
,
51 UINTN TransferLength512
;
55 // Round transferLength up to a 512-byte multiple
57 TransferLength512
= (TransferLength
+ 511) & ~(UINTN
)511;
59 if (TransferLength512
> BufferSize
) {
60 return TcgResultFailureBufferTooSmall
;
63 ZeroMem ((UINT8
*)Buffer
+ TransferLength
, TransferLength512
- TransferLength
);
65 Status
= Sscp
->SendData (
68 TRUSTED_COMMAND_TIMEOUT_NS
,
70 SwapBytes16 (SpSpecific
),
75 return Status
== EFI_SUCCESS
? TcgResultSuccess
: TcgResultFailure
;
80 The function performs a Trusted Receive of a Buffer containing a TCG_COM_PACKET.
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.
93 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Sscp
,
95 UINT8 SecurityProtocol
,
99 UINT32 EstimateTimeCost
102 UINTN TransferLength512
;
104 TCG_COM_PACKET
*ComPacket
;
106 UINT32 OutstandingData
;
111 // Round Buffer Size down to a 512-byte multiple
113 TransferLength512
= BufferSize
& ~(UINTN
)511;
119 if (TransferLength512
< sizeof (TCG_COM_PACKET
)) {
120 DEBUG ((DEBUG_INFO
, "transferLength %u too small for ComPacket\n", TransferLength512
));
121 return TcgResultFailureBufferTooSmall
;
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.
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
133 if (EstimateTimeCost
> 10) {
134 Tries
= EstimateTimeCost
* 500; // 500 = 1000 * 1000 / 2000;
139 while ((Tries
--) > 0) {
140 ZeroMem (Buffer
, BufferSize
);
143 Status
= Sscp
->ReceiveData (
146 TRUSTED_COMMAND_TIMEOUT_NS
,
148 SwapBytes16 (SpSpecific
),
153 if (EFI_ERROR (Status
)) {
154 return TcgResultFailure
;
157 if ((SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_1
) && (SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_2
)) {
158 return TcgResultSuccess
;
161 if (SpSpecific
== TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
) {
162 return TcgResultSuccess
;
165 ComPacket
= (TCG_COM_PACKET
*)Buffer
;
166 Length
= SwapBytes32 (ComPacket
->LengthBE
);
167 OutstandingData
= SwapBytes32 (ComPacket
->OutstandingDataBE
);
169 if ((Length
!= 0) && (OutstandingData
== 0)) {
170 return TcgResultSuccess
;
176 MicroSecondDelay (2000);
179 return TcgResultFailure
;
183 The function performs send, recv, check comIDs, check method status action.
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.
196 OPAL_SESSION
*Session
,
200 TCG_PARSE_STRUCT
*ParseStruct
,
202 UINT32 EstimateTimeCost
205 NULL_CHECK (Session
);
206 NULL_CHECK (MethodStatus
);
212 TCG_OPAL_SECURITY_PROTOCOL_1
,
213 Session
->OpalBaseComId
,
224 TCG_OPAL_SECURITY_PROTOCOL_1
,
225 Session
->OpalBaseComId
,
232 ERROR_CHECK (TcgInitTcgParseStruct (ParseStruct
, Buffer
, BufferSize
));
233 ERROR_CHECK (TcgCheckComIds (ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
234 ERROR_CHECK (TcgGetMethodStatus (ParseStruct
, MethodStatus
));
236 return TcgResultSuccess
;
240 Trig the block sid action.
242 @param[in] Session OPAL_SESSION related to this method..
243 @param[in] HardwareReset Whether need to do hardware reset.
249 OPAL_SESSION
*Session
,
250 BOOLEAN HardwareReset
253 UINT8 Buffer
[BUFFER_SIZE
];
254 TCG_BLOCK_SID_CLEAR_EVENTS
*ClearEvents
;
256 NULL_CHECK (Session
);
259 // Set Hardware Reset bit
261 ClearEvents
= (TCG_BLOCK_SID_CLEAR_EVENTS
*)&Buffer
[0];
263 ClearEvents
->Reserved
= 0;
264 ClearEvents
->HardwareReset
= HardwareReset
;
266 return (OpalTrustedSend (
269 TCG_OPAL_SECURITY_PROTOCOL_2
,
270 TCG_BLOCKSID_COMID
, // hardcode ComID 0x0005
279 Reverts device using Admin SP Revert method.
281 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
287 OPAL_SESSION
*AdminSpSession
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?
295 TCG_CREATE_STRUCT CreateStruct
;
296 TCG_PARSE_STRUCT ParseStruct
;
298 UINT8 Buffer
[BUFFER_SIZE
];
301 NULL_CHECK (AdminSpSession
);
304 // Send Revert action on Admin SP
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
));
319 // Send Revert Method Call
321 ERROR_CHECK (OpalPerformMethod (AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
322 METHOD_STATUS_ERROR_CHECK (MethodStatus
, TcgResultFailure
);
324 return TcgResultSuccess
;
329 Reverts device using Admin SP Revert method.
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.
336 OpalPyrite2PsidRevert (
337 OPAL_SESSION
*AdminSpSession
,
338 UINT32 EstimateTimeCost
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?
346 TCG_CREATE_STRUCT CreateStruct
;
347 TCG_PARSE_STRUCT ParseStruct
;
349 UINT8 Buffer
[BUFFER_SIZE
];
352 NULL_CHECK (AdminSpSession
);
355 // Send Revert action on Admin SP
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
));
370 // Send Revert Method Call
372 ERROR_CHECK (OpalPerformMethod (AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, EstimateTimeCost
));
373 METHOD_STATUS_ERROR_CHECK (MethodStatus
, TcgResultFailure
);
375 return TcgResultSuccess
;
380 The function fills in the provided Buffer with the level 0 discovery Header
381 of the device specified.
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
390 OpalRetrieveLevel0DiscoveryHeader (
391 OPAL_SESSION
*Session
,
396 return (OpalTrustedRecv (
399 TCG_OPAL_SECURITY_PROTOCOL_1
, // SP
400 TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
, // SP_Specific
409 The function fills in the provided Buffer with the supported protocol list
410 of the device specified.
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
419 OpalRetrieveSupportedProtocolList (
420 OPAL_SESSION
*Session
,
425 return (OpalTrustedRecv (
428 TCG_SECURITY_PROTOCOL_INFO
, // SP
429 TCG_SP_SPECIFIC_PROTOCOL_LIST
, // SP_Specific
437 Starts a session with a security provider (SP).
439 If a session is started successfully, the caller must end the session with OpalEndSession when finished
440 performing Opal actions.
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.
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.
457 OPAL_SESSION
*Session
,
460 UINT32 HostChallengeLength
,
461 const VOID
*HostChallenge
,
462 TCG_UID HostSigningAuthority
,
466 TCG_CREATE_STRUCT CreateStruct
;
467 TCG_PARSE_STRUCT ParseStruct
;
469 UINT8 Buf
[BUFFER_SIZE
];
470 UINT16 ComIdExtension
;
471 UINT32 HostSessionId
;
476 NULL_CHECK (Session
);
477 NULL_CHECK (MethodStatus
);
479 Session
->ComIdExtension
= ComIdExtension
;
480 Session
->HostSessionId
= HostSessionId
;
482 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
484 TcgCreateStartSession (
487 Session
->OpalBaseComId
,
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
502 if (TcgParseSyncSession (&ParseStruct
, Session
->OpalBaseComId
, ComIdExtension
, HostSessionId
, &Session
->TperSessionId
) != TcgResultSuccess
) {
503 OpalEndSession (Session
);
504 return TcgResultFailure
;
507 return TcgResultSuccess
;
511 Close a session opened with OpalStartSession.
513 @param[in/out] Session OPAL_SESSION to end.
519 OPAL_SESSION
*Session
522 UINT8 Buffer
[BUFFER_SIZE
];
523 TCG_CREATE_STRUCT CreateStruct
;
525 TCG_PARSE_STRUCT ParseStruct
;
527 NULL_CHECK (Session
);
528 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buffer
, sizeof (Buffer
)));
530 TcgCreateEndSession (
533 Session
->OpalBaseComId
,
534 Session
->ComIdExtension
,
535 Session
->HostSessionId
,
536 Session
->TperSessionId
544 TCG_OPAL_SECURITY_PROTOCOL_1
,
545 Session
->OpalBaseComId
,
556 TCG_OPAL_SECURITY_PROTOCOL_1
,
557 Session
->OpalBaseComId
,
564 ERROR_CHECK (TcgInitTcgParseStruct (&ParseStruct
, Buffer
, sizeof (Buffer
)));
565 ERROR_CHECK (TcgCheckComIds (&ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
567 ERROR_CHECK (TcgGetNextEndOfSession (&ParseStruct
));
568 return TcgResultSuccess
;
573 The function retrieves the MSID from the device specified
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
584 OPAL_SESSION
*AdminSpSession
,
585 UINT32 MsidBufferSize
,
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?
595 TCG_CREATE_STRUCT CreateStruct
;
596 TCG_PARSE_STRUCT ParseStruct
;
600 const VOID
*RecvMsid
;
601 UINT8 Buffer
[BUFFER_SIZE
];
603 NULL_CHECK (AdminSpSession
);
605 NULL_CHECK (MsidLength
);
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
));
630 // Send MSID Method Call
632 ERROR_CHECK (OpalPerformMethod (AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
633 METHOD_STATUS_ERROR_CHECK (MethodStatus
, TcgResultFailure
);
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
));
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
;
650 if (RecvMsid
== NULL
) {
651 return TcgResultFailure
;
654 if (MsidBufferSize
< *MsidLength
) {
655 DEBUG ((DEBUG_INFO
, "Buffer too small MsidBufferSize: %d MsidLength: %d\n", MsidBufferSize
, *MsidLength
));
656 return TcgResultFailureBufferTooSmall
;
660 // copy msid into Buffer
662 CopyMem (Msid
, RecvMsid
, *MsidLength
);
663 return TcgResultSuccess
;
668 The function retrieves the MSID from the device specified
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.
675 OpalPyrite2GetActiveDataRemovalMechanism (
676 IN OPAL_SESSION
*AdminSpSession
,
677 OUT UINT8
*ActiveDataRemovalMechanism
680 TCG_CREATE_STRUCT CreateStruct
;
681 TCG_PARSE_STRUCT ParseStruct
;
685 UINT8 RecvActiveDataRemovalMechanism
;
686 UINT8 Buffer
[BUFFER_SIZE
];
688 NULL_CHECK (AdminSpSession
);
689 NULL_CHECK (ActiveDataRemovalMechanism
);
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
));
714 // Send Get Active Data Removal Mechanism Method Call
716 ERROR_CHECK (OpalPerformMethod (AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
717 METHOD_STATUS_ERROR_CHECK (MethodStatus
, TcgResultFailure
);
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
));
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
;
734 if (RecvActiveDataRemovalMechanism
>= ResearvedMechanism
) {
735 return TcgResultFailure
;
739 // Copy active data removal mechanism into Buffer
741 CopyMem (ActiveDataRemovalMechanism
, &RecvActiveDataRemovalMechanism
, sizeof (RecvActiveDataRemovalMechanism
));
742 return TcgResultSuccess
;
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.
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.
758 OPAL_SESSION
*LockingSpSession
,
759 BOOLEAN KeepUserData
,
763 UINT8 Buf
[BUFFER_SIZE
];
764 TCG_CREATE_STRUCT CreateStruct
;
766 TCG_PARSE_STRUCT ParseStruct
;
769 NULL_CHECK (LockingSpSession
);
770 NULL_CHECK (MethodStatus
);
773 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
777 // set readlocked and writelocked to false
779 Ret
= OpalUpdateGlobalLockingRange (
786 if ((Ret
!= TcgResultSuccess
) || (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
)) {
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
));
803 // optional parameter to keep Data after revert
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
));
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
));
818 // Send RevertSP method call
820 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
823 // Session is immediately ended by device after successful revertsp, so no need to end Session
825 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
827 // Caller should take ownership again
829 return TcgResultSuccess
;
834 METHOD_STATUS_ERROR_CHECK (*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
837 return TcgResultSuccess
;
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.
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.
852 OpalPyrite2AdminRevert (
853 OPAL_SESSION
*LockingSpSession
,
854 BOOLEAN KeepUserData
,
856 UINT32 EstimateTimeCost
859 UINT8 Buf
[BUFFER_SIZE
];
860 TCG_CREATE_STRUCT CreateStruct
;
862 TCG_PARSE_STRUCT ParseStruct
;
865 NULL_CHECK (LockingSpSession
);
866 NULL_CHECK (MethodStatus
);
869 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
873 // set readlocked and writelocked to false
875 Ret
= OpalUpdateGlobalLockingRange (
882 if ((Ret
!= TcgResultSuccess
) || (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
)) {
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
));
899 // optional parameter to keep Data after revert
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
));
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
));
914 // Send RevertSP method call
916 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, EstimateTimeCost
));
919 // Session is immediately ended by device after successful revertsp, so no need to end Session
921 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
923 // Caller should take ownership again
925 return TcgResultSuccess
;
930 METHOD_STATUS_ERROR_CHECK (*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
933 return TcgResultSuccess
;
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.
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.
948 OpalActivateLockingSp (
949 OPAL_SESSION
*AdminSpSession
,
953 UINT8 Buf
[BUFFER_SIZE
];
954 TCG_CREATE_STRUCT CreateStruct
;
956 TCG_PARSE_STRUCT ParseStruct
;
958 NULL_CHECK (AdminSpSession
);
959 NULL_CHECK (MethodStatus
);
962 // Call Activate method on Locking SP
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
));
977 // Send Activate method call
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
982 return TcgResultSuccess
;
987 The function sets the PIN column of the specified cpinRowUid (authority) with the newPin Value.
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.
999 OPAL_SESSION
*Session
,
1002 UINT32 NewPinLength
,
1006 UINT8 Buf
[BUFFER_SIZE
];
1007 TCG_CREATE_STRUCT CreateStruct
;
1008 TCG_PARSE_STRUCT ParseStruct
;
1011 NULL_CHECK (Session
);
1012 NULL_CHECK (NewPin
);
1013 NULL_CHECK (MethodStatus
);
1015 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1020 Session
->OpalBaseComId
,
1021 Session
->ComIdExtension
,
1022 Session
->TperSessionId
,
1023 Session
->HostSessionId
,
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
);
1034 return TcgResultSuccess
;
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.
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.
1052 OpalSetLockingSpAuthorityEnabledAndPin (
1053 OPAL_SESSION
*LockingSpSession
,
1055 TCG_UID AuthorityUid
,
1057 UINT32 NewPinLength
,
1061 UINT8 Buf
[BUFFER_SIZE
];
1062 TCG_CREATE_STRUCT CreateStruct
;
1063 TCG_PARSE_STRUCT ParseStruct
;
1068 NULL_CHECK (LockingSpSession
);
1069 NULL_CHECK (NewPin
);
1070 NULL_CHECK (MethodStatus
);
1072 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1074 TcgSetAuthorityEnabled (
1077 LockingSpSession
->OpalBaseComId
,
1078 LockingSpSession
->ComIdExtension
,
1079 LockingSpSession
->TperSessionId
,
1080 LockingSpSession
->HostSessionId
,
1086 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1088 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1089 DEBUG ((DEBUG_INFO
, "Send Set Authority error\n"));
1090 return TcgResultFailure
;
1093 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1099 LockingSpSession
->OpalBaseComId
,
1100 LockingSpSession
->ComIdExtension
,
1101 LockingSpSession
->TperSessionId
,
1102 LockingSpSession
->HostSessionId
,
1109 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1112 // allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked
1114 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
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
1130 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1132 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1133 DEBUG ((DEBUG_INFO
, "Update ACE for RDLOCKED failed\n"));
1134 return TcgResultFailure
;
1137 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
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
1153 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1155 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1156 DEBUG ((DEBUG_INFO
, "Update ACE for WRLOCKED failed\n"));
1157 return TcgResultFailure
;
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));
1165 // For Pyrite type SSC, it not supports Active Key.
1166 // So here add check logic before enable it.
1168 Ret
= OpalParseRetrieveGlobalLockingRangeActiveKey (&ParseStruct
, &ActiveKey
);
1169 if (Ret
== TcgResultSuccess
) {
1170 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
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
1186 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1188 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1189 DEBUG ((DEBUG_INFO
, "Update ACE for GLOBALRANGE_GENKEY failed\n"));
1191 // Disable user1 if all permissions are not granted.
1193 return TcgResultFailure
;
1197 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
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
1213 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
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
;
1220 return TcgResultSuccess
;
1225 The function sets the Enabled column to FALSE for the USER1 authority.
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.
1234 OPAL_SESSION
*LockingSpSession
,
1238 UINT8 Buf
[BUFFER_SIZE
];
1239 TCG_CREATE_STRUCT CreateStruct
;
1240 TCG_PARSE_STRUCT ParseStruct
;
1243 NULL_CHECK (LockingSpSession
);
1244 NULL_CHECK (MethodStatus
);
1246 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1248 TcgSetAuthorityEnabled (
1251 LockingSpSession
->OpalBaseComId
,
1252 LockingSpSession
->ComIdExtension
,
1253 LockingSpSession
->TperSessionId
,
1254 LockingSpSession
->HostSessionId
,
1255 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1260 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1262 return TcgResultSuccess
;
1267 The function retrieves the active key of the global locking range
1268 and calls the GenKey method on the active key retrieved.
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.
1276 OpalGlobalLockingRangeGenKey (
1277 OPAL_SESSION
*LockingSpSession
,
1281 UINT8 Buf
[BUFFER_SIZE
];
1282 TCG_CREATE_STRUCT CreateStruct
;
1283 TCG_PARSE_STRUCT ParseStruct
;
1287 NULL_CHECK (LockingSpSession
);
1288 NULL_CHECK (MethodStatus
);
1290 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1292 // retrieve the activekey in order to know which globalrange key to generate
1294 ERROR_CHECK (OpalCreateRetrieveGlobalLockingRangeActiveKey (LockingSpSession
, &CreateStruct
, &Size
));
1295 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1297 METHOD_STATUS_ERROR_CHECK (*MethodStatus
, TcgResultSuccess
);
1299 ERROR_CHECK (OpalParseRetrieveGlobalLockingRangeActiveKey (&ParseStruct
, &ActiveKey
));
1302 // call genkey on ActiveKey UID
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
));
1316 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1318 return TcgResultSuccess
;
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).
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.
1335 OpalUpdateGlobalLockingRange (
1336 OPAL_SESSION
*LockingSpSession
,
1338 BOOLEAN WriteLocked
,
1342 UINT8 Buf
[BUFFER_SIZE
];
1343 TCG_CREATE_STRUCT CreateStruct
;
1344 TCG_PARSE_STRUCT ParseStruct
;
1347 NULL_CHECK (LockingSpSession
);
1348 NULL_CHECK (MethodStatus
);
1350 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1353 // set global locking range values
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
));
1364 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1365 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x07)); // "ReadLocked"
1366 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, ReadLocked
));
1367 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
1369 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1370 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x08)); // "WriteLocked"
1371 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, WriteLocked
));
1372 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
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
));
1382 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, MethodStatus
, 0));
1383 METHOD_STATUS_ERROR_CHECK (*MethodStatus
, TcgResultSuccess
);
1385 return TcgResultSuccess
;
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.
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.
1406 OpalSetLockingRange (
1407 OPAL_SESSION
*LockingSpSession
,
1408 TCG_UID LockingRangeUid
,
1411 BOOLEAN ReadLockEnabled
,
1412 BOOLEAN WriteLockEnabled
,
1414 BOOLEAN WriteLocked
,
1418 UINT8 Buf
[BUFFER_SIZE
];
1419 TCG_CREATE_STRUCT CreateStruct
;
1420 TCG_PARSE_STRUCT ParseStruct
;
1423 NULL_CHECK (LockingSpSession
);
1424 NULL_CHECK (MethodStatus
);
1426 ERROR_CHECK (TcgInitTcgCreateStruct (&CreateStruct
, Buf
, sizeof (Buf
)));
1429 // set locking range values
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
));
1441 // range start and range Length only apply to non-global locking ranges
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
));
1449 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1450 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x04)); // "RangeLength"
1451 ERROR_CHECK (TcgAddUINT64 (&CreateStruct
, RangeLength
));
1452 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
1455 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1456 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x05)); // "ReadLockEnabled"
1457 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, ReadLockEnabled
));
1458 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
1460 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1461 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x06)); // "WriteLockEnabled"
1462 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, WriteLockEnabled
));
1463 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
1465 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1466 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x07)); // "ReadLocked"
1467 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, ReadLocked
));
1468 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
1470 ERROR_CHECK (TcgAddStartName (&CreateStruct
));
1471 ERROR_CHECK (TcgAddUINT8 (&CreateStruct
, 0x08)); // "WriteLocked"
1472 ERROR_CHECK (TcgAddBOOLEAN (&CreateStruct
, WriteLocked
));
1473 ERROR_CHECK (TcgAddEndName (&CreateStruct
));
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
));
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
);
1487 return TcgResultSuccess
;
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.
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.
1503 OpalCreateRetrieveGlobalLockingRangeActiveKey (
1504 const OPAL_SESSION
*Session
,
1505 TCG_CREATE_STRUCT
*CreateStruct
,
1509 NULL_CHECK (Session
);
1510 NULL_CHECK (CreateStruct
);
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
));
1535 return TcgResultSuccess
;
1540 The function acquires the activeKey specified for the Global Locking Range from the ParseStruct.
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
1548 OpalParseRetrieveGlobalLockingRangeActiveKey (
1549 TCG_PARSE_STRUCT
*ParseStruct
,
1555 NULL_CHECK (ParseStruct
);
1556 NULL_CHECK (ActiveKey
);
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
));
1569 if (ColumnName
!= 0x0A) {
1570 DEBUG ((DEBUG_INFO
, "Unexpected column name %u (exp 0x0A)\n", ColumnName
));
1571 return TcgResultFailure
;
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
;
1579 return TcgResultSuccess
;
1584 The function retrieves the TryLimit column for the specified rowUid (authority).
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
1594 OPAL_SESSION
*LockingSpSession
,
1599 TCG_CREATE_STRUCT CreateStruct
;
1600 TCG_PARSE_STRUCT ParseStruct
;
1603 UINT8 Buf
[BUFFER_SIZE
];
1606 NULL_CHECK (LockingSpSession
);
1607 NULL_CHECK (TryLimit
);
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
));
1631 ERROR_CHECK (OpalPerformMethod (LockingSpSession
, Size
, Buf
, sizeof (Buf
), &ParseStruct
, &MethodStatus
, 0));
1632 METHOD_STATUS_ERROR_CHECK (MethodStatus
, TcgResultFailure
);
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
));
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
;
1649 return TcgResultSuccess
;
1654 Get the support attribute info.
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.
1663 OpalGetSupportedAttributesInfo (
1664 IN OPAL_SESSION
*Session
,
1665 OUT OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1666 OUT UINT16
*OpalBaseComId
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
;
1677 NULL_CHECK (Session
);
1678 NULL_CHECK (SupportedAttributes
);
1679 NULL_CHECK (OpalBaseComId
);
1681 ZeroMem (Buffer
, BUFFER_SIZE
);
1682 ZeroMem (SupportedAttributes
, sizeof (OPAL_DISK_SUPPORT_ATTRIBUTE
));
1683 ASSERT (sizeof (Buffer
) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1686 // Retrieve supported protocols verify security protocol 1 is supported
1688 SupportedProtocols
= (TCG_SUPPORTED_SECURITY_PROTOCOLS
*)Buffer
;
1691 // Get list of supported protocols
1693 if (OpalRetrieveSupportedProtocolList (Session
, sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS
), SupportedProtocols
) == TcgResultFailure
) {
1694 DEBUG ((DEBUG_INFO
, "OpalRetrieveSupportedProtocolList failed\n"));
1695 return TcgResultFailure
;
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
);
1704 "Supported Protocols: Sp1 %d Sp2: %d SpIeee1667 %d \n",
1705 SupportedAttributes
->Sp1
,
1706 SupportedAttributes
->Sp2
,
1707 SupportedAttributes
->SpIeee1667
1711 // Perform level 0 discovery and assign desired feature info to Opal Disk structure
1713 ZeroMem (Buffer
, BUFFER_SIZE
);
1714 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1715 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1716 return TcgResultFailure
;
1720 // Check for required feature descriptors
1722 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*)Buffer
;
1725 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*)TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_V2_0_0
, &Size
);
1726 SupportedAttributes
->OpalSsc2
= (Feat
!= NULL
);
1728 *OpalBaseComId
= TCG_RESERVED_COMID
;
1731 // Check Opal SCC V2 has valid settings for SID C_PIN on revert
1733 if (SupportedAttributes
->OpalSsc2
&& (Size
>= sizeof (OPAL_SSCV2_FEATURE_DESCRIPTOR
))) {
1735 // Want opposite polarity b/c Value is greater than a bit, but we only care about non-zero vs zero
1737 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1738 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1741 "Opal SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1742 SupportedAttributes
->InitCpinIndicator
,
1743 SupportedAttributes
->CpinUponRevert
1745 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscV2
.BaseComdIdBE
);
1749 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*)TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_LITE
, &Size
);
1750 SupportedAttributes
->OpalSscLite
= (Feat
!= NULL
);
1752 if ((Feat
!= NULL
) && (Size
>= sizeof (OPAL_SSCLITE_FEATURE_DESCRIPTOR
))) {
1753 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1755 // Pin values used always match up with ComId used
1757 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscLite
.BaseComdIdBE
);
1758 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1759 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1762 "Opal SSC Lite InitCpinIndicator %d CpinUponRevert %d \n",
1763 SupportedAttributes
->InitCpinIndicator
,
1764 SupportedAttributes
->CpinUponRevert
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.
1774 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*)TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_PYRITE_SSC
, &Size
);
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);
1785 "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1786 SupportedAttributes
->InitCpinIndicator
,
1787 SupportedAttributes
->CpinUponRevert
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);
1799 "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",
1800 SupportedAttributes
->InitCpinIndicator
,
1801 SupportedAttributes
->CpinUponRevert
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
);
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
));
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
));
1829 DEBUG ((DEBUG_INFO
, "BlockSid Unsupported!!!"));
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
)));
1846 DEBUG ((DEBUG_INFO
, "Base COMID 0x%04X \n", *OpalBaseComId
));
1848 return TcgResultSuccess
;
1853 Get the support attribute info.
1855 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1856 @param[in/out] LockingFeature Return the Locking info.
1861 OpalGetLockingInfo (
1862 OPAL_SESSION
*Session
,
1863 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1866 UINT8 Buffer
[BUFFER_SIZE
];
1867 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1868 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1871 NULL_CHECK (Session
);
1872 NULL_CHECK (LockingFeature
);
1874 ZeroMem (Buffer
, BUFFER_SIZE
);
1875 ASSERT (sizeof (Buffer
) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1877 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1878 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1879 return TcgResultFailure
;
1882 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*)Buffer
;
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
));
1890 return TcgResultSuccess
;
1895 Get the descriptor for the specific feature code.
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.
1904 OpalGetFeatureDescriptor (
1905 IN OPAL_SESSION
*Session
,
1906 IN UINT16 FeatureCode
,
1907 IN OUT UINTN
*DataSize
,
1911 UINT8 Buffer
[BUFFER_SIZE
];
1912 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1913 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1916 NULL_CHECK (Session
);
1917 NULL_CHECK (DataSize
);
1920 ZeroMem (Buffer
, BUFFER_SIZE
);
1921 ASSERT (sizeof (Buffer
) >= sizeof (TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1923 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1924 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1925 return TcgResultFailure
;
1928 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*)Buffer
;
1931 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*)TcgGetFeature (DiscoveryHeader
, FeatureCode
, &Size
);
1933 if (Size
> *DataSize
) {
1935 return TcgResultFailureBufferTooSmall
;
1939 CopyMem (Data
, Feat
, Size
);
1942 return TcgResultSuccess
;
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.
1950 @param[in] SupportedAttributes Opal device attribute.
1955 OpalFeatureSupported (
1956 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
1959 NULL_CHECK (SupportedAttributes
);
1961 if (SupportedAttributes
->Sp1
== 0) {
1965 if ((SupportedAttributes
->OpalSscLite
== 0) &&
1966 (SupportedAttributes
->OpalSsc1
== 0) &&
1967 (SupportedAttributes
->OpalSsc2
== 0) &&
1968 (SupportedAttributes
->PyriteSsc
== 0) &&
1969 (SupportedAttributes
->PyriteSscV2
== 0)
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
1984 @param[in] SupportedAttributes Opal device attribute.
1985 @param[in] LockingFeature Opal device locking status.
1991 OpalFeatureEnabled (
1992 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1993 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1996 NULL_CHECK (SupportedAttributes
);
1997 NULL_CHECK (LockingFeature
);
1999 if (!OpalFeatureSupported (SupportedAttributes
)) {
2003 if (LockingFeature
->LockingSupported
&& LockingFeature
->LockingEnabled
) {
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
2016 @param[in] SupportedAttributes Opal device attribute.
2017 @param[in] LockingFeature Opal device locking status.
2022 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
2023 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
2026 NULL_CHECK (SupportedAttributes
);
2027 NULL_CHECK (LockingFeature
);
2029 if (!OpalFeatureEnabled (SupportedAttributes
, LockingFeature
)) {
2033 return LockingFeature
->Locked
;