2 Public API for Opal Core library.
4 Copyright (c) 2016 - 2018, 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;
138 while ((Tries
--) > 0) {
139 ZeroMem( Buffer
, BufferSize
);
142 Status
= Sscp
->ReceiveData(
145 TRUSTED_COMMAND_TIMEOUT_NS
,
147 SwapBytes16(SpSpecific
),
152 if (EFI_ERROR (Status
)) {
153 return TcgResultFailure
;
156 if (SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_1
&& SecurityProtocol
!= TCG_OPAL_SECURITY_PROTOCOL_2
) {
157 return TcgResultSuccess
;
160 if (SpSpecific
== TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
) {
161 return TcgResultSuccess
;
164 ComPacket
= (TCG_COM_PACKET
*) Buffer
;
165 Length
= SwapBytes32(ComPacket
->LengthBE
);
166 OutstandingData
= SwapBytes32( ComPacket
->OutstandingDataBE
);
168 if (Length
!= 0 && OutstandingData
== 0) {
169 return TcgResultSuccess
;
175 MicroSecondDelay (2000);
178 return TcgResultFailure
;
182 The function performs send, recv, check comIDs, check method status action.
184 @param[in] Session OPAL_SESSION related to this method..
185 @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512
186 @param[in] Buffer Address of Data to transfer
187 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.
188 @param[in] ParseStruct Structure used to parse received TCG response.
189 @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
190 @param[in] EstimateTimeCost Estimate the time need to for the method.
195 OPAL_SESSION
*Session
,
199 TCG_PARSE_STRUCT
*ParseStruct
,
201 UINT32 EstimateTimeCost
205 NULL_CHECK(MethodStatus
);
207 ERROR_CHECK(OpalTrustedSend(
210 TCG_OPAL_SECURITY_PROTOCOL_1
,
211 Session
->OpalBaseComId
,
217 ERROR_CHECK(OpalTrustedRecv(
220 TCG_OPAL_SECURITY_PROTOCOL_1
,
221 Session
->OpalBaseComId
,
227 ERROR_CHECK(TcgInitTcgParseStruct(ParseStruct
, Buffer
, BufferSize
));
228 ERROR_CHECK(TcgCheckComIds(ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
229 ERROR_CHECK(TcgGetMethodStatus(ParseStruct
, MethodStatus
));
231 return TcgResultSuccess
;
235 Trig the block sid action.
237 @param[in] Session OPAL_SESSION related to this method..
238 @param[in] HardwareReset Whether need to do hardware reset.
244 OPAL_SESSION
*Session
,
245 BOOLEAN HardwareReset
248 UINT8 Buffer
[BUFFER_SIZE
];
249 TCG_BLOCK_SID_CLEAR_EVENTS
*ClearEvents
;
254 // Set Hardware Reset bit
256 ClearEvents
= (TCG_BLOCK_SID_CLEAR_EVENTS
*) &Buffer
[0];
258 ClearEvents
->Reserved
= 0;
259 ClearEvents
->HardwareReset
= HardwareReset
;
261 return(OpalTrustedSend(
264 TCG_OPAL_SECURITY_PROTOCOL_2
,
265 TCG_BLOCKSID_COMID
, // hardcode ComID 0x0005
274 Reverts device using Admin SP Revert method.
276 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
282 OPAL_SESSION
*AdminSpSession
286 // Now that base comid is known, start Session
287 // we'll attempt to start Session as PSID authority
288 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
290 TCG_CREATE_STRUCT CreateStruct
;
291 TCG_PARSE_STRUCT ParseStruct
;
293 UINT8 Buffer
[BUFFER_SIZE
];
296 NULL_CHECK(AdminSpSession
);
299 // Send Revert action on Admin SP
301 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
302 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
303 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
304 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
305 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP
, OPAL_ADMIN_SP_REVERT_METHOD
));
306 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
307 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
308 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
309 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
310 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
311 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
314 // Send Revert Method Call
316 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
317 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
319 return TcgResultSuccess
;
324 Reverts device using Admin SP Revert method.
326 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
327 @param[in] EstimateTimeCost Estimate the time needed.
331 OpalPyrite2PsidRevert(
332 OPAL_SESSION
*AdminSpSession
,
333 UINT32 EstimateTimeCost
337 // Now that base comid is known, start Session
338 // we'll attempt to start Session as PSID authority
339 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
341 TCG_CREATE_STRUCT CreateStruct
;
342 TCG_PARSE_STRUCT ParseStruct
;
344 UINT8 Buffer
[BUFFER_SIZE
];
348 NULL_CHECK(AdminSpSession
);
351 // Send Revert action on Admin SP
353 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
354 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
355 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
356 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
357 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP
, OPAL_ADMIN_SP_REVERT_METHOD
));
358 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
359 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
360 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
361 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
362 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
363 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
366 // Send Revert Method Call
368 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, EstimateTimeCost
));
369 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
371 return TcgResultSuccess
;
376 The function fills in the provided Buffer with the level 0 discovery Header
377 of the device specified.
379 @param[in] Session OPAL_SESSION data.
380 @param[in] BufferSize Size of Buffer provided (in bytes)
381 @param[in] BuffAddress Buffer address to fill with Level 0 Discovery response
386 OpalRetrieveLevel0DiscoveryHeader(
387 OPAL_SESSION
*Session
,
392 return (OpalTrustedRecv(
395 TCG_OPAL_SECURITY_PROTOCOL_1
, // SP
396 TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY
, // SP_Specific
405 The function fills in the provided Buffer with the supported protocol list
406 of the device specified.
408 @param[in] Session OPAL_SESSION data.
409 @param[in] BufferSize Size of Buffer provided (in bytes)
410 @param[in] BuffAddress Buffer address to fill with security protocol list
415 OpalRetrieveSupportedProtocolList(
416 OPAL_SESSION
*Session
,
421 return (OpalTrustedRecv(
424 TCG_SECURITY_PROTOCOL_INFO
, // SP
425 TCG_SP_SPECIFIC_PROTOCOL_LIST
, // SP_Specific
433 Starts a session with a security provider (SP).
435 If a session is started successfully, the caller must end the session with OpalEndSession when finished
436 performing Opal actions.
438 @param[in/out] Session OPAL_SESSION to initialize.
439 @param[in] SpId Security provider ID to start the session with.
440 @param[in] Write Whether the session should be read-only (FALSE) or read/write (TRUE).
441 @param[in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
442 @param[in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge will be sent.
443 @param[in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority will be sent.
444 @param[in/out] MethodStatus Status of the StartSession method; only valid if TcgResultSuccess is returned.
446 @return TcgResultSuccess indicates that the function completed without any internal errors.
447 The caller must inspect the MethodStatus field to determine whether the method completed successfully.
453 OPAL_SESSION
*Session
,
456 UINT32 HostChallengeLength
,
457 const VOID
*HostChallenge
,
458 TCG_UID HostSigningAuthority
,
462 TCG_CREATE_STRUCT CreateStruct
;
463 TCG_PARSE_STRUCT ParseStruct
;
465 UINT8 Buf
[BUFFER_SIZE
];
466 UINT16 ComIdExtension
;
467 UINT32 HostSessionId
;
473 NULL_CHECK(MethodStatus
);
475 Session
->ComIdExtension
= ComIdExtension
;
476 Session
->HostSessionId
= HostSessionId
;
478 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
479 ERROR_CHECK(TcgCreateStartSession(
482 Session
->OpalBaseComId
,
491 ERROR_CHECK(OpalPerformMethod(Session
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
492 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
493 return TcgResultSuccess
; // return early if method failed - user must check MethodStatus
496 if (TcgParseSyncSession(&ParseStruct
, Session
->OpalBaseComId
, ComIdExtension
, HostSessionId
, &Session
->TperSessionId
) != TcgResultSuccess
) {
497 OpalEndSession(Session
);
498 return TcgResultFailure
;
501 return TcgResultSuccess
;
505 Close a session opened with OpalStartSession.
507 @param[in/out] Session OPAL_SESSION to end.
513 OPAL_SESSION
*Session
516 UINT8 Buffer
[BUFFER_SIZE
];
517 TCG_CREATE_STRUCT CreateStruct
;
519 TCG_PARSE_STRUCT ParseStruct
;
522 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, sizeof(Buffer
)));
523 ERROR_CHECK(TcgCreateEndSession(
526 Session
->OpalBaseComId
,
527 Session
->ComIdExtension
,
528 Session
->HostSessionId
,
529 Session
->TperSessionId
532 ERROR_CHECK(OpalTrustedSend(
535 TCG_OPAL_SECURITY_PROTOCOL_1
,
536 Session
->OpalBaseComId
,
542 ERROR_CHECK(OpalTrustedRecv(
545 TCG_OPAL_SECURITY_PROTOCOL_1
,
546 Session
->OpalBaseComId
,
552 ERROR_CHECK(TcgInitTcgParseStruct(&ParseStruct
, Buffer
, sizeof(Buffer
)));
553 ERROR_CHECK(TcgCheckComIds(&ParseStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
555 ERROR_CHECK(TcgGetNextEndOfSession(&ParseStruct
));
556 return TcgResultSuccess
;
561 The function retrieves the MSID from the device specified
563 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.
564 @param[in] MsidBufferSize Allocated Buffer Size (in bytes) for MSID allocated by caller
565 @param[in] Msid Variable Length byte sequence representing MSID of device
566 @param[in] MsidLength Actual Length of MSID retrieved from device
572 OPAL_SESSION
*AdminSpSession
,
573 UINT32 MsidBufferSize
,
579 // now that base comid is known, start Session
580 // we'll attempt to start Session as PSID authority
581 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?
583 TCG_CREATE_STRUCT CreateStruct
;
584 TCG_PARSE_STRUCT ParseStruct
;
588 const VOID
*RecvMsid
;
589 UINT8 Buffer
[BUFFER_SIZE
];
591 NULL_CHECK(AdminSpSession
);
593 NULL_CHECK(MsidLength
);
595 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
596 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
597 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
598 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
599 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP_C_PIN_MSID
, TCG_UID_METHOD_GET
));
600 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
601 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
602 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
603 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
604 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_PIN_COL
));
605 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
606 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
607 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
608 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_PIN_COL
));
609 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
610 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
611 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
612 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
613 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
614 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
615 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
618 // Send MSID Method Call
620 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
621 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
623 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
624 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
625 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
626 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
627 ERROR_CHECK(TcgGetNextByteSequence(&ParseStruct
, &RecvMsid
, MsidLength
));
628 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
629 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
630 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
631 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
633 if (Col
!= OPAL_ADMIN_SP_PIN_COL
) {
634 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_ADMIN_SP_PIN_COL
));
635 return TcgResultFailure
;
638 if (RecvMsid
== NULL
) {
639 return TcgResultFailure
;
642 if (MsidBufferSize
< *MsidLength
) {
643 DEBUG ((DEBUG_INFO
, "Buffer too small MsidBufferSize: %d MsidLength: %d\n", MsidBufferSize
, *MsidLength
));
644 return TcgResultFailureBufferTooSmall
;
648 // copy msid into Buffer
650 CopyMem(Msid
, RecvMsid
, *MsidLength
);
651 return TcgResultSuccess
;
656 The function retrieves the MSID from the device specified
658 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY
659 @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism that the device will use for Revert/RevertSP calls.
663 OpalPyrite2GetActiveDataRemovalMechanism (
664 IN OPAL_SESSION
*AdminSpSession
,
665 OUT UINT8
*ActiveDataRemovalMechanism
668 TCG_CREATE_STRUCT CreateStruct
;
669 TCG_PARSE_STRUCT ParseStruct
;
673 UINT8 RecvActiveDataRemovalMechanism
;
674 UINT8 Buffer
[BUFFER_SIZE
];
676 NULL_CHECK(AdminSpSession
);
677 NULL_CHECK(ActiveDataRemovalMechanism
);
679 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buffer
, BUFFER_SIZE
));
680 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
681 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
682 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
683 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_ADMIN_SP_DATA_REMOVAL_MECHANISM
, TCG_UID_METHOD_GET
));
684 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
685 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
686 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
687 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
688 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
689 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
690 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
691 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
692 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
693 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
694 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
695 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
696 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
697 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
698 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
699 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
702 // Send Get Active Data Removal Mechanism Method Call
704 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buffer
, BUFFER_SIZE
, &ParseStruct
, &MethodStatus
, 0));
705 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
707 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
708 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
709 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
710 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
711 ERROR_CHECK(TcgGetNextUINT8(&ParseStruct
, &RecvActiveDataRemovalMechanism
));
712 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
713 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
714 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
715 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
717 if (Col
!= OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
) {
718 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL
));
719 return TcgResultFailure
;
722 if (RecvActiveDataRemovalMechanism
>= ResearvedMechanism
) {
723 return TcgResultFailure
;
727 // Copy active data removal mechanism into Buffer
729 CopyMem(ActiveDataRemovalMechanism
, &RecvActiveDataRemovalMechanism
, sizeof(RecvActiveDataRemovalMechanism
));
730 return TcgResultSuccess
;
735 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
736 to keep the user Data is set to True, otherwise the optional parameter is not provided.
738 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
739 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
740 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
746 OPAL_SESSION
*LockingSpSession
,
747 BOOLEAN KeepUserData
,
751 UINT8 Buf
[BUFFER_SIZE
];
752 TCG_CREATE_STRUCT CreateStruct
;
754 TCG_PARSE_STRUCT ParseStruct
;
757 NULL_CHECK(LockingSpSession
);
758 NULL_CHECK(MethodStatus
);
761 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
765 // set readlocked and writelocked to false
767 Ret
= OpalUpdateGlobalLockingRange(
773 if (Ret
!= TcgResultSuccess
|| *MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
781 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
782 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
783 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
784 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
785 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, TCG_UID_THIS_SP
, OPAL_LOCKING_SP_REVERTSP_METHOD
));
786 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
790 // optional parameter to keep Data after revert
792 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
793 ERROR_CHECK(TcgAddUINT32(&CreateStruct
, 0x060000)); // weird Value but that's what spec says
794 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, KeepUserData
));
795 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
798 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
799 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
800 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
801 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
802 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
805 // Send RevertSP method call
807 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
810 // Session is immediately ended by device after successful revertsp, so no need to end Session
812 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
814 // Caller should take ownership again
816 return TcgResultSuccess
;
821 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
824 return TcgResultSuccess
;
830 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter
831 to keep the user Data is set to True, otherwise the optional parameter is not provided.
833 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP
834 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.
835 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
836 @param[in] EstimateTimeCost Estimate the time needed.
840 OpalPyrite2AdminRevert(
841 OPAL_SESSION
*LockingSpSession
,
842 BOOLEAN KeepUserData
,
844 UINT32 EstimateTimeCost
847 UINT8 Buf
[BUFFER_SIZE
];
848 TCG_CREATE_STRUCT CreateStruct
;
850 TCG_PARSE_STRUCT ParseStruct
;
853 NULL_CHECK(LockingSpSession
);
854 NULL_CHECK(MethodStatus
);
857 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data
861 // set readlocked and writelocked to false
863 Ret
= OpalUpdateGlobalLockingRange(
869 if (Ret
!= TcgResultSuccess
|| *MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
877 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
878 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
879 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
880 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
881 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, TCG_UID_THIS_SP
, OPAL_LOCKING_SP_REVERTSP_METHOD
));
882 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
886 // optional parameter to keep Data after revert
888 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
889 ERROR_CHECK(TcgAddUINT32(&CreateStruct
, 0x060000)); // weird Value but that's what spec says
890 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, KeepUserData
));
891 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
894 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
895 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
896 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
897 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
898 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
901 // Send RevertSP method call
903 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, EstimateTimeCost
));
906 // Session is immediately ended by device after successful revertsp, so no need to end Session
908 if (*MethodStatus
== TCG_METHOD_STATUS_CODE_SUCCESS
) {
910 // Caller should take ownership again
912 return TcgResultSuccess
;
917 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
920 return TcgResultSuccess
;
925 The function activates the Locking SP.
926 Once activated, per Opal spec, the ADMIN SP SID PIN is copied over to the ADMIN1 LOCKING SP PIN.
927 If the Locking SP is already enabled, then TcgResultSuccess is returned and no action occurs.
929 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY to activate Locking SP
930 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
935 OpalActivateLockingSp(
936 OPAL_SESSION
*AdminSpSession
,
940 UINT8 Buf
[BUFFER_SIZE
];
941 TCG_CREATE_STRUCT CreateStruct
;
943 TCG_PARSE_STRUCT ParseStruct
;
945 NULL_CHECK(AdminSpSession
);
946 NULL_CHECK(MethodStatus
);
949 // Call Activate method on Locking SP
951 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
952 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, AdminSpSession
->OpalBaseComId
, AdminSpSession
->ComIdExtension
));
953 ERROR_CHECK(TcgStartPacket(&CreateStruct
, AdminSpSession
->TperSessionId
, AdminSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
954 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
955 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_UID_LOCKING_SP
, OPAL_ADMIN_SP_ACTIVATE_METHOD
));
956 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
957 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
958 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
959 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
960 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
961 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
964 // Send Activate method call
966 ERROR_CHECK(OpalPerformMethod(AdminSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
967 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
); // exit with success on method failure - user must inspect MethodStatus
969 return TcgResultSuccess
;
974 The function sets the PIN column of the specified cpinRowUid (authority) with the newPin Value.
976 @param[in/out] Session OPAL_SESSION to set password
977 @param[in] CpinRowUid UID of row (authority) to update PIN column
978 @param[in] NewPin New Pin to set for cpinRowUid specified
979 @param[in] NewPinLength Length in bytes of newPin
980 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
986 OPAL_SESSION
*Session
,
993 UINT8 Buf
[BUFFER_SIZE
];
994 TCG_CREATE_STRUCT CreateStruct
;
995 TCG_PARSE_STRUCT ParseStruct
;
1000 NULL_CHECK(MethodStatus
);
1002 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1003 ERROR_CHECK(TcgCreateSetCPin(
1006 Session
->OpalBaseComId
,
1007 Session
->ComIdExtension
,
1008 Session
->TperSessionId
,
1009 Session
->HostSessionId
,
1015 ERROR_CHECK(OpalPerformMethod(Session
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1016 // exit with success on method failure - user must inspect MethodStatus
1017 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1019 return TcgResultSuccess
;
1024 The function sets the Enabled column to TRUE for the authorityUid provided and updates the PIN column for the cpinRowUid provided
1025 using the newPin provided. AuthorityUid and cpinRowUid should describe the same authority.
1027 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to update
1028 @param[in] CpinRowUid Row UID of C_PIN table of Locking SP to update PIN
1029 @param[in] AuthorityUid UID of Locking SP authority to update Pin column with
1030 @param[in] NewPin New Password used to set Pin column
1031 @param[in] NewPinLength Length in bytes of new password
1032 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1037 OpalSetLockingSpAuthorityEnabledAndPin(
1038 OPAL_SESSION
*LockingSpSession
,
1040 TCG_UID AuthorityUid
,
1042 UINT32 NewPinLength
,
1046 UINT8 Buf
[BUFFER_SIZE
];
1047 TCG_CREATE_STRUCT CreateStruct
;
1048 TCG_PARSE_STRUCT ParseStruct
;
1053 NULL_CHECK(LockingSpSession
);
1055 NULL_CHECK(MethodStatus
);
1057 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1058 ERROR_CHECK(TcgSetAuthorityEnabled(
1061 LockingSpSession
->OpalBaseComId
,
1062 LockingSpSession
->ComIdExtension
,
1063 LockingSpSession
->TperSessionId
,
1064 LockingSpSession
->HostSessionId
,
1068 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1070 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1071 DEBUG ((DEBUG_INFO
, "Send Set Authority error\n"));
1072 return TcgResultFailure
;
1075 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1077 ERROR_CHECK(TcgCreateSetCPin(
1080 LockingSpSession
->OpalBaseComId
,
1081 LockingSpSession
->ComIdExtension
,
1082 LockingSpSession
->TperSessionId
,
1083 LockingSpSession
->HostSessionId
,
1088 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1091 // allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked
1093 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1094 ERROR_CHECK(TcgCreateSetAce(
1097 LockingSpSession
->OpalBaseComId
,
1098 LockingSpSession
->ComIdExtension
,
1099 LockingSpSession
->TperSessionId
,
1100 LockingSpSession
->HostSessionId
,
1101 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_RDLOCKED
,
1102 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1103 TCG_ACE_EXPRESSION_OR
,
1104 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1107 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1109 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1110 DEBUG ((DEBUG_INFO
, "Update ACE for RDLOCKED failed\n"));
1111 return TcgResultFailure
;
1114 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1115 ERROR_CHECK(TcgCreateSetAce(
1118 LockingSpSession
->OpalBaseComId
,
1119 LockingSpSession
->ComIdExtension
,
1120 LockingSpSession
->TperSessionId
,
1121 LockingSpSession
->HostSessionId
,
1122 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_WRLOCKED
,
1123 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1124 TCG_ACE_EXPRESSION_OR
,
1125 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1128 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1130 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1131 DEBUG ((DEBUG_INFO
, "Update ACE for WRLOCKED failed\n"));
1132 return TcgResultFailure
;
1135 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1136 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession
, &CreateStruct
, &Size
));
1137 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1140 // For Pyrite type SSC, it not supports Active Key.
1141 // So here add check logic before enable it.
1143 Ret
= OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct
, &ActiveKey
);
1144 if (Ret
== TcgResultSuccess
) {
1145 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1146 ERROR_CHECK(TcgCreateSetAce(
1149 LockingSpSession
->OpalBaseComId
,
1150 LockingSpSession
->ComIdExtension
,
1151 LockingSpSession
->TperSessionId
,
1152 LockingSpSession
->HostSessionId
,
1153 (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
,
1154 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1155 TCG_ACE_EXPRESSION_OR
,
1156 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1159 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1161 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1162 DEBUG ((DEBUG_INFO
, "Update ACE for GLOBALRANGE_GENKEY failed\n"));
1164 // Disable user1 if all permissions are not granted.
1166 return TcgResultFailure
;
1170 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1171 ERROR_CHECK(TcgCreateSetAce(
1174 LockingSpSession
->OpalBaseComId
,
1175 LockingSpSession
->ComIdExtension
,
1176 LockingSpSession
->TperSessionId
,
1177 LockingSpSession
->HostSessionId
,
1178 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL
,
1179 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1180 TCG_ACE_EXPRESSION_OR
,
1181 OPAL_LOCKING_SP_ADMINS_AUTHORITY
1184 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1186 if (*MethodStatus
!= TCG_METHOD_STATUS_CODE_SUCCESS
) {
1187 DEBUG ((DEBUG_INFO
, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL failed\n"));
1188 return TcgResultFailure
;
1191 return TcgResultSuccess
;
1196 The function sets the Enabled column to FALSE for the USER1 authority.
1198 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to disable User1
1199 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1205 OPAL_SESSION
*LockingSpSession
,
1209 UINT8 Buf
[BUFFER_SIZE
];
1210 TCG_CREATE_STRUCT CreateStruct
;
1211 TCG_PARSE_STRUCT ParseStruct
;
1214 NULL_CHECK(LockingSpSession
);
1215 NULL_CHECK(MethodStatus
);
1217 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1218 ERROR_CHECK(TcgSetAuthorityEnabled(
1221 LockingSpSession
->OpalBaseComId
,
1222 LockingSpSession
->ComIdExtension
,
1223 LockingSpSession
->TperSessionId
,
1224 LockingSpSession
->HostSessionId
,
1225 OPAL_LOCKING_SP_USER1_AUTHORITY
,
1228 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1230 return TcgResultSuccess
;
1235 The function retrieves the active key of the global locking range
1236 and calls the GenKey method on the active key retrieved.
1238 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1239 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1244 OpalGlobalLockingRangeGenKey(
1245 OPAL_SESSION
*LockingSpSession
,
1249 UINT8 Buf
[BUFFER_SIZE
];
1250 TCG_CREATE_STRUCT CreateStruct
;
1251 TCG_PARSE_STRUCT ParseStruct
;
1255 NULL_CHECK(LockingSpSession
);
1256 NULL_CHECK(MethodStatus
);
1258 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1260 // retrieve the activekey in order to know which globalrange key to generate
1262 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession
, &CreateStruct
, &Size
));
1263 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1265 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1267 ERROR_CHECK(OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct
, &ActiveKey
));
1270 // call genkey on ActiveKey UID
1272 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1273 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1274 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1275 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1276 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, ActiveKey
, TCG_UID_METHOD_GEN_KEY
));
1277 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1278 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1279 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1280 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1281 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1282 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1284 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1286 return TcgResultSuccess
;
1291 The function updates the ReadLocked and WriteLocked columns of the Global Locking Range.
1292 This function is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns
1293 (not ReadLockEnabled and WriteLockEnabled columns).
1295 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1296 @param[in] ReadLocked Value to set ReadLocked column for Global Locking Range
1297 @param[in] WriteLocked Value to set WriteLocked column for Global Locking Range
1298 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1303 OpalUpdateGlobalLockingRange(
1304 OPAL_SESSION
*LockingSpSession
,
1306 BOOLEAN WriteLocked
,
1310 UINT8 Buf
[BUFFER_SIZE
];
1311 TCG_CREATE_STRUCT CreateStruct
;
1312 TCG_PARSE_STRUCT ParseStruct
;
1315 NULL_CHECK(LockingSpSession
);
1316 NULL_CHECK(MethodStatus
);
1318 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1321 // set global locking range values
1323 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1324 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1325 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1326 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
, TCG_UID_METHOD_SET
));
1327 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1328 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1329 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x01)); // "Values"
1330 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1332 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1333 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x07)); // "ReadLocked"
1334 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLocked
));
1335 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1337 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1338 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x08)); // "WriteLocked"
1339 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLocked
));
1340 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1342 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1343 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1344 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1345 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1346 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1347 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1348 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1350 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1351 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1353 return TcgResultSuccess
;
1358 The function updates the RangeStart, RangeLength, ReadLockedEnabled, WriteLockedEnabled, ReadLocked and WriteLocked columns
1359 of the specified Locking Range. This function requires admin authority of a locking SP session.
1361 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key
1362 @param[in] LockingRangeUid Locking range UID to set values
1363 @param[in] RangeStart Value to set RangeStart column for Locking Range
1364 @param[in] RangeLength Value to set RangeLength column for Locking Range
1365 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range
1366 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range
1367 @param[in] ReadLocked Value to set ReadLocked column for Locking Range
1368 @param[in] WriteLocked Value to set WriteLocked column for Locking Range
1369 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.
1374 OpalSetLockingRange(
1375 OPAL_SESSION
*LockingSpSession
,
1376 TCG_UID LockingRangeUid
,
1379 BOOLEAN ReadLockEnabled
,
1380 BOOLEAN WriteLockEnabled
,
1382 BOOLEAN WriteLocked
,
1386 UINT8 Buf
[BUFFER_SIZE
];
1387 TCG_CREATE_STRUCT CreateStruct
;
1388 TCG_PARSE_STRUCT ParseStruct
;
1391 NULL_CHECK(LockingSpSession
);
1392 NULL_CHECK(MethodStatus
);
1394 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1397 // set locking range values
1399 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1400 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1401 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1402 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, LockingRangeUid
, TCG_UID_METHOD_SET
));
1403 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1404 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1405 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x01)); // "Values"
1406 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1409 // range start and range Length only apply to non-global locking ranges
1411 if (LockingRangeUid
!= OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
) {
1412 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1413 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x03)); // "RangeStart"
1414 ERROR_CHECK(TcgAddUINT64(&CreateStruct
, RangeStart
));
1415 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1417 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1418 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x04)); // "RangeLength"
1419 ERROR_CHECK(TcgAddUINT64(&CreateStruct
, RangeLength
));
1420 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1423 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1424 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x05)); // "ReadLockEnabled"
1425 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLockEnabled
));
1426 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1428 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1429 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x06)); // "WriteLockEnabled"
1430 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLockEnabled
));
1431 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1433 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1434 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x07)); // "ReadLocked"
1435 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, ReadLocked
));
1436 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1438 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1439 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, 0x08)); // "WriteLocked"
1440 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct
, WriteLocked
));
1441 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1443 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1444 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1445 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1446 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1447 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1448 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1449 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1451 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, MethodStatus
, 0));
1452 // Exit with success on method failure - user must inspect MethodStatus
1453 METHOD_STATUS_ERROR_CHECK(*MethodStatus
, TcgResultSuccess
);
1455 return TcgResultSuccess
;
1460 The function populates the CreateStruct with a payload that will retrieve the global locking range active key.
1461 It is intended to be called with a session that is already started with a valid credential.
1462 The function does not send the payload.
1464 @param[in] Session OPAL_SESSION to populate command for, needs ComId
1465 @param[in/out] CreateStruct Structure to populate with encoded TCG command
1466 @param[in/out] Size Size in bytes of the command created.
1471 OpalCreateRetrieveGlobalLockingRangeActiveKey(
1472 const OPAL_SESSION
*Session
,
1473 TCG_CREATE_STRUCT
*CreateStruct
,
1477 NULL_CHECK(Session
);
1478 NULL_CHECK(CreateStruct
);
1481 // Retrieve the activekey in order to know which globalrange key to generate
1482 ERROR_CHECK(TcgStartComPacket(CreateStruct
, Session
->OpalBaseComId
, Session
->ComIdExtension
));
1483 ERROR_CHECK(TcgStartPacket(CreateStruct
, Session
->TperSessionId
, Session
->HostSessionId
, 0x0, 0x0, 0x0));
1484 ERROR_CHECK(TcgStartSubPacket(CreateStruct
, 0x0));
1485 ERROR_CHECK(TcgStartMethodCall(CreateStruct
, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
, TCG_UID_METHOD_GET
));
1486 ERROR_CHECK(TcgStartParameters(CreateStruct
));
1487 ERROR_CHECK(TcgAddStartList(CreateStruct
));
1488 ERROR_CHECK(TcgAddStartName(CreateStruct
));
1489 ERROR_CHECK(TcgAddUINT8(CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
1490 ERROR_CHECK(TcgAddUINT8(CreateStruct
, 0x0A)); // ActiveKey
1491 ERROR_CHECK(TcgAddEndName(CreateStruct
));
1492 ERROR_CHECK(TcgAddStartName(CreateStruct
));
1493 ERROR_CHECK(TcgAddUINT8(CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
1494 ERROR_CHECK(TcgAddUINT8(CreateStruct
, 0x0A));
1495 ERROR_CHECK(TcgAddEndName(CreateStruct
));
1496 ERROR_CHECK(TcgAddEndList(CreateStruct
));
1497 ERROR_CHECK(TcgEndParameters(CreateStruct
));
1498 ERROR_CHECK(TcgEndMethodCall(CreateStruct
));
1499 ERROR_CHECK(TcgEndSubPacket(CreateStruct
));
1500 ERROR_CHECK(TcgEndPacket(CreateStruct
));
1501 ERROR_CHECK(TcgEndComPacket(CreateStruct
, Size
));
1503 return TcgResultSuccess
;
1508 The function acquires the activeKey specified for the Global Locking Range from the ParseStruct.
1510 @param[in] ParseStruct Structure that contains the device's response with the activekey
1511 @param[in/out] ActiveKey The UID of the active key retrieved
1516 OpalParseRetrieveGlobalLockingRangeActiveKey(
1517 TCG_PARSE_STRUCT
*ParseStruct
,
1523 NULL_CHECK(ParseStruct
);
1524 NULL_CHECK(ActiveKey
);
1527 ERROR_CHECK(TcgGetNextStartList(ParseStruct
));
1528 ERROR_CHECK(TcgGetNextStartList(ParseStruct
));
1529 ERROR_CHECK(TcgGetNextStartName(ParseStruct
));
1530 ERROR_CHECK(TcgGetNextUINT32(ParseStruct
, &ColumnName
));
1531 ERROR_CHECK(TcgGetNextTcgUid(ParseStruct
, ActiveKey
));
1532 ERROR_CHECK(TcgGetNextEndName(ParseStruct
));
1533 ERROR_CHECK(TcgGetNextEndList(ParseStruct
));
1534 ERROR_CHECK(TcgGetNextEndList(ParseStruct
));
1535 ERROR_CHECK(TcgGetNextEndOfData(ParseStruct
));
1537 if (ColumnName
!= 0x0A) {
1538 DEBUG ((DEBUG_INFO
, "Unexpected column name %u (exp 0x0A)\n", ColumnName
));
1539 return TcgResultFailure
;
1542 if (*ActiveKey
!= OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY
&& *ActiveKey
!= OPAL_LOCKING_SP_K_AES_128_GLOBALRANGE_KEY
) {
1543 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
));
1544 return TcgResultFailure
;
1547 return TcgResultSuccess
;
1552 The function retrieves the TryLimit column for the specified rowUid (authority).
1554 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve try limit
1555 @param[in] RowUid Row UID of the Locking SP C_PIN table to retrieve TryLimit column
1556 @param[in/out] TryLimit Value from TryLimit column
1562 OPAL_SESSION
*LockingSpSession
,
1567 TCG_CREATE_STRUCT CreateStruct
;
1568 TCG_PARSE_STRUCT ParseStruct
;
1571 UINT8 Buf
[BUFFER_SIZE
];
1574 NULL_CHECK(LockingSpSession
);
1575 NULL_CHECK(TryLimit
);
1577 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct
, Buf
, sizeof(Buf
)));
1578 ERROR_CHECK(TcgStartComPacket(&CreateStruct
, LockingSpSession
->OpalBaseComId
, LockingSpSession
->ComIdExtension
));
1579 ERROR_CHECK(TcgStartPacket(&CreateStruct
, LockingSpSession
->TperSessionId
, LockingSpSession
->HostSessionId
, 0x0, 0x0, 0x0));
1580 ERROR_CHECK(TcgStartSubPacket(&CreateStruct
, 0x0));
1581 ERROR_CHECK(TcgStartMethodCall(&CreateStruct
, RowUid
, TCG_UID_METHOD_GET
));
1582 ERROR_CHECK(TcgStartParameters(&CreateStruct
));
1583 ERROR_CHECK(TcgAddStartList(&CreateStruct
));
1584 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1585 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_START_COLUMN_NAME
));
1586 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1587 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1588 ERROR_CHECK(TcgAddStartName(&CreateStruct
));
1589 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, TCG_CELL_BLOCK_END_COLUMN_NAME
));
1590 ERROR_CHECK(TcgAddUINT8(&CreateStruct
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1591 ERROR_CHECK(TcgAddEndName(&CreateStruct
));
1592 ERROR_CHECK(TcgAddEndList(&CreateStruct
));
1593 ERROR_CHECK(TcgEndParameters(&CreateStruct
));
1594 ERROR_CHECK(TcgEndMethodCall(&CreateStruct
));
1595 ERROR_CHECK(TcgEndSubPacket(&CreateStruct
));
1596 ERROR_CHECK(TcgEndPacket(&CreateStruct
));
1597 ERROR_CHECK(TcgEndComPacket(&CreateStruct
, &Size
));
1599 ERROR_CHECK(OpalPerformMethod(LockingSpSession
, Size
, Buf
, sizeof(Buf
), &ParseStruct
, &MethodStatus
, 0));
1600 METHOD_STATUS_ERROR_CHECK(MethodStatus
, TcgResultFailure
);
1602 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
1603 ERROR_CHECK(TcgGetNextStartList(&ParseStruct
));
1604 ERROR_CHECK(TcgGetNextStartName(&ParseStruct
));
1605 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, &Col
));
1606 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct
, TryLimit
));
1607 ERROR_CHECK(TcgGetNextEndName(&ParseStruct
));
1608 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
1609 ERROR_CHECK(TcgGetNextEndList(&ParseStruct
));
1610 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct
));
1612 if (Col
!= OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
) {
1613 DEBUG ((DEBUG_INFO
, "ERROR: got col %u, expected %u\n", Col
, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL
));
1614 return TcgResultFailure
;
1617 return TcgResultSuccess
;
1622 Get the support attribute info.
1624 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1625 @param[out] SupportedAttributes Return the support attribute info.
1626 @param[out] OpalBaseComId Return the base com id info.
1631 OpalGetSupportedAttributesInfo(
1632 IN OPAL_SESSION
*Session
,
1633 OUT OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1634 OUT UINT16
*OpalBaseComId
1637 UINT8 Buffer
[BUFFER_SIZE
];
1638 TCG_SUPPORTED_SECURITY_PROTOCOLS
*SupportedProtocols
;
1639 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1640 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1641 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat2
;
1645 NULL_CHECK(Session
);
1646 NULL_CHECK(SupportedAttributes
);
1647 NULL_CHECK(OpalBaseComId
);
1649 ZeroMem(Buffer
, BUFFER_SIZE
);
1650 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1653 // Retrieve supported protocols verify security protocol 1 is supported
1655 SupportedProtocols
= (TCG_SUPPORTED_SECURITY_PROTOCOLS
*) Buffer
;
1658 // Get list of supported protocols
1660 if (OpalRetrieveSupportedProtocolList (Session
, sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
), SupportedProtocols
) == TcgResultFailure
) {
1661 DEBUG ((DEBUG_INFO
, "OpalRetrieveSupportedProtocolList failed\n"));
1662 return TcgResultFailure
;
1665 SupportedAttributes
->Sp1
= TcgIsProtocolSupported (SupportedProtocols
, TCG_OPAL_SECURITY_PROTOCOL_1
);
1666 SupportedAttributes
->Sp2
= TcgIsProtocolSupported (SupportedProtocols
, TCG_OPAL_SECURITY_PROTOCOL_2
);
1667 SupportedAttributes
->SpIeee1667
= TcgIsProtocolSupported (SupportedProtocols
, TCG_SECURITY_PROTOCOL_IEEE_1667
);
1669 DEBUG ((DEBUG_INFO
, "Supported Protocols: Sp1 %d Sp2: %d SpIeee1667 %d \n",
1670 SupportedAttributes
->Sp1
,
1671 SupportedAttributes
->Sp2
,
1672 SupportedAttributes
->SpIeee1667
1676 // Perform level 0 discovery and assign desired feature info to Opal Disk structure
1678 ZeroMem (Buffer
, BUFFER_SIZE
);
1679 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1680 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1681 return TcgResultFailure
;
1685 // Check for required feature descriptors
1687 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1690 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_V2_0_0
, &Size
);
1691 SupportedAttributes
->OpalSsc2
= (Feat
!= NULL
);
1693 *OpalBaseComId
= TCG_RESERVED_COMID
;
1696 // Check Opal SCC V2 has valid settings for SID C_PIN on revert
1698 if (SupportedAttributes
->OpalSsc2
&& Size
>= sizeof (OPAL_SSCV2_FEATURE_DESCRIPTOR
)) {
1700 // Want opposite polarity b/c Value is greater than a bit, but we only care about non-zero vs zero
1702 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1703 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1704 DEBUG ((DEBUG_INFO
, "Opal SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1705 SupportedAttributes
->InitCpinIndicator
,
1706 SupportedAttributes
->CpinUponRevert
1708 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscV2
.BaseComdIdBE
);
1712 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_LITE
, &Size
);
1713 SupportedAttributes
->OpalSscLite
= (Feat
!= NULL
);
1715 if (Feat
!= NULL
&& Size
>= sizeof (OPAL_SSCLITE_FEATURE_DESCRIPTOR
)) {
1716 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1718 // Pin values used always match up with ComId used
1720 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscLite
.BaseComdIdBE
);
1721 SupportedAttributes
->InitCpinIndicator
= (Feat
->OpalSscV2
.InitialCPINSIDPIN
== 0);
1722 SupportedAttributes
->CpinUponRevert
= (Feat
->OpalSscV2
.CPINSIDPINRevertBehavior
== 0);
1723 DEBUG ((DEBUG_INFO
, "Opal SSC Lite InitCpinIndicator %d CpinUponRevert %d \n",
1724 SupportedAttributes
->InitCpinIndicator
,
1725 SupportedAttributes
->CpinUponRevert
1731 // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 feature data.
1732 // so here try to get data from pyrite 2.0 feature data first.
1735 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_PYRITE_SSC
, &Size
);
1737 Feat2
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_PYRITE_SSC_V2_0_0
, &Size2
);
1738 if (Feat2
!= NULL
&& Size2
>= sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTOR
)) {
1739 SupportedAttributes
->PyriteSscV2
= TRUE
;
1740 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1741 *OpalBaseComId
= SwapBytes16 (Feat2
->PyriteSscV2
.BaseComdIdBE
);
1742 SupportedAttributes
->InitCpinIndicator
= (Feat2
->PyriteSscV2
.InitialCPINSIDPIN
== 0);
1743 SupportedAttributes
->CpinUponRevert
= (Feat2
->PyriteSscV2
.CPINSIDPINRevertBehavior
== 0);
1744 DEBUG ((DEBUG_INFO
, "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",
1745 SupportedAttributes
->InitCpinIndicator
,
1746 SupportedAttributes
->CpinUponRevert
1750 SupportedAttributes
->PyriteSsc
= (Feat
!= NULL
);
1751 if (Feat
!= NULL
&& Size
>= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR
)) {
1752 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1753 *OpalBaseComId
= SwapBytes16 (Feat
->PyriteSsc
.BaseComdIdBE
);
1754 SupportedAttributes
->InitCpinIndicator
= (Feat
->PyriteSsc
.InitialCPINSIDPIN
== 0);
1755 SupportedAttributes
->CpinUponRevert
= (Feat
->PyriteSsc
.CPINSIDPINRevertBehavior
== 0);
1756 DEBUG ((DEBUG_INFO
, "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",
1757 SupportedAttributes
->InitCpinIndicator
,
1758 SupportedAttributes
->CpinUponRevert
1765 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_OPAL_SSC_V1_0_0
, &Size
);
1766 SupportedAttributes
->OpalSsc1
= (Feat
!= NULL
);
1767 if (Feat
!= NULL
&& Size
>= sizeof (OPAL_SSCV1_FEATURE_DESCRIPTOR
)) {
1768 if (*OpalBaseComId
== TCG_RESERVED_COMID
) {
1769 *OpalBaseComId
= SwapBytes16 (Feat
->OpalSscV1
.BaseComdIdBE
);
1774 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_LOCKING
, &Size
);
1775 if (Feat
!= NULL
&& Size
>= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
)) {
1776 SupportedAttributes
->MediaEncryption
= Feat
->Locking
.MediaEncryption
;
1777 DEBUG ((DEBUG_INFO
, "SupportedAttributes->MediaEncryption 0x%X \n", SupportedAttributes
->MediaEncryption
));
1781 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_BLOCK_SID
, &Size
);
1782 if (Feat
!= NULL
&& Size
>= sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR
)) {
1783 SupportedAttributes
->BlockSid
= TRUE
;
1784 DEBUG ((DEBUG_INFO
, "BlockSid Supported!!! Current Status is 0x%X \n", Feat
->BlockSid
.SIDBlockedState
));
1786 DEBUG ((DEBUG_INFO
, "BlockSid Unsupported!!!"));
1790 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_DATA_REMOVAL
, &Size
);
1791 if (Feat
!= NULL
&& Size
>= sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR
)) {
1792 SupportedAttributes
->DataRemoval
= TRUE
;
1793 DEBUG ((DEBUG_INFO
, "DataRemoval Feature Supported!\n"));
1794 DEBUG ((DEBUG_INFO
, "Operation Processing = 0x%x\n", Feat
->DataRemoval
.OperationProcessing
));
1795 DEBUG ((DEBUG_INFO
, "RemovalMechanism = 0x%x\n", Feat
->DataRemoval
.RemovalMechanism
));
1796 DEBUG ((DEBUG_INFO
, "BIT0 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit0
, SwapBytes16 (Feat
->DataRemoval
.TimeBit0
)));
1797 DEBUG ((DEBUG_INFO
, "BIT1 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit1
, SwapBytes16 (Feat
->DataRemoval
.TimeBit1
)));
1798 DEBUG ((DEBUG_INFO
, "BIT2 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit2
, SwapBytes16 (Feat
->DataRemoval
.TimeBit2
)));
1799 DEBUG ((DEBUG_INFO
, "BIT3 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit3
, SwapBytes16 (Feat
->DataRemoval
.TimeBit3
)));
1800 DEBUG ((DEBUG_INFO
, "BIT4 :: Format = 0x%x, Time = 0x%x\n", Feat
->DataRemoval
.FormatBit4
, SwapBytes16 (Feat
->DataRemoval
.TimeBit4
)));
1803 DEBUG ((DEBUG_INFO
, "Base COMID 0x%04X \n", *OpalBaseComId
));
1805 return TcgResultSuccess
;
1810 Get the support attribute info.
1812 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1813 @param[in/out] LockingFeature Return the Locking info.
1819 OPAL_SESSION
*Session
,
1820 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1823 UINT8 Buffer
[BUFFER_SIZE
];
1824 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1825 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1828 NULL_CHECK(Session
);
1829 NULL_CHECK(LockingFeature
);
1831 ZeroMem(Buffer
, BUFFER_SIZE
);
1832 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1834 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1835 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1836 return TcgResultFailure
;
1838 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1841 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, TCG_FEATURE_LOCKING
, &Size
);
1842 if (Feat
!= NULL
&& Size
>= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
)) {
1843 CopyMem (LockingFeature
, &Feat
->Locking
, sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR
));
1846 return TcgResultSuccess
;
1851 Get the descriptor for the specific feature code.
1853 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.
1854 @param[in] FeatureCode The feature code user request.
1855 @param[in, out] DataSize The data size.
1856 @param[out] Data The data buffer used to save the feature descriptor.
1860 OpalGetFeatureDescriptor (
1861 IN OPAL_SESSION
*Session
,
1862 IN UINT16 FeatureCode
,
1863 IN OUT UINTN
*DataSize
,
1867 UINT8 Buffer
[BUFFER_SIZE
];
1868 TCG_LEVEL0_DISCOVERY_HEADER
*DiscoveryHeader
;
1869 OPAL_LEVEL0_FEATURE_DESCRIPTOR
*Feat
;
1872 NULL_CHECK(Session
);
1873 NULL_CHECK(DataSize
);
1876 ZeroMem(Buffer
, BUFFER_SIZE
);
1877 ASSERT(sizeof(Buffer
) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS
));
1879 if (OpalRetrieveLevel0DiscoveryHeader (Session
, BUFFER_SIZE
, Buffer
) == TcgResultFailure
) {
1880 DEBUG ((DEBUG_INFO
, "OpalRetrieveLevel0DiscoveryHeader failed\n"));
1881 return TcgResultFailure
;
1883 DiscoveryHeader
= (TCG_LEVEL0_DISCOVERY_HEADER
*) Buffer
;
1886 Feat
= (OPAL_LEVEL0_FEATURE_DESCRIPTOR
*) TcgGetFeature (DiscoveryHeader
, FeatureCode
, &Size
);
1888 if (Size
> *DataSize
) {
1890 return TcgResultFailureBufferTooSmall
;
1894 CopyMem (Data
, Feat
, Size
);
1897 return TcgResultSuccess
;
1902 The function determines whether or not all of the requirements for the Opal Feature (not full specification)
1903 are met by the specified device.
1905 @param[in] SupportedAttributes Opal device attribute.
1910 OpalFeatureSupported(
1911 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
1914 NULL_CHECK(SupportedAttributes
);
1916 if (SupportedAttributes
->Sp1
== 0) {
1920 if (SupportedAttributes
->OpalSscLite
== 0 &&
1921 SupportedAttributes
->OpalSsc1
== 0 &&
1922 SupportedAttributes
->OpalSsc2
== 0 &&
1923 SupportedAttributes
->PyriteSsc
== 0 &&
1924 SupportedAttributes
->PyriteSscV2
== 0
1934 The function returns whether or not the device is Opal Enabled.
1935 TRUE means that the device is partially or fully locked.
1936 This will perform a Level 0 Discovery and parse the locking feature descriptor
1938 @param[in] SupportedAttributes Opal device attribute.
1939 @param[in] LockingFeature Opal device locking status.
1946 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1947 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1950 NULL_CHECK(SupportedAttributes
);
1951 NULL_CHECK(LockingFeature
);
1953 if (!OpalFeatureSupported (SupportedAttributes
)) {
1957 if (LockingFeature
->LockingSupported
&& LockingFeature
->LockingEnabled
) {
1966 The function returns whether or not the device is Opal Locked.
1967 TRUE means that the device is partially or fully locked.
1968 This will perform a Level 0 Discovery and parse the locking feature descriptor
1970 @param[in] SupportedAttributes Opal device attribute.
1971 @param[in] LockingFeature Opal device locking status.
1976 OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
1977 TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
1980 NULL_CHECK(SupportedAttributes
);
1981 NULL_CHECK(LockingFeature
);
1983 if (!OpalFeatureEnabled (SupportedAttributes
, LockingFeature
)) {
1987 return LockingFeature
->Locked
;