2 Public API for Opal Core library.
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/TimerLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/TcgStorageOpalLib.h>
22 #include "TcgStorageOpalLibInternal.h"
26 UINT8 HardwareReset
: 1;
28 } TCG_BLOCK_SID_CLEAR_EVENTS
;
31 #define TRUSTED_COMMAND_TIMEOUT_NS ((UINT64) 5 * ((UINT64)(1000000)) * 1000) // 5 seconds
32 #define BUFFER_SIZE 512
35 The function performs a Trusted Send of a Buffer containing a TCG_COM_PACKET.
37 @param[in] Sscp The input Ssc Protocol.
38 @param[in] MediaId The input Media id info used by Ssc Protocol.
39 @param[in] SecurityProtocol Security Protocol
40 @param[in] SpSpecific Security Protocol Specific
41 @param[in] TransferLength Transfer Length of Buffer (in bytes) - always a multiple of 512
42 @param[in] Buffer Address of Data to transfer
43 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
48 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Sscp
,
50 UINT8 SecurityProtocol
,
57 UINTN TransferLength512
;
61 // Round transferLength up to a 512-byte multiple
63 TransferLength512
= (TransferLength
+ 511) & ~(UINTN
)511;
65 if (TransferLength512
> BufferSize
) {
66 return TcgResultFailureBufferTooSmall
;
69 ZeroMem((UINT8
*)Buffer
+ TransferLength
, TransferLength512
- TransferLength
);
71 Status
= Sscp
->SendData(
74 TRUSTED_COMMAND_TIMEOUT_NS
,
76 SwapBytes16(SpSpecific
),
81 return Status
== EFI_SUCCESS
? TcgResultSuccess
: TcgResultFailure
;
86 The function performs a Trusted Receive of a Buffer containing a TCG_COM_PACKET.
88 @param[in] Sscp The input Ssc Protocol.
89 @param[in] MediaId The input Media id info used by Ssc Protocol.
90 @param[in] SecurityProtocol Security Protocol
91 @param[in] SpSpecific Security Protocol Specific
92 @param[in] Buffer Address of Data to transfer
93 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
94 @param[in] EstimateTimeCost Estimate the time needed.
99 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Sscp
,
101 UINT8 SecurityProtocol
,
105 UINT32 EstimateTimeCost
108 UINTN TransferLength512
;
110 TCG_COM_PACKET
*ComPacket
;
112 UINT32 OutstandingData
;
117 // Round Buffer Size down to a 512-byte multiple
119 TransferLength512
= BufferSize
& ~(UINTN
)511;
125 if (TransferLength512
< sizeof(TCG_COM_PACKET
)) {
126 DEBUG ((DEBUG_INFO
, "transferLength %u too small for ComPacket\n", TransferLength512
));
127 return TcgResultFailureBufferTooSmall
;
131 // Some devices respond with Length = 0 and OutstandingData = 1 to indicate that processing is not yet completed,
132 // so we need to retry the IF-RECV to get the actual Data.
133 // See TCG Core Spec v2 Table 45 IF-RECV ComPacket Field Values Summary
134 // This is an arbitrary number of retries, not from the spec.
136 // if user input estimate time cost(second level) value bigger than 10s, base on user input value to wait.
137 // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms = 10s
139 if (EstimateTimeCost
> 10) {
140 Tries
= EstimateTimeCost
* 500; // 500 = 1000 * 1000 / 2000;
144 while ((Tries
--) > 0) {
145 ZeroMem( Buffer
, BufferSize
);
148 Status
= Sscp
->ReceiveData(
151 TRUSTED_COMMAND_TIMEOUT_NS
,
153 SwapBytes16(SpSpecific
),
158 if (EFI_ERROR (Status
)) {
159 return TcgResultFailure
;
162 if (SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_1
&& SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_2
) {
163 return TcgResultSuccess
;
166 if (SpSpecific
== TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
) {
167 return TcgResultSuccess
;
170 ComPacket
= (TCG_COM_PACKET
*) Buffer
;
171 Length
= SwapBytes32(ComPacket
->LengthBE
);
172 OutstandingData
= SwapBytes32( ComPacket
->OutstandingDataBE
);
174 if (Length
!= 0 && OutstandingData
== 0) {
175 return TcgResultSuccess
;
181 MicroSecondDelay (2000);
184 return TcgResultFailure
;
188 The function performs send, recv, check comIDs, check method status action.
190 @param[in] Session OPAL_SESSION related to this method..
191 @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512
192 @param[in] Buffer Address of Data to transfer
193 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
194 @param[in] ParseStruct Structure used to parse received TCG response.
195 @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
196 @param[in] EstimateTimeCost Estimate the time need to for the method.
201 OPAL_SESSION
*Session
,
205 TCG_PARSE_STRUCT
*ParseStruct
,
207 UINT32 EstimateTimeCost
211 NULL_CHECK(MethodStatus
);
213 ERROR_CHECK(OpalTrustedSend(
216 TCG_OPAL_SECURITY_PROTOCOL_1
,
217 Session
->OpalBaseComId
,
223 ERROR_CHECK(OpalTrustedRecv(
226 TCG_OPAL_SECURITY_PROTOCOL_1
,
227 Session
->OpalBaseComId
,
233 ERROR_CHECK(TcgInitTcgParseStruct(ParseStruct
, Buffer
, BufferSize
));
234 ERROR_CHECK(TcgCheckComIds(ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
235 ERROR_CHECK(TcgGetMethodStatus(ParseStruct
, MethodStatus
));
237 return TcgResultSuccess
;
241 Trig the block sid action.
243 @param[in] Session OPAL_SESSION related to this method..
244 @param[in] HardwareReset Whether need to do hardware reset.
250 OPAL_SESSION
*Session
,
251 BOOLEAN HardwareReset
254 UINT8 Buffer
[BUFFER_SIZE
];
255 TCG_BLOCK_SID_CLEAR_EVENTS
*ClearEvents
;
260 // Set Hardware Reset bit
262 ClearEvents
= (TCG_BLOCK_SID_CLEAR_EVENTS
*) &Buffer
[0];
264 ClearEvents
->Reserved
= 0;
265 ClearEvents
->HardwareReset
= HardwareReset
;
267 return(OpalTrustedSend(
270 TCG_OPAL_SECURITY_PROTOCOL_2
,
271 TCG_BLOCKSID_COMID
, // hardcode ComID 0x0005
280 Reverts device using Admin SP Revert method.
282 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
288 OPAL_SESSION
*AdminSpSession
292 // Now that base comid is known, start Session
293 // we'll attempt to start Session as PSID authority
294 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
296 TCG_CREATE_STRUCT CreateStruct
;
297 TCG_PARSE_STRUCT ParseStruct
;
299 UINT8 Buffer
[BUFFER_SIZE
];
302 NULL_CHECK(AdminSpSession
);
305 // Send Revert action on Admin SP
307 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
308 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
309 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
310 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
311 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP
, OPAL_ADMIN_SP_REVERT_METHOD
));
312 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
313 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
314 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
315 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
316 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
317 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
320 // Send Revert Method Call
322 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
323 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
325 return TcgResultSuccess
;
330 Reverts device using Admin SP Revert method.
332 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
333 @param[in] EstimateTimeCost Estimate the time needed.
338 OpalPyrite2PsidRevert(
339 OPAL_SESSION
*AdminSpSession
,
340 UINT32 EstimateTimeCost
344 // Now that base comid is known, start Session
345 // we'll attempt to start Session as PSID authority
346 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
348 TCG_CREATE_STRUCT CreateStruct
;
349 TCG_PARSE_STRUCT ParseStruct
;
351 UINT8 Buffer
[BUFFER_SIZE
];
355 NULL_CHECK(AdminSpSession
);
358 // Send Revert action on Admin SP
360 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
361 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
362 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
363 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
364 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP
, OPAL_ADMIN_SP_REVERT_METHOD
));
365 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
366 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
367 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
368 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
369 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
370 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
373 // Send Revert Method Call
375 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, EstimateTimeCost
));
376 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
378 return TcgResultSuccess
;
383 The function fills in the provided Buffer with the level 0 discovery Header
384 of the device specified.
386 @param[in] Session OPAL_SESSION data.
387 @param[in] BufferSize Size of Buffer provided (in bytes)
388 @param[in] BuffAddress Buffer address to fill with Level 0 Discovery response
393 OpalRetrieveLevel0DiscoveryHeader(
394 OPAL_SESSION
*Session
,
399 return (OpalTrustedRecv(
402 TCG_OPAL_SECURITY_PROTOCOL_1
, // SP
403 TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
, // SP_Specific
412 The function fills in the provided Buffer with the supported protocol list
413 of the device specified.
415 @param[in] Session OPAL_SESSION data.
416 @param[in] BufferSize Size of Buffer provided (in bytes)
417 @param[in] BuffAddress Buffer address to fill with security protocol list
422 OpalRetrieveSupportedProtocolList(
423 OPAL_SESSION
*Session
,
428 return (OpalTrustedRecv(
431 TCG_SECURITY_PROTOCOL_INFO
, // SP
432 TCG_SP_SPECIFIC_PROTOCOL_LIST
, // SP_Specific
440 Starts a session with a security provider (SP).
442 If a session is started successfully, the caller must end the session with OpalEndSession when finished
443 performing Opal actions.
445 @param[in/out] Session OPAL_SESSION to initialize.
446 @param[in] SpId Security provider ID to start the session with.
447 @param[in] Write Whether the session should be read-only (FALSE) or read/write (TRUE).
448 @param[in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
449 @param[in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge will be sent.
450 @param[in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority will be sent.
451 @param[in/out] MethodStatus Status of the StartSession method; only valid if TcgResultSuccess is returned.
453 @return TcgResultSuccess indicates that the function completed without any internal errors.
454 The caller must inspect the MethodStatus field to determine whether the method completed successfully.
460 OPAL_SESSION
*Session
,
463 UINT32 HostChallengeLength
,
464 const VOID
*HostChallenge
,
465 TCG_UID HostSigningAuthority
,
469 TCG_CREATE_STRUCT CreateStruct
;
470 TCG_PARSE_STRUCT ParseStruct
;
472 UINT8 Buf
[BUFFER_SIZE
];
473 UINT16 ComIdExtension
;
474 UINT32 HostSessionId
;
480 NULL_CHECK(MethodStatus
);
482 Session
->ComIdExtension
= ComIdExtension
;
483 Session
->HostSessionId
= HostSessionId
;
485 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
486 ERROR_CHECK(TcgCreateStartSession(
489 Session
->OpalBaseComId
,
498 ERROR_CHECK(OpalPerformMethod(Session
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
499 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
500 return TcgResultSuccess
; // return early if method failed - user must check MethodStatus
503 if (TcgParseSyncSession(&ParseStruct
, Session
->OpalBaseComId
, ComIdExtension
, HostSessionId
, &Session
->TperSessionId
) != TcgResultSuccess
) {
504 OpalEndSession(Session
);
505 return TcgResultFailure
;
508 return TcgResultSuccess
;
512 Close a session opened with OpalStartSession.
514 @param[in/out] Session OPAL_SESSION to end.
520 OPAL_SESSION
*Session
523 UINT8 Buffer
[BUFFER_SIZE
];
524 TCG_CREATE_STRUCT CreateStruct
;
526 TCG_PARSE_STRUCT ParseStruct
;
529 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, sizeof(Buffer
)));
530 ERROR_CHECK(TcgCreateEndSession(
533 Session
->OpalBaseComId
,
534 Session
->ComIdExtension
,
535 Session
->HostSessionId
,
536 Session
->TperSessionId
539 ERROR_CHECK(OpalTrustedSend(
542 TCG_OPAL_SECURITY_PROTOCOL_1
,
543 Session
->OpalBaseComId
,
549 ERROR_CHECK(OpalTrustedRecv(
552 TCG_OPAL_SECURITY_PROTOCOL_1
,
553 Session
->OpalBaseComId
,
559 ERROR_CHECK(TcgInitTcgParseStruct(&ParseStruct
, Buffer
, sizeof(Buffer
)));
560 ERROR_CHECK(TcgCheckComIds(&ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
562 ERROR_CHECK(TcgGetNextEndOfSession(&ParseStruct
));
563 return TcgResultSuccess
;
568 The function retrieves the MSID from the device specified
570 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
571 @param[in] MsidBufferSize Allocated Buffer Size (in bytes) for MSID allocated by caller
572 @param[in] Msid Variable Length byte sequence representing MSID of device
573 @param[in] MsidLength Actual Length of MSID retrieved from device
579 OPAL_SESSION
*AdminSpSession
,
580 UINT32 MsidBufferSize
,
586 // now that base comid is known, start Session
587 // we'll attempt to start Session as PSID authority
588 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
590 TCG_CREATE_STRUCT CreateStruct
;
591 TCG_PARSE_STRUCT ParseStruct
;
595 const VOID
*RecvMsid
;
596 UINT8 Buffer
[BUFFER_SIZE
];
598 NULL_CHECK(AdminSpSession
);
600 NULL_CHECK(MsidLength
);
602 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
603 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
604 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
605 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
606 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP_C_PIN_MSID
, TCG_UID_METHOD_GET
));
607 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
608 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
609 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
610 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
611 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_PIN_COL
));
612 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
613 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
614 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
615 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_PIN_COL
));
616 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
617 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
618 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
619 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
620 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
621 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
622 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
625 // Send MSID Method Call
627 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
628 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
630 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
631 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
632 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
633 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
634 ERROR_CHECK(TcgGetNextByteSequence(&ParseStruct
, &RecvMsid
, MsidLength
));
635 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
636 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
637 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
638 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
640 if (Col
!= OPAL_ADMIN_SP_PIN_COL
) {
641 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_ADMIN_SP_PIN_COL
));
642 return TcgResultFailure
;
645 if (RecvMsid
== NULL
) {
646 return TcgResultFailure
;
649 if (MsidBufferSize
< *MsidLength
) {
650 DEBUG ((DEBUG_INFO
, "Buffer too small MsidBufferSize: %d MsidLength: %d\n", MsidBufferSize
, *MsidLength
));
651 return TcgResultFailureBufferTooSmall
;
655 // copy msid into Buffer
657 CopyMem(Msid
, RecvMsid
, *MsidLength
);
658 return TcgResultSuccess
;
663 The function retrieves the MSID from the device specified
665 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY
666 @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism that the device will use for Revert/RevertSP calls.
671 OpalPyrite2GetActiveDataRemovalMechanism (
672 IN OPAL_SESSION
*AdminSpSession
,
673 OUT UINT8
*ActiveDataRemovalMechanism
676 TCG_CREATE_STRUCT CreateStruct
;
677 TCG_PARSE_STRUCT ParseStruct
;
681 UINT8 RecvActiveDataRemovalMechanism
;
682 UINT8 Buffer
[BUFFER_SIZE
];
684 NULL_CHECK(AdminSpSession
);
685 NULL_CHECK(ActiveDataRemovalMechanism
);
687 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
688 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
689 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
690 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
691 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP_DATA_REMOVAL_MECHANISM
, TCG_UID_METHOD_GET
));
692 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
693 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
694 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
695 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
696 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
697 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
698 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
699 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
700 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
701 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
702 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
703 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
704 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
705 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
706 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
707 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
710 // Send Get Active Data Removal Mechanism Method Call
712 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
713 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
715 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
716 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
717 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
718 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
719 ERROR_CHECK(TcgGetNextUINT8(&ParseStruct
, &RecvActiveDataRemovalMechanism
));
720 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
721 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
722 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
723 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
725 if (Col
!= OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
) {
726 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
727 return TcgResultFailure
;
730 if (RecvActiveDataRemovalMechanism
>= ResearvedMechanism
) {
731 return TcgResultFailure
;
735 // Copy active data removal mechanism into Buffer
737 CopyMem(ActiveDataRemovalMechanism
, &RecvActiveDataRemovalMechanism
, sizeof(RecvActiveDataRemovalMechanism
));
738 return TcgResultSuccess
;
743 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
744 to keep the user Data is set to True, otherwise the optional parameter is not provided.
746 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
747 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
748 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
754 OPAL_SESSION
*LockingSpSession
,
755 BOOLEAN KeepUserData
,
759 UINT8 Buf
[BUFFER_SIZE
];
760 TCG_CREATE_STRUCT CreateStruct
;
762 TCG_PARSE_STRUCT ParseStruct
;
765 NULL_CHECK(LockingSpSession
);
766 NULL_CHECK(MethodStatus
);
769 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
773 // set readlocked and writelocked to false
775 Ret
= OpalUpdateGlobalLockingRange(
781 if (Ret
!= TcgResultSuccess
|| *MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
789 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
790 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
791 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
792 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
793 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, TCG_UID_THIS_SP
, OPAL_LOCKING_SP_REVERTSP_METHOD
));
794 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
798 // optional parameter to keep Data after revert
800 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
801 ERROR_CHECK(TcgAddUINT32(&CreateStruct
, 0x060000)); // weird Value but that's what spec says
802 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, KeepUserData
));
803 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
806 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
807 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
808 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
809 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
810 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
813 // Send RevertSP method call
815 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
818 // Session is immediately ended by device after successful revertsp, so no need to end Session
820 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
822 // Caller should take ownership again
824 return TcgResultSuccess
;
829 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
832 return TcgResultSuccess
;
838 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
839 to keep the user Data is set to True, otherwise the optional parameter is not provided.
841 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
842 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
843 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
844 @param[in] EstimateTimeCost Estimate the time needed.
849 OpalPyrite2AdminRevert(
850 OPAL_SESSION
*LockingSpSession
,
851 BOOLEAN KeepUserData
,
853 UINT32 EstimateTimeCost
856 UINT8 Buf
[BUFFER_SIZE
];
857 TCG_CREATE_STRUCT CreateStruct
;
859 TCG_PARSE_STRUCT ParseStruct
;
862 NULL_CHECK(LockingSpSession
);
863 NULL_CHECK(MethodStatus
);
866 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
870 // set readlocked and writelocked to false
872 Ret
= OpalUpdateGlobalLockingRange(
878 if (Ret
!= TcgResultSuccess
|| *MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
886 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
887 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
888 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
889 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
890 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, TCG_UID_THIS_SP
, OPAL_LOCKING_SP_REVERTSP_METHOD
));
891 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
895 // optional parameter to keep Data after revert
897 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
898 ERROR_CHECK(TcgAddUINT32(&CreateStruct
, 0x060000)); // weird Value but that's what spec says
899 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, KeepUserData
));
900 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
903 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
904 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
905 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
906 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
907 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
910 // Send RevertSP method call
912 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, EstimateTimeCost
));
915 // Session is immediately ended by device after successful revertsp, so no need to end Session
917 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
919 // Caller should take ownership again
921 return TcgResultSuccess
;
926 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
929 return TcgResultSuccess
;
934 The function activates the Locking SP.
935 Once activated, per Opal spec, the ADMIN SP SID PIN is copied over to the ADMIN1 LOCKING SP PIN.
936 If the Locking SP is already enabled, then TcgResultSuccess is returned and no action occurs.
938 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY to activate Locking SP
939 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
944 OpalActivateLockingSp(
945 OPAL_SESSION
*AdminSpSession
,
949 UINT8 Buf
[BUFFER_SIZE
];
950 TCG_CREATE_STRUCT CreateStruct
;
952 TCG_PARSE_STRUCT ParseStruct
;
954 NULL_CHECK(AdminSpSession
);
955 NULL_CHECK(MethodStatus
);
958 // Call Activate method on Locking SP
960 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
961 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
962 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
963 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
964 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_LOCKING_SP
, OPAL_ADMIN_SP_ACTIVATE_METHOD
));
965 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
966 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
967 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
968 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
969 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
970 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
973 // Send Activate method call
975 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
976 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
978 return TcgResultSuccess
;
983 The function sets the PIN column of the specified cpinRowUid (authority) with the newPin Value.
985 @param[in/out] Session OPAL_SESSION to set password
986 @param[in] CpinRowUid UID of row (authority) to update PIN column
987 @param[in] NewPin New Pin to set for cpinRowUid specified
988 @param[in] NewPinLength Length in bytes of newPin
989 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
995 OPAL_SESSION
*Session
,
1002 UINT8 Buf
[BUFFER_SIZE
];
1003 TCG_CREATE_STRUCT CreateStruct
;
1004 TCG_PARSE_STRUCT ParseStruct
;
1007 NULL_CHECK(Session
);
1009 NULL_CHECK(MethodStatus
);
1011 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1012 ERROR_CHECK(TcgCreateSetCPin(
1015 Session
->OpalBaseComId
,
1016 Session
->ComIdExtension
,
1017 Session
->TperSessionId
,
1018 Session
->HostSessionId
,
1024 ERROR_CHECK(OpalPerformMethod(Session
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1025 // exit with success on method failure - user must inspect MethodStatus
1026 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1028 return TcgResultSuccess
;
1033 The function sets the Enabled column to TRUE for the authorityUid provided and updates the PIN column for the cpinRowUid provided
1034 using the newPin provided. AuthorityUid and cpinRowUid should describe the same authority.
1036 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to update
1037 @param[in] CpinRowUid Row UID of C_PIN table of Locking SP to update PIN
1038 @param[in] AuthorityUid UID of Locking SP authority to update Pin column with
1039 @param[in] NewPin New Password used to set Pin column
1040 @param[in] NewPinLength Length in bytes of new password
1041 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1046 OpalSetLockingSpAuthorityEnabledAndPin(
1047 OPAL_SESSION
*LockingSpSession
,
1049 TCG_UID AuthorityUid
,
1051 UINT32 NewPinLength
,
1055 UINT8 Buf
[BUFFER_SIZE
];
1056 TCG_CREATE_STRUCT CreateStruct
;
1057 TCG_PARSE_STRUCT ParseStruct
;
1062 NULL_CHECK(LockingSpSession
);
1064 NULL_CHECK(MethodStatus
);
1066 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1067 ERROR_CHECK(TcgSetAuthorityEnabled(
1070 LockingSpSession
->OpalBaseComId
,
1071 LockingSpSession
->ComIdExtension
,
1072 LockingSpSession
->TperSessionId
,
1073 LockingSpSession
->HostSessionId
,
1077 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1079 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1080 DEBUG ((DEBUG_INFO
, "Send Set Authority error\n"));
1081 return TcgResultFailure
;
1084 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1086 ERROR_CHECK(TcgCreateSetCPin(
1089 LockingSpSession
->OpalBaseComId
,
1090 LockingSpSession
->ComIdExtension
,
1091 LockingSpSession
->TperSessionId
,
1092 LockingSpSession
->HostSessionId
,
1097 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1100 // allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked
1102 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1103 ERROR_CHECK(TcgCreateSetAce(
1106 LockingSpSession
->OpalBaseComId
,
1107 LockingSpSession
->ComIdExtension
,
1108 LockingSpSession
->TperSessionId
,
1109 LockingSpSession
->HostSessionId
,
1110 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_RDLOCKED
,
1111 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1112 TCG_ACE_EXPRESSION_OR
,
1113 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1116 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1118 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1119 DEBUG ((DEBUG_INFO
, "Update ACE for RDLOCKED failed\n"));
1120 return TcgResultFailure
;
1123 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1124 ERROR_CHECK(TcgCreateSetAce(
1127 LockingSpSession
->OpalBaseComId
,
1128 LockingSpSession
->ComIdExtension
,
1129 LockingSpSession
->TperSessionId
,
1130 LockingSpSession
->HostSessionId
,
1131 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_WRLOCKED
,
1132 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1133 TCG_ACE_EXPRESSION_OR
,
1134 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1137 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1139 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1140 DEBUG ((DEBUG_INFO
, "Update ACE for WRLOCKED failed\n"));
1141 return TcgResultFailure
;
1144 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1145 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession
, &CreateStruct
, &Size
));
1146 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1149 // For Pyrite type SSC, it not supports Active Key.
1150 // So here add check logic before enable it.
1152 Ret
= OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct
, &ActiveKey
);
1153 if (Ret
== TcgResultSuccess
) {
1154 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1155 ERROR_CHECK(TcgCreateSetAce(
1158 LockingSpSession
->OpalBaseComId
,
1159 LockingSpSession
->ComIdExtension
,
1160 LockingSpSession
->TperSessionId
,
1161 LockingSpSession
->HostSessionId
,
1162 (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
,
1163 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1164 TCG_ACE_EXPRESSION_OR
,
1165 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1168 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1170 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1171 DEBUG ((DEBUG_INFO
, "Update ACE for GLOBALRANGE_GENKEY failed\n"));
1173 // Disable user1 if all permissions are not granted.
1175 return TcgResultFailure
;
1179 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1180 ERROR_CHECK(TcgCreateSetAce(
1183 LockingSpSession
->OpalBaseComId
,
1184 LockingSpSession
->ComIdExtension
,
1185 LockingSpSession
->TperSessionId
,
1186 LockingSpSession
->HostSessionId
,
1187 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL
,
1188 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1189 TCG_ACE_EXPRESSION_OR
,
1190 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1193 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1195 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1196 DEBUG ((DEBUG_INFO
, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL failed\n"));
1197 return TcgResultFailure
;
1200 return TcgResultSuccess
;
1205 The function sets the Enabled column to FALSE for the USER1 authority.
1207 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to disable User1
1208 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1214 OPAL_SESSION
*LockingSpSession
,
1218 UINT8 Buf
[BUFFER_SIZE
];
1219 TCG_CREATE_STRUCT CreateStruct
;
1220 TCG_PARSE_STRUCT ParseStruct
;
1223 NULL_CHECK(LockingSpSession
);
1224 NULL_CHECK(MethodStatus
);
1226 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1227 ERROR_CHECK(TcgSetAuthorityEnabled(
1230 LockingSpSession
->OpalBaseComId
,
1231 LockingSpSession
->ComIdExtension
,
1232 LockingSpSession
->TperSessionId
,
1233 LockingSpSession
->HostSessionId
,
1234 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1237 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1239 return TcgResultSuccess
;
1244 The function retrieves the active key of the global locking range
1245 and calls the GenKey method on the active key retrieved.
1247 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1248 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1253 OpalGlobalLockingRangeGenKey(
1254 OPAL_SESSION
*LockingSpSession
,
1258 UINT8 Buf
[BUFFER_SIZE
];
1259 TCG_CREATE_STRUCT CreateStruct
;
1260 TCG_PARSE_STRUCT ParseStruct
;
1264 NULL_CHECK(LockingSpSession
);
1265 NULL_CHECK(MethodStatus
);
1267 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1269 // retrieve the activekey in order to know which globalrange key to generate
1271 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession
, &CreateStruct
, &Size
));
1272 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1274 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1276 ERROR_CHECK(OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct
, &ActiveKey
));
1279 // call genkey on ActiveKey UID
1281 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1282 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1283 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1284 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1285 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, ActiveKey
, TCG_UID_METHOD_GEN_KEY
));
1286 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1287 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1288 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1289 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1290 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1291 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1293 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1295 return TcgResultSuccess
;
1300 The function updates the ReadLocked and WriteLocked columns of the Global Locking Range.
1301 This function is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns
1302 (not ReadLockEnabled and WriteLockEnabled columns).
1304 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1305 @param[in] ReadLocked Value to set ReadLocked column for Global Locking Range
1306 @param[in] WriteLocked Value to set WriteLocked column for Global Locking Range
1307 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1312 OpalUpdateGlobalLockingRange(
1313 OPAL_SESSION
*LockingSpSession
,
1315 BOOLEAN WriteLocked
,
1319 UINT8 Buf
[BUFFER_SIZE
];
1320 TCG_CREATE_STRUCT CreateStruct
;
1321 TCG_PARSE_STRUCT ParseStruct
;
1324 NULL_CHECK(LockingSpSession
);
1325 NULL_CHECK(MethodStatus
);
1327 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1330 // set global locking range values
1332 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1333 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1334 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1335 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
, TCG_UID_METHOD_SET
));
1336 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1337 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1338 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x01)); // "Values"
1339 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1341 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1342 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x07)); // "ReadLocked"
1343 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLocked
));
1344 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1346 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1347 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x08)); // "WriteLocked"
1348 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLocked
));
1349 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1351 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1352 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1353 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1354 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1355 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1356 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1357 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1359 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1360 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1362 return TcgResultSuccess
;
1367 The function updates the RangeStart, RangeLength, ReadLockedEnabled, WriteLockedEnabled, ReadLocked and WriteLocked columns
1368 of the specified Locking Range. This function requires admin authority of a locking SP session.
1370 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1371 @param[in] LockingRangeUid Locking range UID to set values
1372 @param[in] RangeStart Value to set RangeStart column for Locking Range
1373 @param[in] RangeLength Value to set RangeLength column for Locking Range
1374 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range
1375 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range
1376 @param[in] ReadLocked Value to set ReadLocked column for Locking Range
1377 @param[in] WriteLocked Value to set WriteLocked column for Locking Range
1378 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1383 OpalSetLockingRange(
1384 OPAL_SESSION
*LockingSpSession
,
1385 TCG_UID LockingRangeUid
,
1388 BOOLEAN ReadLockEnabled
,
1389 BOOLEAN WriteLockEnabled
,
1391 BOOLEAN WriteLocked
,
1395 UINT8 Buf
[BUFFER_SIZE
];
1396 TCG_CREATE_STRUCT CreateStruct
;
1397 TCG_PARSE_STRUCT ParseStruct
;
1400 NULL_CHECK(LockingSpSession
);
1401 NULL_CHECK(MethodStatus
);
1403 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1406 // set locking range values
1408 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1409 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1410 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1411 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, LockingRangeUid
, TCG_UID_METHOD_SET
));
1412 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1413 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1414 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x01)); // "Values"
1415 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1418 // range start and range Length only apply to non-global locking ranges
1420 if (LockingRangeUid
!= OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
) {
1421 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1422 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x03)); // "RangeStart"
1423 ERROR_CHECK(TcgAddUINT64(&CreateStruct
, RangeStart
));
1424 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1426 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1427 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x04)); // "RangeLength"
1428 ERROR_CHECK(TcgAddUINT64(&CreateStruct
, RangeLength
));
1429 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1432 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1433 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x05)); // "ReadLockEnabled"
1434 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLockEnabled
));
1435 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1437 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1438 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x06)); // "WriteLockEnabled"
1439 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLockEnabled
));
1440 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1442 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1443 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x07)); // "ReadLocked"
1444 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLocked
));
1445 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1447 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1448 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x08)); // "WriteLocked"
1449 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLocked
));
1450 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1452 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1453 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1454 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1455 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1456 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1457 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1458 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1460 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1461 // Exit with success on method failure - user must inspect MethodStatus
1462 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1464 return TcgResultSuccess
;
1469 The function populates the CreateStruct with a payload that will retrieve the global locking range active key.
1470 It is intended to be called with a session that is already started with a valid credential.
1471 The function does not send the payload.
1473 @param[in] Session OPAL_SESSION to populate command for, needs ComId
1474 @param[in/out] CreateStruct Structure to populate with encoded TCG command
1475 @param[in/out] Size Size in bytes of the command created.
1480 OpalCreateRetrieveGlobalLockingRangeActiveKey(
1481 const OPAL_SESSION
*Session
,
1482 TCG_CREATE_STRUCT
*CreateStruct
,
1486 NULL_CHECK(Session
);
1487 NULL_CHECK(CreateStruct
);
1490 // Retrieve the activekey in order to know which globalrange key to generate
1491 ERROR_CHECK(TcgStartComPacket(CreateStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
1492 ERROR_CHECK(TcgStartPacket(CreateStruct
, Session
->TperSessionId
, Session
->HostSessionId
, 0x0, 0x0, 0x0));
1493 ERROR_CHECK(TcgStartSubPacket(CreateStruct
, 0x0));
1494 ERROR_CHECK(TcgStartMethodCall(CreateStruct
, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
, TCG_UID_METHOD_GET
));
1495 ERROR_CHECK(TcgStartParameters(CreateStruct
));
1496 ERROR_CHECK(TcgAddStartList(CreateStruct
));
1497 ERROR_CHECK(TcgAddStartName(CreateStruct
));
1498 ERROR_CHECK(TcgAddUINT8(CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
1499 ERROR_CHECK(TcgAddUINT8(CreateStruct
, 0x0A)); // ActiveKey
1500 ERROR_CHECK(TcgAddEndName(CreateStruct
));
1501 ERROR_CHECK(TcgAddStartName(CreateStruct
));
1502 ERROR_CHECK(TcgAddUINT8(CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
1503 ERROR_CHECK(TcgAddUINT8(CreateStruct
, 0x0A));
1504 ERROR_CHECK(TcgAddEndName(CreateStruct
));
1505 ERROR_CHECK(TcgAddEndList(CreateStruct
));
1506 ERROR_CHECK(TcgEndParameters(CreateStruct
));
1507 ERROR_CHECK(TcgEndMethodCall(CreateStruct
));
1508 ERROR_CHECK(TcgEndSubPacket(CreateStruct
));
1509 ERROR_CHECK(TcgEndPacket(CreateStruct
));
1510 ERROR_CHECK(TcgEndComPacket(CreateStruct
, Size
));
1512 return TcgResultSuccess
;
1517 The function acquires the activeKey specified for the Global Locking Range from the ParseStruct.
1519 @param[in] ParseStruct Structure that contains the device's response with the activekey
1520 @param[in/out] ActiveKey The UID of the active key retrieved
1525 OpalParseRetrieveGlobalLockingRangeActiveKey(
1526 TCG_PARSE_STRUCT
*ParseStruct
,
1532 NULL_CHECK(ParseStruct
);
1533 NULL_CHECK(ActiveKey
);
1536 ERROR_CHECK(TcgGetNextStartList(ParseStruct
));
1537 ERROR_CHECK(TcgGetNextStartList(ParseStruct
));
1538 ERROR_CHECK(TcgGetNextStartName(ParseStruct
));
1539 ERROR_CHECK(TcgGetNextUINT32(ParseStruct
, &ColumnName
));
1540 ERROR_CHECK(TcgGetNextTcgUid(ParseStruct
, ActiveKey
));
1541 ERROR_CHECK(TcgGetNextEndName(ParseStruct
));
1542 ERROR_CHECK(TcgGetNextEndList(ParseStruct
));
1543 ERROR_CHECK(TcgGetNextEndList(ParseStruct
));
1544 ERROR_CHECK(TcgGetNextEndOfData(ParseStruct
));
1546 if (ColumnName
!= 0x0A) {
1547 DEBUG ((DEBUG_INFO
, "Unexpected column name %u (exp 0x0A)\n", ColumnName
));
1548 return TcgResultFailure
;
1551 if (*ActiveKey
!= OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY
&& *ActiveKey
!= OPAL_LOCKING_SP_K_AES_128_GLOBALRANGE_KEY
) {
1552 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
));
1553 return TcgResultFailure
;
1556 return TcgResultSuccess
;
1561 The function retrieves the TryLimit column for the specified rowUid (authority).
1563 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve try limit
1564 @param[in] RowUid Row UID of the Locking SP C_PIN table to retrieve TryLimit column
1565 @param[in/out] TryLimit Value from TryLimit column
1571 OPAL_SESSION
*LockingSpSession
,
1576 TCG_CREATE_STRUCT CreateStruct
;
1577 TCG_PARSE_STRUCT ParseStruct
;
1580 UINT8 Buf
[BUFFER_SIZE
];
1583 NULL_CHECK(LockingSpSession
);
1584 NULL_CHECK(TryLimit
);
1586 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1587 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1588 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1589 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1590 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, RowUid
, TCG_UID_METHOD_GET
));
1591 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1592 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1593 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1594 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
1595 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1596 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1597 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1598 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
1599 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1600 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1601 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1602 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1603 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1604 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1605 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1606 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1608 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, &MethodStatus
, 0));
1609 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
1611 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
1612 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
1613 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
1614 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
1615 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, TryLimit
));
1616 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
1617 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
1618 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
1619 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
1621 if (Col
!= OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
) {
1622 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1623 return TcgResultFailure
;
1626 return TcgResultSuccess
;
1631 Get the support attribute info.
1633 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1634 @param[out] SupportedAttributes Return the support attribute info.
1635 @param[out] OpalBaseComId Return the base com id info.
1640 OpalGetSupportedAttributesInfo(
1641 IN OPAL_SESSION
*Session
,
1642 OUT OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1643 OUT UINT16
*OpalBaseComId
1646 UINT8 Buffer
[BUFFER_SIZE
];
1647 TCG_SUPPORTED_SECURITY_PROTOCOLS
*SupportedProtocols
;
1648 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1649 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1650 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat2
;
1654 NULL_CHECK(Session
);
1655 NULL_CHECK(SupportedAttributes
);
1656 NULL_CHECK(OpalBaseComId
);
1658 ZeroMem(Buffer
, BUFFER_SIZE
);
1659 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1662 // Retrieve supported protocols verify security protocol 1 is supported
1664 SupportedProtocols
= (TCG_SUPPORTED_SECURITY_PROTOCOLS
*) Buffer
;
1667 // Get list of supported protocols
1669 if (OpalRetrieveSupportedProtocolList (Session
, sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
), SupportedProtocols
) == TcgResultFailure
) {
1670 DEBUG ((DEBUG_INFO
, "OpalRetrieveSupportedProtocolList failed\n"));
1671 return TcgResultFailure
;
1674 SupportedAttributes
->Sp1
= TcgIsProtocolSupported (SupportedProtocols
, TCG_OPAL_SECURITY_PROTOCOL_1
);
1675 SupportedAttributes
->Sp2
= TcgIsProtocolSupported (SupportedProtocols
, TCG_OPAL_SECURITY_PROTOCOL_2
);
1676 SupportedAttributes
->SpIeee1667
= TcgIsProtocolSupported (SupportedProtocols
, TCG_SECURITY_PROTOCOL_IEEE_1667
);
1678 DEBUG ((DEBUG_INFO
, "Supported Protocols: Sp1 %d Sp2: %d SpIeee1667 %d \n",
1679 SupportedAttributes
->Sp1
,
1680 SupportedAttributes
->Sp2
,
1681 SupportedAttributes
->SpIeee1667
1685 // Perform level 0 discovery and assign desired feature info to Opal Disk structure
1687 ZeroMem (Buffer
, BUFFER_SIZE
);
1688 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1689 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1690 return TcgResultFailure
;
1694 // Check for required feature descriptors
1696 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1699 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_V2_0_0
, &Size
);
1700 SupportedAttributes
->OpalSsc2
= (Feat
!= NULL
);
1702 *OpalBaseComId
= TCG_RESERVED_COMID
;
1705 // Check Opal SCC V2 has valid settings for SID C_PIN on revert
1707 if (SupportedAttributes
->OpalSsc2
&& Size
>= sizeof (OPAL_SSCV2_FEATURE_DESCRIPTOR
)) {
1709 // Want opposite polarity b/c Value is greater than a bit, but we only care about non-zero vs zero
1711 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1712 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1713 DEBUG ((DEBUG_INFO
, "Opal SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1714 SupportedAttributes
->InitCpinIndicator
,
1715 SupportedAttributes
->CpinUponRevert
1717 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscV2
.BaseComdIdBE
);
1721 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_LITE
, &Size
);
1722 SupportedAttributes
->OpalSscLite
= (Feat
!= NULL
);
1724 if (Feat
!= NULL
&& Size
>= sizeof (OPAL_SSCLITE_FEATURE_DESCRIPTOR
)) {
1725 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1727 // Pin values used always match up with ComId used
1729 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscLite
.BaseComdIdBE
);
1730 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1731 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1732 DEBUG ((DEBUG_INFO
, "Opal SSC Lite InitCpinIndicator %d CpinUponRevert %d \n",
1733 SupportedAttributes
->InitCpinIndicator
,
1734 SupportedAttributes
->CpinUponRevert
1740 // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 feature data.
1741 // so here try to get data from pyrite 2.0 feature data first.
1744 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_PYRITE_SSC
, &Size
);
1746 Feat2
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_PYRITE_SSC_V2_0_0
, &Size2
);
1747 if (Feat2
!= NULL
&& Size2
>= sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTOR
)) {
1748 SupportedAttributes
->PyriteSscV2
= TRUE
;
1749 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1750 *OpalBaseComId
= SwapBytes16 (Feat2
->PyriteSscV2
.BaseComdIdBE
);
1751 SupportedAttributes
->InitCpinIndicator
= (Feat2
->PyriteSscV2
.InitialCPINSIDPIN
== 0);
1752 SupportedAttributes
->CpinUponRevert
= (Feat2
->PyriteSscV2
.CPINSIDPINRevertBehavior
== 0);
1753 DEBUG ((DEBUG_INFO
, "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1754 SupportedAttributes
->InitCpinIndicator
,
1755 SupportedAttributes
->CpinUponRevert
1759 SupportedAttributes
->PyriteSsc
= (Feat
!= NULL
);
1760 if (Feat
!= NULL
&& Size
>= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR
)) {
1761 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1762 *OpalBaseComId
= SwapBytes16 (Feat
->PyriteSsc
.BaseComdIdBE
);
1763 SupportedAttributes
->InitCpinIndicator
= (Feat
->PyriteSsc
.InitialCPINSIDPIN
== 0);
1764 SupportedAttributes
->CpinUponRevert
= (Feat
->PyriteSsc
.CPINSIDPINRevertBehavior
== 0);
1765 DEBUG ((DEBUG_INFO
, "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",
1766 SupportedAttributes
->InitCpinIndicator
,
1767 SupportedAttributes
->CpinUponRevert
1774 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_V1_0_0
, &Size
);
1775 SupportedAttributes
->OpalSsc1
= (Feat
!= NULL
);
1776 if (Feat
!= NULL
&& Size
>= sizeof (OPAL_SSCV1_FEATURE_DESCRIPTOR
)) {
1777 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1778 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscV1
.BaseComdIdBE
);
1783 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_LOCKING
, &Size
);
1784 if (Feat
!= NULL
&& Size
>= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
)) {
1785 SupportedAttributes
->MediaEncryption
= Feat
->Locking
.MediaEncryption
;
1786 DEBUG ((DEBUG_INFO
, "SupportedAttributes->MediaEncryption 0x%X \n", SupportedAttributes
->MediaEncryption
));
1790 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_BLOCK_SID
, &Size
);
1791 if (Feat
!= NULL
&& Size
>= sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR
)) {
1792 SupportedAttributes
->BlockSid
= TRUE
;
1793 DEBUG ((DEBUG_INFO
, "BlockSid Supported!!! Current Status is 0x%X \n", Feat
->BlockSid
.SIDBlockedState
));
1795 DEBUG ((DEBUG_INFO
, "BlockSid Unsupported!!!"));
1799 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_DATA_REMOVAL
, &Size
);
1800 if (Feat
!= NULL
&& Size
>= sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR
)) {
1801 SupportedAttributes
->DataRemoval
= TRUE
;
1802 DEBUG ((DEBUG_INFO
, "DataRemoval Feature Supported!\n"));
1803 DEBUG ((DEBUG_INFO
, "Operation Processing = 0x%x\n", Feat
->DataRemoval
.OperationProcessing
));
1804 DEBUG ((DEBUG_INFO
, "RemovalMechanism = 0x%x\n", Feat
->DataRemoval
.RemovalMechanism
));
1805 DEBUG ((DEBUG_INFO
, "BIT0 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit0
, SwapBytes16 (Feat
->DataRemoval
.TimeBit0
)));
1806 DEBUG ((DEBUG_INFO
, "BIT1 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit1
, SwapBytes16 (Feat
->DataRemoval
.TimeBit1
)));
1807 DEBUG ((DEBUG_INFO
, "BIT2 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit2
, SwapBytes16 (Feat
->DataRemoval
.TimeBit2
)));
1808 DEBUG ((DEBUG_INFO
, "BIT3 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit3
, SwapBytes16 (Feat
->DataRemoval
.TimeBit3
)));
1809 DEBUG ((DEBUG_INFO
, "BIT4 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit4
, SwapBytes16 (Feat
->DataRemoval
.TimeBit4
)));
1812 DEBUG ((DEBUG_INFO
, "Base COMID 0x%04X \n", *OpalBaseComId
));
1814 return TcgResultSuccess
;
1819 Get the support attribute info.
1821 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1822 @param[in/out] LockingFeature Return the Locking info.
1828 OPAL_SESSION
*Session
,
1829 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1832 UINT8 Buffer
[BUFFER_SIZE
];
1833 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1834 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1837 NULL_CHECK(Session
);
1838 NULL_CHECK(LockingFeature
);
1840 ZeroMem(Buffer
, BUFFER_SIZE
);
1841 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1843 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1844 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1845 return TcgResultFailure
;
1847 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1850 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_LOCKING
, &Size
);
1851 if (Feat
!= NULL
&& Size
>= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
)) {
1852 CopyMem (LockingFeature
, &Feat
->Locking
, sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
));
1855 return TcgResultSuccess
;
1860 Get the descriptor for the specific feature code.
1862 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1863 @param[in] FeatureCode The feature code user request.
1864 @param[in, out] DataSize The data size.
1865 @param[out] Data The data buffer used to save the feature descriptor.
1870 OpalGetFeatureDescriptor (
1871 IN OPAL_SESSION
*Session
,
1872 IN UINT16 FeatureCode
,
1873 IN OUT UINTN
*DataSize
,
1877 UINT8 Buffer
[BUFFER_SIZE
];
1878 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1879 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1882 NULL_CHECK(Session
);
1883 NULL_CHECK(DataSize
);
1886 ZeroMem(Buffer
, BUFFER_SIZE
);
1887 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1889 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1890 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1891 return TcgResultFailure
;
1893 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1896 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, FeatureCode
, &Size
);
1898 if (Size
> *DataSize
) {
1900 return TcgResultFailureBufferTooSmall
;
1904 CopyMem (Data
, Feat
, Size
);
1907 return TcgResultSuccess
;
1912 The function determines whether or not all of the requirements for the Opal Feature (not full specification)
1913 are met by the specified device.
1915 @param[in] SupportedAttributes Opal device attribute.
1920 OpalFeatureSupported(
1921 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
1924 NULL_CHECK(SupportedAttributes
);
1926 if (SupportedAttributes
->Sp1
== 0) {
1930 if (SupportedAttributes
->OpalSscLite
== 0 &&
1931 SupportedAttributes
->OpalSsc1
== 0 &&
1932 SupportedAttributes
->OpalSsc2
== 0 &&
1933 SupportedAttributes
->PyriteSsc
== 0 &&
1934 SupportedAttributes
->PyriteSscV2
== 0
1944 The function returns whether or not the device is Opal Enabled.
1945 TRUE means that the device is partially or fully locked.
1946 This will perform a Level 0 Discovery and parse the locking feature descriptor
1948 @param[in] SupportedAttributes Opal device attribute.
1949 @param[in] LockingFeature Opal device locking status.
1956 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1957 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1960 NULL_CHECK(SupportedAttributes
);
1961 NULL_CHECK(LockingFeature
);
1963 if (!OpalFeatureSupported (SupportedAttributes
)) {
1967 if (LockingFeature
->LockingSupported
&& LockingFeature
->LockingEnabled
) {
1976 The function returns whether or not the device is Opal Locked.
1977 TRUE means that the device is partially or fully locked.
1978 This will perform a Level 0 Discovery and parse the locking feature descriptor
1980 @param[in] SupportedAttributes Opal device attribute.
1981 @param[in] LockingFeature Opal device locking status.
1986 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1987 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1990 NULL_CHECK(SupportedAttributes
);
1991 NULL_CHECK(LockingFeature
);
1993 if (!OpalFeatureEnabled (SupportedAttributes
, LockingFeature
)) {
1997 return LockingFeature
->Locked
;