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