]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / TcgStorageOpalLib / TcgStorageOpalUtil.c
1 /** @file
2 Public API for Opal Core library.
3
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8 #include <Uefi.h>
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/TcgStorageOpalLib.h>
12 #include "TcgStorageOpalLibInternal.h"
13
14 #define OPAL_MSID_LENGTH 128
15
16 /**
17 Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.
18
19 @param[in] Session, The session info for one opal device.
20 @param[in] Psid PSID of device to revert.
21 @param[in] PsidLength Length of PSID in bytes.
22
23 **/
24 TCG_RESULT
25 EFIAPI
26 OpalUtilPsidRevert (
27 OPAL_SESSION *Session,
28 const VOID *Psid,
29 UINT32 PsidLength
30 )
31 {
32 UINT8 MethodStatus;
33 TCG_RESULT Ret;
34 UINT32 RemovalTimeOut;
35
36 NULL_CHECK (Session);
37 NULL_CHECK (Psid);
38
39 RemovalTimeOut = GetRevertTimeOut (Session);
40 DEBUG ((DEBUG_INFO, "OpalUtilPsidRevert: Timeout value = %d\n", RemovalTimeOut));
41
42 Ret = OpalStartSession (
43 Session,
44 OPAL_UID_ADMIN_SP,
45 TRUE,
46 PsidLength,
47 Psid,
48 OPAL_ADMIN_SP_PSID_AUTHORITY,
49 &MethodStatus
50 );
51 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
52 Ret = OpalPyrite2PsidRevert (Session, RemovalTimeOut);
53 if (Ret != TcgResultSuccess) {
54 //
55 // If revert was successful, session was already ended by TPer, so only end session on failure
56 //
57 OpalEndSession (Session);
58 }
59 }
60
61 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
62 Ret = TcgResultFailure;
63 }
64
65 return Ret;
66 }
67
68 /**
69 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY,
70 sets the OPAL_UID_ADMIN_SP_C_PIN_SID column with the new password,
71 and activates the locking SP to copy SID PIN to Admin1 Locking SP PIN
72
73 @param[in] Session, The session info for one opal device.
74 @param[in] GeneratedSid Generated SID of disk
75 @param[in] SidLength Length of generatedSid in bytes
76 @param[in] Password New admin password to set
77 @param[in] PassLength Length of password in bytes
78
79 **/
80 TCG_RESULT
81 EFIAPI
82 OpalUtilSetAdminPasswordAsSid (
83 OPAL_SESSION *Session,
84 const VOID *GeneratedSid,
85 UINT32 SidLength,
86 const VOID *Password,
87 UINT32 PassLength
88 )
89 {
90 UINT8 MethodStatus;
91 TCG_RESULT Ret;
92
93 NULL_CHECK (Session);
94 NULL_CHECK (GeneratedSid);
95 NULL_CHECK (Password);
96
97 Ret = OpalStartSession (
98 Session,
99 OPAL_UID_ADMIN_SP,
100 TRUE,
101 SidLength,
102 GeneratedSid,
103 OPAL_ADMIN_SP_SID_AUTHORITY,
104 &MethodStatus
105 );
106 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
107 DEBUG ((DEBUG_INFO, "start session with admin SP as SID authority failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));
108 goto done;
109 }
110
111 //
112 // 1. Update SID = new Password
113 //
114 Ret = OpalSetPassword (
115 Session,
116 OPAL_UID_ADMIN_SP_C_PIN_SID,
117 Password,
118 PassLength,
119 &MethodStatus
120 );
121
122 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
123 OpalEndSession (Session);
124 DEBUG ((DEBUG_INFO, "set Password failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));
125 goto done;
126 }
127
128 //
129 // 2. Activate locking SP
130 //
131 Ret = OpalActivateLockingSp (Session, &MethodStatus);
132 OpalEndSession (Session);
133 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
134 DEBUG ((DEBUG_INFO, "activate locking SP failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));
135 goto done;
136 }
137
138 done:
139 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
140 Ret = TcgResultFailure;
141 }
142
143 return Ret;
144 }
145
146 /**
147
148 Opens a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
149 and updates the specified locking range with the provided column values
150
151 @param[in] Session, The session info for one opal device.
152 @param[in] Password New admin password to set
153 @param[in] PassLength Length of password in bytes
154 @param[in] LockingRangeUid Locking range UID to set values
155 @param[in] RangeStart Value to set RangeStart column for Locking Range
156 @param[in] RangeLength Value to set RangeLength column for Locking Range
157 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range
158 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range
159 @param[in] ReadLocked Value to set ReadLocked column for Locking Range
160 @param[in] WriteLocked Value to set WriteLocked column for Locking Range
161
162 **/
163 TCG_RESULT
164 EFIAPI
165 OpalUtilSetOpalLockingRange (
166 OPAL_SESSION *Session,
167 const VOID *Password,
168 UINT32 PassLength,
169 TCG_UID LockingRangeUid,
170 UINT64 RangeStart,
171 UINT64 RangeLength,
172 BOOLEAN ReadLockEnabled,
173 BOOLEAN WriteLockEnabled,
174 BOOLEAN ReadLocked,
175 BOOLEAN WriteLocked
176 )
177 {
178 UINT8 MethodStatus;
179 TCG_RESULT Ret;
180
181 NULL_CHECK (Session);
182 NULL_CHECK (Password);
183
184 //
185 // Start session with Locking SP using current admin Password
186 //
187 Ret = OpalStartSession (
188 Session,
189 OPAL_UID_LOCKING_SP,
190 TRUE,
191 PassLength,
192 Password,
193 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
194 &MethodStatus
195 );
196 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
197 DEBUG ((DEBUG_INFO, "start session with locking SP failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));
198 goto done;
199 }
200
201 //
202 // Enable locking range
203 //
204 Ret = OpalSetLockingRange (
205 Session,
206 LockingRangeUid,
207 RangeStart,
208 RangeLength,
209 ReadLockEnabled,
210 WriteLockEnabled,
211 ReadLocked,
212 WriteLocked,
213 &MethodStatus
214 );
215
216 OpalEndSession (Session);
217 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
218 DEBUG ((DEBUG_INFO, "set locking range failed: Ret=%d MethodStatus=0x%x\n", Ret, MethodStatus));
219 }
220
221 done:
222 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
223 Ret = TcgResultFailure;
224 }
225
226 return Ret;
227 }
228
229 /**
230 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY,
231 sets OPAL_UID_ADMIN_SP_C_PIN_SID with the new password,
232 and sets OPAL_LOCKING_SP_C_PIN_ADMIN1 with the new password.
233
234 @param[in] Session, The session info for one opal device.
235 @param[in] OldPassword Current admin password
236 @param[in] OldPasswordLength Length of current admin password in bytes
237 @param[in] NewPassword New admin password to set
238 @param[in] NewPasswordLength Length of new password in bytes
239
240 **/
241 TCG_RESULT
242 EFIAPI
243 OpalUtilSetAdminPassword (
244 OPAL_SESSION *Session,
245 const VOID *OldPassword,
246 UINT32 OldPasswordLength,
247 const VOID *NewPassword,
248 UINT32 NewPasswordLength
249 )
250 {
251 TCG_RESULT Ret;
252 UINT8 MethodStatus;
253
254 NULL_CHECK (Session);
255 NULL_CHECK (OldPassword);
256 NULL_CHECK (NewPassword);
257
258 //
259 // Unknown ownership
260 //
261 Ret = OpalStartSession (
262 Session,
263 OPAL_UID_ADMIN_SP,
264 TRUE,
265 OldPasswordLength,
266 OldPassword,
267 OPAL_ADMIN_SP_SID_AUTHORITY,
268 &MethodStatus
269 );
270 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
271 DEBUG ((DEBUG_INFO, "start session with admin SP using old Password failed\n"));
272 goto done;
273 }
274
275 //
276 // Update SID = new pw
277 //
278 Ret = OpalSetPassword (Session, OPAL_UID_ADMIN_SP_C_PIN_SID, NewPassword, NewPasswordLength, &MethodStatus);
279 OpalEndSession (Session);
280 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
281 DEBUG ((DEBUG_INFO, "set new admin SP Password failed\n"));
282 goto done;
283 }
284
285 Ret = OpalStartSession (
286 Session,
287 OPAL_UID_LOCKING_SP,
288 TRUE,
289 OldPasswordLength,
290 OldPassword,
291 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
292 &MethodStatus
293 );
294 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
295 DEBUG ((DEBUG_INFO, "start session with locking SP using old Password failed\n"));
296 goto done;
297 }
298
299 //
300 // Update admin locking SP to new pw
301 //
302 Ret = OpalSetPassword (Session, OPAL_LOCKING_SP_C_PIN_ADMIN1, NewPassword, NewPasswordLength, &MethodStatus);
303 OpalEndSession (Session);
304 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
305 DEBUG ((DEBUG_INFO, "set new locking SP Password failed\n"));
306 goto done;
307 }
308
309 done:
310 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
311 Ret = TcgResultFailure;
312 }
313
314 return Ret;
315 }
316
317 /**
318 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
319 and sets the User1 SP authority to enabled and sets the User1 password.
320
321 @param[in] Session, The session info for one opal device.
322 @param[in] OldPassword Current admin password
323 @param[in] OldPasswordLength Length of current admin password in bytes
324 @param[in] NewPassword New admin password to set
325 @param[in] NewPasswordLength Length of new password in bytes
326
327 **/
328 TCG_RESULT
329 EFIAPI
330 OpalUtilSetUserPassword (
331 OPAL_SESSION *Session,
332 const VOID *OldPassword,
333 UINT32 OldPasswordLength,
334 const VOID *NewPassword,
335 UINT32 NewPasswordLength
336 )
337 {
338 UINT8 MethodStatus;
339 TCG_RESULT Ret;
340
341 NULL_CHECK (Session);
342 NULL_CHECK (OldPassword);
343 NULL_CHECK (NewPassword);
344
345 //
346 // See if updating user1 authority
347 //
348 Ret = OpalStartSession (
349 Session,
350 OPAL_UID_LOCKING_SP,
351 TRUE,
352 OldPasswordLength,
353 OldPassword,
354 OPAL_LOCKING_SP_USER1_AUTHORITY,
355 &MethodStatus
356 );
357 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
358 Ret = OpalSetPassword (
359 Session,
360 OPAL_LOCKING_SP_C_PIN_USER1,
361 NewPassword,
362 NewPasswordLength,
363 &MethodStatus
364 );
365 OpalEndSession (Session);
366 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
367 return Ret;
368 }
369 }
370
371 //
372 // Setting Password for first time or setting Password as admin
373 //
374
375 //
376 // Start session with Locking SP using current admin Password
377 //
378 Ret = OpalStartSession (
379 Session,
380 OPAL_UID_LOCKING_SP,
381 TRUE,
382 OldPasswordLength,
383 OldPassword,
384 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
385 &MethodStatus
386 );
387 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
388 DEBUG ((DEBUG_INFO, "StartSession with locking SP as admin1 authority failed\n"));
389 goto done;
390 }
391
392 //
393 // Enable User1 and set its PIN
394 //
395 Ret = OpalSetLockingSpAuthorityEnabledAndPin (
396 Session,
397 OPAL_LOCKING_SP_C_PIN_USER1,
398 OPAL_LOCKING_SP_USER1_AUTHORITY,
399 NewPassword,
400 NewPasswordLength,
401 &MethodStatus
402 );
403 OpalEndSession (Session);
404 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
405 DEBUG ((DEBUG_INFO, "OpalSetLockingSpAuthorityEnabledAndPin failed\n"));
406 goto done;
407 }
408
409 done:
410 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
411 Ret = TcgResultFailure;
412 }
413
414 return Ret;
415 }
416
417 /**
418 Verify whether user input the correct password.
419
420 @param[in] Session, The session info for one opal device.
421 @param[in] Password Admin password
422 @param[in] PasswordLength Length of password in bytes
423 @param[in/out] HostSigningAuthority Use the Host signing authority type.
424
425 **/
426 TCG_RESULT
427 EFIAPI
428 OpalUtilVerifyPassword (
429 OPAL_SESSION *Session,
430 const VOID *Password,
431 UINT32 PasswordLength,
432 TCG_UID HostSigningAuthority
433 )
434 {
435 TCG_RESULT Ret;
436 UINT8 MethodStatus;
437
438 NULL_CHECK (Session);
439 NULL_CHECK (Password);
440
441 Ret = OpalStartSession (
442 Session,
443 OPAL_UID_LOCKING_SP,
444 TRUE,
445 PasswordLength,
446 Password,
447 HostSigningAuthority,
448 &MethodStatus
449 );
450 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
451 OpalEndSession (Session);
452 return TcgResultSuccess;
453 }
454
455 return TcgResultFailure;
456 }
457
458 /**
459 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
460 and generates a new global locking range key to erase the Data.
461
462 @param[in] Session, The session info for one opal device.
463 @param[in] Password Admin or user password
464 @param[in] PasswordLength Length of password in bytes
465 @param[in/out] PasswordFailed indicates if password failed (start session didn't work)
466
467 **/
468 TCG_RESULT
469 EFIAPI
470 OpalUtilSecureErase (
471 OPAL_SESSION *Session,
472 const VOID *Password,
473 UINT32 PasswordLength,
474 BOOLEAN *PasswordFailed
475 )
476 {
477 UINT8 MethodStatus;
478 TCG_RESULT Ret;
479
480 NULL_CHECK (Session);
481 NULL_CHECK (Password);
482 NULL_CHECK (PasswordFailed);
483
484 //
485 // Try to generate a new key with admin1
486 //
487 Ret = OpalStartSession (
488 Session,
489 OPAL_UID_LOCKING_SP,
490 TRUE,
491 PasswordLength,
492 Password,
493 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
494 &MethodStatus
495 );
496
497 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
498 Ret = OpalGlobalLockingRangeGenKey (Session, &MethodStatus);
499 *PasswordFailed = FALSE;
500 OpalEndSession (Session);
501 } else {
502 //
503 // Try to generate a new key with user1
504 //
505 Ret = OpalStartSession (
506 Session,
507 OPAL_UID_LOCKING_SP,
508 TRUE,
509 PasswordLength,
510 Password,
511 OPAL_LOCKING_SP_USER1_AUTHORITY,
512 &MethodStatus
513 );
514
515 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
516 Ret = OpalGlobalLockingRangeGenKey (Session, &MethodStatus);
517 *PasswordFailed = FALSE;
518 OpalEndSession (Session);
519 } else {
520 *PasswordFailed = TRUE;
521 }
522 }
523
524 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
525 Ret = TcgResultFailure;
526 }
527
528 return Ret;
529 }
530
531 /**
532 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority.
533
534 @param[in] Session, The session info for one opal device.
535 @param[in] Password Admin password
536 @param[in] PasswordLength Length of password in bytes
537 @param[in/out] PasswordFailed indicates if password failed (start session didn't work)
538
539 **/
540 TCG_RESULT
541 EFIAPI
542 OpalUtilDisableUser (
543 OPAL_SESSION *Session,
544 const VOID *Password,
545 UINT32 PasswordLength,
546 BOOLEAN *PasswordFailed
547 )
548 {
549 UINT8 MethodStatus;
550 TCG_RESULT Ret;
551
552 NULL_CHECK (Session);
553 NULL_CHECK (Password);
554 NULL_CHECK (PasswordFailed);
555
556 //
557 // Start session with Locking SP using current admin Password
558 //
559 Ret = OpalStartSession (
560 Session,
561 OPAL_UID_LOCKING_SP,
562 TRUE,
563 PasswordLength,
564 Password,
565 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
566 &MethodStatus
567 );
568 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
569 DEBUG ((DEBUG_INFO, "StartSession with Locking SP as Admin1 failed\n"));
570 *PasswordFailed = TRUE;
571 goto done;
572 }
573
574 *PasswordFailed = FALSE;
575 Ret = OpalDisableUser (Session, &MethodStatus);
576 OpalEndSession (Session);
577
578 done:
579 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
580 Ret = TcgResultFailure;
581 }
582
583 return Ret;
584 }
585
586 /**
587 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method.
588
589 @param[in] Session, The session info for one opal device.
590 @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it
591 @param[in] Password Admin password
592 @param[in] PasswordLength Length of password in bytes
593 @param[in/out] PasswordFailed indicates if password failed (start session didn't work)
594 @param[in] Msid Msid info.
595 @param[in] MsidLength Msid data length.
596
597 **/
598 TCG_RESULT
599 EFIAPI
600 OpalUtilRevert (
601 OPAL_SESSION *Session,
602 BOOLEAN KeepUserData,
603 const VOID *Password,
604 UINT32 PasswordLength,
605 BOOLEAN *PasswordFailed,
606 UINT8 *Msid,
607 UINT32 MsidLength
608 )
609 {
610 UINT8 MethodStatus;
611 TCG_RESULT Ret;
612 UINT32 RemovalTimeOut;
613
614 NULL_CHECK (Session);
615 NULL_CHECK (Msid);
616 NULL_CHECK (Password);
617 NULL_CHECK (PasswordFailed);
618
619 RemovalTimeOut = GetRevertTimeOut (Session);
620 DEBUG ((DEBUG_INFO, "OpalUtilRevert: Timeout value = %d\n", RemovalTimeOut));
621
622 Ret = OpalStartSession (
623 Session,
624 OPAL_UID_LOCKING_SP,
625 TRUE,
626 PasswordLength,
627 Password,
628 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
629 &MethodStatus
630 );
631
632 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
633 DEBUG ((DEBUG_INFO, "error starting session: Ret=%d, MethodStatus=%u\n", Ret, MethodStatus));
634 *PasswordFailed = TRUE;
635 goto done;
636 }
637
638 *PasswordFailed = FALSE;
639 //
640 // Try to revert with admin1
641 //
642 Ret = OpalPyrite2AdminRevert (Session, KeepUserData, &MethodStatus, RemovalTimeOut);
643 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
644 //
645 // Device ends the session on successful revert, so only call OpalEndSession when fail.
646 //
647 DEBUG ((DEBUG_INFO, "OpalAdminRevert as admin failed\n"));
648 OpalEndSession (Session);
649 }
650
651 Ret = OpalUtilSetSIDtoMSID (Session, Password, PasswordLength, Msid, MsidLength);
652
653 done:
654 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
655 Ret = TcgResultFailure;
656 }
657
658 return Ret;
659 }
660
661 /**
662 After revert success, set SID to MSID.
663
664 @param Session, The session info for one opal device.
665 @param Password, Input password info.
666 @param PasswordLength, Input password length.
667 @param Msid Msid info.
668 @param MsidLength Msid data length.
669
670 **/
671 TCG_RESULT
672 EFIAPI
673 OpalUtilSetSIDtoMSID (
674 OPAL_SESSION *Session,
675 const VOID *Password,
676 UINT32 PasswordLength,
677 UINT8 *Msid,
678 UINT32 MsidLength
679 )
680 {
681 TCG_RESULT Ret;
682 UINT8 MethodStatus;
683
684 NULL_CHECK (Session);
685 NULL_CHECK (Msid);
686 NULL_CHECK (Password);
687
688 //
689 // Start session with admin sp to update SID to MSID
690 //
691 Ret = OpalStartSession (
692 Session,
693 OPAL_UID_ADMIN_SP,
694 TRUE,
695 PasswordLength,
696 Password,
697 OPAL_ADMIN_SP_SID_AUTHORITY,
698 &MethodStatus
699 );
700 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
701 goto done;
702 }
703
704 //
705 // Update SID pin
706 //
707 Ret = OpalSetPassword (Session, OPAL_UID_ADMIN_SP_C_PIN_SID, Msid, MsidLength, &MethodStatus);
708 OpalEndSession (Session);
709
710 done:
711 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
712 Ret = TcgResultFailure;
713 }
714
715 return Ret;
716 }
717
718 /**
719 Update global locking range.
720
721 @param Session, The session info for one opal device.
722 @param Password, Input password info.
723 @param PasswordLength, Input password length.
724 @param ReadLocked, Read lock info.
725 @param WriteLocked write lock info.
726
727 **/
728 TCG_RESULT
729 EFIAPI
730 OpalUtilUpdateGlobalLockingRange (
731 OPAL_SESSION *Session,
732 const VOID *Password,
733 UINT32 PasswordLength,
734 BOOLEAN ReadLocked,
735 BOOLEAN WriteLocked
736 )
737 {
738 UINT8 MethodStatus;
739 TCG_RESULT Ret;
740
741 NULL_CHECK (Session);
742 NULL_CHECK (Password);
743
744 //
745 // Try to start session with Locking SP as admin1 authority
746 //
747 Ret = OpalStartSession (
748 Session,
749 OPAL_UID_LOCKING_SP,
750 TRUE,
751 PasswordLength,
752 Password,
753 OPAL_LOCKING_SP_ADMIN1_AUTHORITY,
754 &MethodStatus
755 );
756 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
757 Ret = OpalUpdateGlobalLockingRange (
758 Session,
759 ReadLocked,
760 WriteLocked,
761 &MethodStatus
762 );
763 OpalEndSession (Session);
764 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
765 goto done;
766 }
767 }
768
769 if (MethodStatus == TCG_METHOD_STATUS_CODE_AUTHORITY_LOCKED_OUT) {
770 DEBUG ((DEBUG_INFO, "unlock as admin failed with AUTHORITY_LOCKED_OUT\n"));
771 }
772
773 //
774 // Try user1 authority
775 //
776 Ret = OpalStartSession (
777 Session,
778 OPAL_UID_LOCKING_SP,
779 TRUE,
780 PasswordLength,
781 Password,
782 OPAL_LOCKING_SP_USER1_AUTHORITY,
783 &MethodStatus
784 );
785 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
786 DEBUG ((DEBUG_INFO, "StartSession with Locking SP as User1 failed\n"));
787 goto done;
788 }
789
790 Ret = OpalUpdateGlobalLockingRange (Session, ReadLocked, WriteLocked, &MethodStatus);
791 OpalEndSession (Session);
792
793 done:
794 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
795 if (MethodStatus == TCG_METHOD_STATUS_CODE_AUTHORITY_LOCKED_OUT) {
796 //
797 // Caller need to know this special error, but return status not has type for it.
798 // so here use TcgResultFailureInvalidType as an replacement.
799 //
800 Ret = TcgResultFailureInvalidType;
801 } else {
802 Ret = TcgResultFailure;
803 }
804 }
805
806 return Ret;
807 }
808
809 /**
810 Update global locking range.
811
812 @param Session, The session info for one opal device.
813 @param Msid, The data buffer to save Msid info.
814 @param MsidBufferLength, The data buffer length for Msid.
815 @param MsidLength, The actual data length for Msid.
816
817 **/
818 TCG_RESULT
819 EFIAPI
820 OpalUtilGetMsid (
821 OPAL_SESSION *Session,
822 UINT8 *Msid,
823 UINT32 MsidBufferLength,
824 UINT32 *MsidLength
825 )
826 {
827 UINT8 MethodStatus;
828 TCG_RESULT Ret;
829
830 NULL_CHECK (Session);
831 NULL_CHECK (Msid);
832 NULL_CHECK (MsidLength);
833
834 Ret = OpalStartSession (
835 Session,
836 OPAL_UID_ADMIN_SP,
837 TRUE,
838 0,
839 NULL,
840 TCG_UID_NULL,
841 &MethodStatus
842 );
843 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
844 Ret = OpalGetMsid (Session, MsidBufferLength, Msid, MsidLength);
845 OpalEndSession (Session);
846 }
847
848 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
849 Ret = TcgResultFailure;
850 }
851
852 return Ret;
853 }
854
855 /**
856
857 The function determines who owns the device by attempting to start a session with different credentials.
858 If the SID PIN matches the MSID PIN, the no one owns the device.
859 If the SID PIN matches the ourSidPin, then "Us" owns the device. Otherwise it is unknown.
860
861
862 @param[in] Session The session info for one opal device.
863 @param Msid, The Msid info.
864 @param MsidLength, The data length for Msid.
865
866 **/
867 OPAL_OWNER_SHIP
868 EFIAPI
869 OpalUtilDetermineOwnership (
870 OPAL_SESSION *Session,
871 UINT8 *Msid,
872 UINT32 MsidLength
873 )
874 {
875 UINT8 MethodStatus;
876 TCG_RESULT Ret;
877 OPAL_OWNER_SHIP Owner;
878
879 if ((Session == NULL) || (Msid == NULL)) {
880 return OpalOwnershipUnknown;
881 }
882
883 Owner = OpalOwnershipUnknown;
884 //
885 // Start Session as SID_UID with ADMIN_SP using MSID PIN
886 //
887 Ret = OpalStartSession (
888 Session,
889 OPAL_UID_ADMIN_SP,
890 TRUE,
891 MsidLength,
892 Msid,
893 OPAL_ADMIN_SP_SID_AUTHORITY,
894 &MethodStatus
895 );
896 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) {
897 //
898 // now we know that SID PIN == MSID PIN
899 //
900 Owner = OpalOwnershipNobody;
901
902 OpalEndSession (Session);
903 }
904
905 return Owner;
906 }
907
908 /**
909
910 The function returns if admin password exists.
911
912 @param[in] OwnerShip The owner ship of the opal device.
913 @param[in] LockingFeature The locking info of the opal device.
914
915 @retval TRUE Admin password existed.
916 @retval FALSE Admin password not existed.
917
918 **/
919 BOOLEAN
920 EFIAPI
921 OpalUtilAdminPasswordExists (
922 IN UINT16 OwnerShip,
923 IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature
924 )
925 {
926 NULL_CHECK (LockingFeature);
927
928 // if it is Unknown who owns the device
929 // then someone has set password previously through our UI
930 // because the SID would no longer match the generated SID (ownership us)
931 // or someone has set password using 3rd party software
932
933 //
934 // Locking sp enabled is checked b/c it must be enabled to change the PIN of the Admin1.
935 //
936 return (OwnerShip == OpalOwnershipUnknown && LockingFeature->LockingEnabled);
937 }
938
939 /**
940 Get Active Data Removal Mechanism Value.
941
942 @param[in] Session The session info for one opal device.
943 @param[in] GeneratedSid Generated SID of disk
944 @param[in] SidLength Length of generatedSid in bytes
945 @param[out] ActiveDataRemovalMechanism Return the active data removal mechanism.
946
947 **/
948 TCG_RESULT
949 EFIAPI
950 OpalUtilGetActiveDataRemovalMechanism (
951 OPAL_SESSION *Session,
952 const VOID *GeneratedSid,
953 UINT32 SidLength,
954 UINT8 *ActiveDataRemovalMechanism
955 )
956 {
957 TCG_RESULT Ret;
958 UINT8 MethodStatus;
959
960 NULL_CHECK (Session);
961 NULL_CHECK (GeneratedSid);
962 NULL_CHECK (ActiveDataRemovalMechanism);
963
964 Ret = OpalStartSession (
965 Session,
966 OPAL_UID_ADMIN_SP,
967 TRUE,
968 SidLength,
969 GeneratedSid,
970 OPAL_ADMIN_SP_ANYBODY_AUTHORITY,
971 &MethodStatus
972 );
973 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) {
974 DEBUG ((DEBUG_INFO, "Start session with admin SP as SID authority failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));
975 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {
976 Ret = TcgResultFailure;
977 }
978
979 return Ret;
980 }
981
982 Ret = OpalPyrite2GetActiveDataRemovalMechanism (
983 Session,
984 ActiveDataRemovalMechanism
985 );
986
987 if (Ret != TcgResultSuccess) {
988 DEBUG ((DEBUG_INFO, "Pyrite2 Get Active Data Removal Mechanism failed: Ret=%d\n", Ret));
989 }
990
991 OpalEndSession (Session);
992
993 return Ret;
994 }
995
996 /**
997 Calculate the estimated time.
998
999 @param[in] IsMinute Whether the input time value is minute type or second type.
1000 @param[in] Time The input time value.
1001
1002 **/
1003 UINT32
1004 CalculateDataRemovalTime (
1005 IN BOOLEAN IsMinute,
1006 IN UINT16 Time
1007 )
1008 {
1009 if (IsMinute) {
1010 return Time * 2 * 60;
1011 } else {
1012 return Time * 2;
1013 }
1014 }
1015
1016 /**
1017 Return the estimated time for specific type.
1018
1019 @param[in] Index The input data removal type.
1020 @param[in] Descriptor DATA_REMOVAL_FEATURE_DESCRIPTOR
1021
1022 **/
1023 UINT32
1024 GetDataRemovalTime (
1025 IN UINT8 Index,
1026 IN DATA_REMOVAL_FEATURE_DESCRIPTOR *Descriptor
1027 )
1028 {
1029 switch (Index) {
1030 case OverwriteDataErase:
1031 return CalculateDataRemovalTime (Descriptor->FormatBit0, SwapBytes16 (Descriptor->TimeBit0));
1032
1033 case BlockErase:
1034 return CalculateDataRemovalTime (Descriptor->FormatBit1, SwapBytes16 (Descriptor->TimeBit1));
1035
1036 case CryptoErase:
1037 return CalculateDataRemovalTime (Descriptor->FormatBit2, SwapBytes16 (Descriptor->TimeBit2));
1038
1039 case Unmap:
1040 return CalculateDataRemovalTime (Descriptor->FormatBit3, SwapBytes16 (Descriptor->TimeBit3));
1041
1042 case ResetWritePointers:
1043 return CalculateDataRemovalTime (Descriptor->FormatBit4, SwapBytes16 (Descriptor->TimeBit4));
1044
1045 case VendorSpecificErase:
1046 return CalculateDataRemovalTime (Descriptor->FormatBit5, SwapBytes16 (Descriptor->TimeBit5));
1047
1048 default:
1049 return 0;
1050 }
1051 }
1052
1053 /**
1054 Get the supported Data Removal Mechanism list.
1055
1056 @param[in] Session The session info for one opal device.
1057 @param[out] RemovalMechanismLists Return the supported data removal mechanism lists.
1058
1059 **/
1060 TCG_RESULT
1061 EFIAPI
1062 OpalUtilGetDataRemovalMechanismLists (
1063 IN OPAL_SESSION *Session,
1064 OUT UINT32 *RemovalMechanismLists
1065 )
1066 {
1067 TCG_RESULT Ret;
1068 UINTN DataSize;
1069 DATA_REMOVAL_FEATURE_DESCRIPTOR Descriptor;
1070 UINT8 Index;
1071 UINT8 BitValue;
1072
1073 NULL_CHECK (Session);
1074 NULL_CHECK (RemovalMechanismLists);
1075
1076 DataSize = sizeof (Descriptor);
1077 Ret = OpalGetFeatureDescriptor (Session, TCG_FEATURE_DATA_REMOVAL, &DataSize, &Descriptor);
1078 if (Ret != TcgResultSuccess) {
1079 return TcgResultFailure;
1080 }
1081
1082 ASSERT (Descriptor.RemovalMechanism != 0);
1083
1084 for (Index = 0; Index < ResearvedMechanism; Index++) {
1085 BitValue = (BOOLEAN)BitFieldRead8 (Descriptor.RemovalMechanism, Index, Index);
1086
1087 if (BitValue == 0) {
1088 RemovalMechanismLists[Index] = 0;
1089 } else {
1090 RemovalMechanismLists[Index] = GetDataRemovalTime (Index, &Descriptor);
1091 }
1092 }
1093
1094 return TcgResultSuccess;
1095 }
1096
1097 /**
1098 Get revert timeout value.
1099
1100 @param[in] Session The session info for one opal device.
1101
1102 **/
1103 UINT32
1104 GetRevertTimeOut (
1105 IN OPAL_SESSION *Session
1106 )
1107 {
1108 TCG_RESULT TcgResult;
1109 OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes;
1110 UINT16 BaseComId;
1111 UINT32 MsidLength;
1112 UINT8 Msid[OPAL_MSID_LENGTH];
1113 UINT32 RemovalMechanishLists[ResearvedMechanism];
1114 UINT8 ActiveDataRemovalMechanism;
1115
1116 TcgResult = OpalGetSupportedAttributesInfo (Session, &SupportedAttributes, &BaseComId);
1117 if ((TcgResult != TcgResultSuccess) || (SupportedAttributes.DataRemoval == 0)) {
1118 return 0;
1119 }
1120
1121 TcgResult = OpalUtilGetMsid (Session, Msid, OPAL_MSID_LENGTH, &MsidLength);
1122 if (TcgResult != TcgResultSuccess) {
1123 return 0;
1124 }
1125
1126 TcgResult = OpalUtilGetDataRemovalMechanismLists (Session, RemovalMechanishLists);
1127 if (TcgResult != TcgResultSuccess) {
1128 return 0;
1129 }
1130
1131 TcgResult = OpalUtilGetActiveDataRemovalMechanism (Session, Msid, MsidLength, &ActiveDataRemovalMechanism);
1132 if (TcgResult != TcgResultSuccess) {
1133 return 0;
1134 }
1135
1136 return RemovalMechanishLists[ActiveDataRemovalMechanism];
1137 }