]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c
ArmPkg/ArmMmuLib ARM: fix thinko in second level page table handling
[mirror_edk2.git] / SecurityPkg / Library / TcgStorageOpalLib / TcgStorageOpalCore.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
9dd05dde
ED
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
59ed6433 15#include <Uefi.h>\r
9dd05dde
ED
16#include <Library/BaseLib.h>\r
17#include <Library/TimerLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/TcgStorageOpalLib.h>\r
21\r
a3068f06
ED
22#include "TcgStorageOpalLibInternal.h"\r
23\r
9dd05dde
ED
24#pragma pack(1)\r
25typedef struct {\r
26 UINT8 HardwareReset : 1;\r
27 UINT8 Reserved : 7;\r
28} TCG_BLOCK_SID_CLEAR_EVENTS;\r
29#pragma pack()\r
30\r
31#define TRUSTED_COMMAND_TIMEOUT_NS ((UINT64) 5 * ((UINT64)(1000000)) * 1000) // 5 seconds\r
32#define BUFFER_SIZE 512\r
33\r
34/**\r
35 The function performs a Trusted Send of a Buffer containing a TCG_COM_PACKET.\r
36\r
37 @param[in] Sscp The input Ssc Protocol.\r
38 @param[in] MediaId The input Media id info used by Ssc Protocol.\r
39 @param[in] SecurityProtocol Security Protocol\r
40 @param[in] SpSpecific Security Protocol Specific\r
41 @param[in] TransferLength Transfer Length of Buffer (in bytes) - always a multiple of 512\r
42 @param[in] Buffer Address of Data to transfer\r
43 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
44\r
45**/\r
46TCG_RESULT\r
47OpalTrustedSend(\r
48 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp,\r
49 UINT32 MediaId,\r
50 UINT8 SecurityProtocol,\r
51 UINT16 SpSpecific,\r
52 UINTN TransferLength,\r
53 VOID *Buffer,\r
54 UINTN BufferSize\r
55 )\r
56{\r
57 UINTN TransferLength512;\r
58 EFI_STATUS Status;\r
59\r
60 //\r
61 // Round transferLength up to a 512-byte multiple\r
62 //\r
63 TransferLength512 = (TransferLength + 511) & ~(UINTN)511;\r
64\r
65 if (TransferLength512 > BufferSize) {\r
66 return TcgResultFailureBufferTooSmall;\r
67 }\r
68\r
69 ZeroMem((UINT8*)Buffer + TransferLength, TransferLength512 - TransferLength);\r
70\r
71 Status = Sscp->SendData(\r
72 Sscp,\r
73 MediaId,\r
74 TRUSTED_COMMAND_TIMEOUT_NS,\r
75 SecurityProtocol,\r
76 SwapBytes16(SpSpecific),\r
77 TransferLength512,\r
78 Buffer\r
79 );\r
80\r
81 return Status == EFI_SUCCESS ? TcgResultSuccess : TcgResultFailure;\r
82}\r
83\r
84/**\r
85\r
86 The function performs a Trusted Receive of a Buffer containing a TCG_COM_PACKET.\r
87\r
88 @param[in] Sscp The input Ssc Protocol.\r
89 @param[in] MediaId The input Media id info used by Ssc Protocol.\r
90 @param[in] SecurityProtocol Security Protocol\r
91 @param[in] SpSpecific Security Protocol Specific\r
92 @param[in] Buffer Address of Data to transfer\r
93 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
a3068f06 94 @param[in] EstimateTimeCost Estimate the time needed.\r
9dd05dde
ED
95\r
96**/\r
97TCG_RESULT\r
98OpalTrustedRecv(\r
99 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp,\r
100 UINT32 MediaId,\r
101 UINT8 SecurityProtocol,\r
102 UINT16 SpSpecific,\r
103 VOID *Buffer,\r
a3068f06
ED
104 UINTN BufferSize,\r
105 UINT32 EstimateTimeCost\r
9dd05dde
ED
106 )\r
107{\r
9dd05dde
ED
108 UINTN TransferLength512;\r
109 UINT32 Tries;\r
110 TCG_COM_PACKET *ComPacket;\r
111 UINT32 Length;\r
112 UINT32 OutstandingData;\r
113 EFI_STATUS Status;\r
114 UINTN TransferSize;\r
115\r
116 //\r
117 // Round Buffer Size down to a 512-byte multiple\r
118 //\r
119 TransferLength512 = BufferSize & ~(UINTN)511;\r
120 Tries = 0;\r
121 ComPacket = NULL;\r
122 Length = 0;\r
123 OutstandingData = 0;\r
124\r
125 if (TransferLength512 < sizeof(TCG_COM_PACKET)) {\r
126 DEBUG ((DEBUG_INFO, "transferLength %u too small for ComPacket\n", TransferLength512));\r
127 return TcgResultFailureBufferTooSmall;\r
128 }\r
129\r
130 //\r
131 // Some devices respond with Length = 0 and OutstandingData = 1 to indicate that processing is not yet completed,\r
132 // so we need to retry the IF-RECV to get the actual Data.\r
133 // See TCG Core Spec v2 Table 45 IF-RECV ComPacket Field Values Summary\r
134 // This is an arbitrary number of retries, not from the spec.\r
9dd05dde 135 //\r
a3068f06
ED
136 // if user input estimate time cost(second level) value bigger than 10s, base on user input value to wait.\r
137 // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms = 10s\r
138 //\r
139 if (EstimateTimeCost > 10) {\r
140 Tries = EstimateTimeCost * 500; // 500 = 1000 * 1000 / 2000;\r
141 } else {\r
142 Tries = 5000;\r
143 }\r
9dd05dde
ED
144 while ((Tries--) > 0) {\r
145 ZeroMem( Buffer, BufferSize );\r
146 TransferSize = 0;\r
147\r
148 Status = Sscp->ReceiveData(\r
149 Sscp,\r
150 MediaId,\r
151 TRUSTED_COMMAND_TIMEOUT_NS,\r
152 SecurityProtocol,\r
153 SwapBytes16(SpSpecific),\r
154 TransferLength512,\r
155 Buffer,\r
156 &TransferSize\r
157 );\r
9dd05dde
ED
158 if (EFI_ERROR (Status)) {\r
159 return TcgResultFailure;\r
160 }\r
161\r
162 if (SecurityProtocol != TCG_OPAL_SECURITY_PROTOCOL_1 && SecurityProtocol != TCG_OPAL_SECURITY_PROTOCOL_2) {\r
163 return TcgResultSuccess;\r
164 }\r
165\r
166 if (SpSpecific == TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY) {\r
167 return TcgResultSuccess;\r
168 }\r
169\r
170 ComPacket = (TCG_COM_PACKET*) Buffer;\r
171 Length = SwapBytes32(ComPacket->LengthBE);\r
172 OutstandingData = SwapBytes32( ComPacket->OutstandingDataBE );\r
173\r
174 if (Length != 0 && OutstandingData == 0) {\r
175 return TcgResultSuccess;\r
176 }\r
177\r
178 //\r
179 // Delay for 2 ms\r
180 //\r
181 MicroSecondDelay (2000);\r
182 }\r
183\r
184 return TcgResultFailure;\r
185}\r
186\r
187/**\r
188 The function performs send, recv, check comIDs, check method status action.\r
189\r
a3068f06
ED
190 @param[in] Session OPAL_SESSION related to this method..\r
191 @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512\r
192 @param[in] Buffer Address of Data to transfer\r
193 @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
194 @param[in] ParseStruct Structure used to parse received TCG response.\r
195 @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
196 @param[in] EstimateTimeCost Estimate the time need to for the method.\r
9dd05dde
ED
197**/\r
198TCG_RESULT\r
199EFIAPI\r
a3068f06 200OpalPerformMethod (\r
9dd05dde
ED
201 OPAL_SESSION *Session,\r
202 UINT32 SendSize,\r
203 VOID *Buffer,\r
204 UINT32 BufferSize,\r
205 TCG_PARSE_STRUCT *ParseStruct,\r
a3068f06
ED
206 UINT8 *MethodStatus,\r
207 UINT32 EstimateTimeCost\r
9dd05dde
ED
208 )\r
209{\r
210 NULL_CHECK(Session);\r
211 NULL_CHECK(MethodStatus);\r
212\r
213 ERROR_CHECK(OpalTrustedSend(\r
214 Session->Sscp,\r
215 Session->MediaId,\r
216 TCG_OPAL_SECURITY_PROTOCOL_1,\r
217 Session->OpalBaseComId,\r
218 SendSize,\r
219 Buffer,\r
220 BufferSize\r
221 ));\r
222\r
223 ERROR_CHECK(OpalTrustedRecv(\r
224 Session->Sscp,\r
225 Session->MediaId,\r
226 TCG_OPAL_SECURITY_PROTOCOL_1,\r
227 Session->OpalBaseComId,\r
228 Buffer,\r
a3068f06
ED
229 BufferSize,\r
230 EstimateTimeCost\r
9dd05dde
ED
231 ));\r
232\r
233 ERROR_CHECK(TcgInitTcgParseStruct(ParseStruct, Buffer, BufferSize));\r
234 ERROR_CHECK(TcgCheckComIds(ParseStruct, Session->OpalBaseComId, Session->ComIdExtension));\r
235 ERROR_CHECK(TcgGetMethodStatus(ParseStruct, MethodStatus));\r
236\r
237 return TcgResultSuccess;\r
238}\r
239\r
240/**\r
241 Trig the block sid action.\r
242\r
243 @param[in] Session OPAL_SESSION related to this method..\r
244 @param[in] HardwareReset Whether need to do hardware reset.\r
245\r
246**/\r
247TCG_RESULT\r
248EFIAPI\r
249OpalBlockSid(\r
250 OPAL_SESSION *Session,\r
251 BOOLEAN HardwareReset\r
252 )\r
253{\r
254 UINT8 Buffer[BUFFER_SIZE];\r
255 TCG_BLOCK_SID_CLEAR_EVENTS *ClearEvents;\r
256\r
257 NULL_CHECK(Session);\r
258\r
259 //\r
260 // Set Hardware Reset bit\r
261 //\r
262 ClearEvents = (TCG_BLOCK_SID_CLEAR_EVENTS *) &Buffer[0];\r
263\r
264 ClearEvents->Reserved = 0;\r
265 ClearEvents->HardwareReset = HardwareReset;\r
266\r
267 return(OpalTrustedSend(\r
268 Session->Sscp,\r
269 Session->MediaId,\r
270 TCG_OPAL_SECURITY_PROTOCOL_2,\r
81c1b6df 271 TCG_BLOCKSID_COMID, // hardcode ComID 0x0005\r
9dd05dde
ED
272 1,\r
273 Buffer,\r
274 BUFFER_SIZE\r
275 ));\r
276}\r
277\r
278/**\r
279\r
280 Reverts device using Admin SP Revert method.\r
281\r
282 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.\r
283\r
284**/\r
285TCG_RESULT\r
286EFIAPI\r
287OpalPsidRevert(\r
288 OPAL_SESSION *AdminSpSession\r
289 )\r
290{\r
291 //\r
292 // Now that base comid is known, start Session\r
293 // we'll attempt to start Session as PSID authority\r
294 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?\r
295 //\r
296 TCG_CREATE_STRUCT CreateStruct;\r
297 TCG_PARSE_STRUCT ParseStruct;\r
298 UINT32 Size;\r
299 UINT8 Buffer[BUFFER_SIZE];\r
300 UINT8 MethodStatus;\r
301\r
302 NULL_CHECK(AdminSpSession);\r
303\r
304 //\r
305 // Send Revert action on Admin SP\r
306 //\r
307 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
308 ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
309 ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
310 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
311 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_ADMIN_SP_REVERT_METHOD));\r
312 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
313 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
314 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
315 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
316 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
317 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
318\r
319 //\r
320 // Send Revert Method Call\r
321 //\r
a3068f06
ED
322 ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
323 METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
324\r
325 return TcgResultSuccess;\r
326}\r
327\r
328/**\r
329\r
330 Reverts device using Admin SP Revert method.\r
331\r
332 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.\r
333 @param[in] EstimateTimeCost Estimate the time needed.\r
334\r
335**/\r
336TCG_RESULT\r
a3068f06
ED
337OpalPyrite2PsidRevert(\r
338 OPAL_SESSION *AdminSpSession,\r
339 UINT32 EstimateTimeCost\r
340 )\r
341{\r
342 //\r
343 // Now that base comid is known, start Session\r
344 // we'll attempt to start Session as PSID authority\r
345 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?\r
346 //\r
347 TCG_CREATE_STRUCT CreateStruct;\r
348 TCG_PARSE_STRUCT ParseStruct;\r
349 UINT32 Size;\r
350 UINT8 Buffer[BUFFER_SIZE];\r
351 UINT8 MethodStatus;\r
352\r
353\r
354 NULL_CHECK(AdminSpSession);\r
355\r
356 //\r
357 // Send Revert action on Admin SP\r
358 //\r
359 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
360 ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
361 ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
362 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
363 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_ADMIN_SP_REVERT_METHOD));\r
364 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
365 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
366 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
367 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
368 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
369 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
370\r
371 //\r
372 // Send Revert Method Call\r
373 //\r
374 ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, EstimateTimeCost));\r
9dd05dde
ED
375 METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
376\r
377 return TcgResultSuccess;\r
378}\r
379\r
380/**\r
381\r
382 The function fills in the provided Buffer with the level 0 discovery Header\r
383 of the device specified.\r
384\r
385 @param[in] Session OPAL_SESSION data.\r
386 @param[in] BufferSize Size of Buffer provided (in bytes)\r
387 @param[in] BuffAddress Buffer address to fill with Level 0 Discovery response\r
388\r
389**/\r
390TCG_RESULT\r
391EFIAPI\r
392OpalRetrieveLevel0DiscoveryHeader(\r
393 OPAL_SESSION *Session,\r
394 UINTN BufferSize,\r
395 VOID *BuffAddress\r
396 )\r
397{\r
398 return (OpalTrustedRecv(\r
399 Session->Sscp,\r
400 Session->MediaId,\r
401 TCG_OPAL_SECURITY_PROTOCOL_1, // SP\r
402 TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY, // SP_Specific\r
403 BuffAddress,\r
a3068f06
ED
404 BufferSize,\r
405 0\r
9dd05dde
ED
406 ));\r
407}\r
408\r
409/**\r
410\r
411 The function fills in the provided Buffer with the supported protocol list\r
412 of the device specified.\r
413\r
414 @param[in] Session OPAL_SESSION data.\r
415 @param[in] BufferSize Size of Buffer provided (in bytes)\r
416 @param[in] BuffAddress Buffer address to fill with security protocol list\r
417\r
418**/\r
419TCG_RESULT\r
420EFIAPI\r
421OpalRetrieveSupportedProtocolList(\r
422 OPAL_SESSION *Session,\r
423 UINTN BufferSize,\r
424 VOID *BuffAddress\r
425 )\r
426{\r
427 return (OpalTrustedRecv(\r
428 Session->Sscp,\r
429 Session->MediaId,\r
430 TCG_SECURITY_PROTOCOL_INFO, // SP\r
431 TCG_SP_SPECIFIC_PROTOCOL_LIST, // SP_Specific\r
432 BuffAddress,\r
a3068f06
ED
433 BufferSize,\r
434 0\r
9dd05dde
ED
435 ));\r
436}\r
437\r
438/**\r
439 Starts a session with a security provider (SP).\r
440\r
441 If a session is started successfully, the caller must end the session with OpalEndSession when finished\r
442 performing Opal actions.\r
443\r
444 @param[in/out] Session OPAL_SESSION to initialize.\r
445 @param[in] SpId Security provider ID to start the session with.\r
446 @param[in] Write Whether the session should be read-only (FALSE) or read/write (TRUE).\r
447 @param[in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL\r
448 @param[in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge will be sent.\r
449 @param[in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority will be sent.\r
450 @param[in/out] MethodStatus Status of the StartSession method; only valid if TcgResultSuccess is returned.\r
451\r
452 @return TcgResultSuccess indicates that the function completed without any internal errors.\r
453 The caller must inspect the MethodStatus field to determine whether the method completed successfully.\r
454\r
455**/\r
456TCG_RESULT\r
457EFIAPI\r
458OpalStartSession(\r
459 OPAL_SESSION *Session,\r
460 TCG_UID SpId,\r
461 BOOLEAN Write,\r
462 UINT32 HostChallengeLength,\r
463 const VOID *HostChallenge,\r
464 TCG_UID HostSigningAuthority,\r
465 UINT8 *MethodStatus\r
466 )\r
467{\r
468 TCG_CREATE_STRUCT CreateStruct;\r
469 TCG_PARSE_STRUCT ParseStruct;\r
470 UINT32 Size;\r
471 UINT8 Buf[BUFFER_SIZE];\r
472 UINT16 ComIdExtension;\r
473 UINT32 HostSessionId;\r
474\r
475 ComIdExtension = 0;\r
476 HostSessionId = 1;\r
477\r
478 NULL_CHECK(Session);\r
479 NULL_CHECK(MethodStatus);\r
480\r
481 Session->ComIdExtension = ComIdExtension;\r
482 Session->HostSessionId = HostSessionId;\r
483\r
484 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
485 ERROR_CHECK(TcgCreateStartSession(\r
486 &CreateStruct,\r
487 &Size,\r
488 Session->OpalBaseComId,\r
489 ComIdExtension,\r
490 HostSessionId,\r
491 SpId,\r
492 Write,\r
493 HostChallengeLength,\r
494 HostChallenge,\r
495 HostSigningAuthority\r
496 ));\r
a3068f06 497 ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
498 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
499 return TcgResultSuccess; // return early if method failed - user must check MethodStatus\r
500 }\r
501\r
502 if (TcgParseSyncSession(&ParseStruct, Session->OpalBaseComId, ComIdExtension, HostSessionId, &Session->TperSessionId) != TcgResultSuccess) {\r
503 OpalEndSession(Session);\r
504 return TcgResultFailure;\r
505 }\r
506\r
507 return TcgResultSuccess;\r
508}\r
509\r
510/**\r
511 Close a session opened with OpalStartSession.\r
512\r
513 @param[in/out] Session OPAL_SESSION to end.\r
514\r
515**/\r
516TCG_RESULT\r
517EFIAPI\r
518OpalEndSession(\r
519 OPAL_SESSION *Session\r
520 )\r
521{\r
522 UINT8 Buffer[BUFFER_SIZE];\r
523 TCG_CREATE_STRUCT CreateStruct;\r
524 UINT32 Size;\r
525 TCG_PARSE_STRUCT ParseStruct;\r
526\r
527 NULL_CHECK(Session);\r
528 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, sizeof(Buffer)));\r
529 ERROR_CHECK(TcgCreateEndSession(\r
530 &CreateStruct,\r
531 &Size,\r
532 Session->OpalBaseComId,\r
533 Session->ComIdExtension,\r
534 Session->HostSessionId,\r
535 Session->TperSessionId\r
536 ));\r
537\r
538 ERROR_CHECK(OpalTrustedSend(\r
539 Session->Sscp,\r
540 Session->MediaId,\r
541 TCG_OPAL_SECURITY_PROTOCOL_1,\r
542 Session->OpalBaseComId,\r
543 Size,\r
544 Buffer,\r
545 sizeof(Buffer)\r
546 ));\r
547\r
548 ERROR_CHECK(OpalTrustedRecv(\r
549 Session->Sscp,\r
550 Session->MediaId,\r
551 TCG_OPAL_SECURITY_PROTOCOL_1,\r
552 Session->OpalBaseComId,\r
553 Buffer,\r
a3068f06
ED
554 sizeof(Buffer),\r
555 0\r
9dd05dde
ED
556 ));\r
557\r
558 ERROR_CHECK(TcgInitTcgParseStruct(&ParseStruct, Buffer, sizeof(Buffer)));\r
559 ERROR_CHECK(TcgCheckComIds(&ParseStruct, Session->OpalBaseComId, Session->ComIdExtension));\r
560\r
561 ERROR_CHECK(TcgGetNextEndOfSession(&ParseStruct));\r
562 return TcgResultSuccess;\r
563}\r
564\r
565/**\r
566\r
567 The function retrieves the MSID from the device specified\r
568\r
569 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.\r
570 @param[in] MsidBufferSize Allocated Buffer Size (in bytes) for MSID allocated by caller\r
571 @param[in] Msid Variable Length byte sequence representing MSID of device\r
572 @param[in] MsidLength Actual Length of MSID retrieved from device\r
573\r
574**/\r
575TCG_RESULT\r
576EFIAPI\r
577OpalGetMsid(\r
578 OPAL_SESSION *AdminSpSession,\r
579 UINT32 MsidBufferSize,\r
580 UINT8 *Msid,\r
581 UINT32 *MsidLength\r
582 )\r
583{\r
584 //\r
585 // now that base comid is known, start Session\r
586 // we'll attempt to start Session as PSID authority\r
587 // verify PSID Authority is defined in ADMIN SP authority table... is this possible?\r
588 //\r
589 TCG_CREATE_STRUCT CreateStruct;\r
590 TCG_PARSE_STRUCT ParseStruct;\r
591 UINT32 Size;\r
592 UINT8 MethodStatus;\r
593 UINT32 Col;\r
594 const VOID *RecvMsid;\r
595 UINT8 Buffer[BUFFER_SIZE];\r
596\r
597 NULL_CHECK(AdminSpSession);\r
598 NULL_CHECK(Msid);\r
599 NULL_CHECK(MsidLength);\r
600\r
601 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
602 ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
603 ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
604 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
605 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP_C_PIN_MSID, TCG_UID_METHOD_GET));\r
606 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
607 ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
608 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
609 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));\r
610 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_PIN_COL));\r
611 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
612 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
613 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));\r
614 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_PIN_COL));\r
615 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
616 ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
617 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
618 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
619 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
620 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
621 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
622\r
623 //\r
624 // Send MSID Method Call\r
625 //\r
a3068f06 626 ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
9dd05dde
ED
627 METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
628\r
629 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
630 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
631 ERROR_CHECK(TcgGetNextStartName(&ParseStruct));\r
632 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, &Col));\r
633 ERROR_CHECK(TcgGetNextByteSequence(&ParseStruct, &RecvMsid, MsidLength));\r
634 ERROR_CHECK(TcgGetNextEndName(&ParseStruct));\r
635 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
636 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
637 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct));\r
638\r
639 if (Col != OPAL_ADMIN_SP_PIN_COL) {\r
640 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMIN_SP_PIN_COL));\r
641 return TcgResultFailure;\r
642 }\r
643\r
644 if (RecvMsid == NULL) {\r
645 return TcgResultFailure;\r
646 }\r
647\r
648 if (MsidBufferSize < *MsidLength) {\r
649 DEBUG ((DEBUG_INFO, "Buffer too small MsidBufferSize: %d MsidLength: %d\n", MsidBufferSize, *MsidLength));\r
650 return TcgResultFailureBufferTooSmall;\r
651 }\r
652\r
653 //\r
654 // copy msid into Buffer\r
655 //\r
656 CopyMem(Msid, RecvMsid, *MsidLength);\r
657 return TcgResultSuccess;\r
658}\r
659\r
a3068f06
ED
660/**\r
661\r
662 The function retrieves the MSID from the device specified\r
663\r
664 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY\r
665 @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism that the device will use for Revert/RevertSP calls.\r
666\r
667**/\r
668TCG_RESULT\r
a3068f06
ED
669OpalPyrite2GetActiveDataRemovalMechanism (\r
670 IN OPAL_SESSION *AdminSpSession,\r
671 OUT UINT8 *ActiveDataRemovalMechanism\r
672 )\r
673{\r
674 TCG_CREATE_STRUCT CreateStruct;\r
675 TCG_PARSE_STRUCT ParseStruct;\r
676 UINT32 Size;\r
677 UINT8 MethodStatus;\r
678 UINT32 Col;\r
679 UINT8 RecvActiveDataRemovalMechanism;\r
680 UINT8 Buffer[BUFFER_SIZE];\r
681\r
682 NULL_CHECK(AdminSpSession);\r
683 NULL_CHECK(ActiveDataRemovalMechanism);\r
684\r
685 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
686 ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
687 ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
688 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
689 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP_DATA_REMOVAL_MECHANISM, TCG_UID_METHOD_GET));\r
690 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
691 ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
692 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
693 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));\r
694 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
695 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
696 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
697 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));\r
698 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
699 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
700 ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
701 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
702 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
703 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
704 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
705 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
706\r
707 //\r
708 // Send Get Active Data Removal Mechanism Method Call\r
709 //\r
710 ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
711 METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
712\r
713 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
714 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
715 ERROR_CHECK(TcgGetNextStartName(&ParseStruct));\r
716 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, &Col));\r
717 ERROR_CHECK(TcgGetNextUINT8(&ParseStruct, &RecvActiveDataRemovalMechanism));\r
718 ERROR_CHECK(TcgGetNextEndName(&ParseStruct));\r
719 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
720 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
721 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct));\r
722\r
723 if (Col != OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL) {\r
724 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
725 return TcgResultFailure;\r
726 }\r
727\r
728 if (RecvActiveDataRemovalMechanism >= ResearvedMechanism) {\r
729 return TcgResultFailure;\r
730 }\r
731\r
732 //\r
733 // Copy active data removal mechanism into Buffer\r
734 //\r
735 CopyMem(ActiveDataRemovalMechanism, &RecvActiveDataRemovalMechanism, sizeof(RecvActiveDataRemovalMechanism));\r
736 return TcgResultSuccess;\r
737}\r
738\r
9dd05dde
ED
739/**\r
740\r
741 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter\r
742 to keep the user Data is set to True, otherwise the optional parameter is not provided.\r
743\r
744 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP\r
745 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.\r
746 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
747\r
748**/\r
749TCG_RESULT\r
750EFIAPI\r
751OpalAdminRevert(\r
752 OPAL_SESSION *LockingSpSession,\r
753 BOOLEAN KeepUserData,\r
754 UINT8 *MethodStatus\r
755 )\r
756{\r
757 UINT8 Buf[BUFFER_SIZE];\r
758 TCG_CREATE_STRUCT CreateStruct;\r
759 UINT32 Size;\r
760 TCG_PARSE_STRUCT ParseStruct;\r
761 TCG_RESULT Ret;\r
762\r
763 NULL_CHECK(LockingSpSession);\r
764 NULL_CHECK(MethodStatus);\r
765\r
766 //\r
767 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data\r
768 //\r
769 if (KeepUserData) {\r
770 //\r
771 // set readlocked and writelocked to false\r
772 //\r
773 Ret = OpalUpdateGlobalLockingRange(\r
774 LockingSpSession,\r
775 FALSE,\r
776 FALSE,\r
777 MethodStatus);\r
778\r
779 if (Ret != TcgResultSuccess || *MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
780 //\r
781 // bail out\r
782 //\r
783 return Ret;\r
784 }\r
785 }\r
786\r
787 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
788 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
789 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
790 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
791 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCKING_SP_REVERTSP_METHOD));\r
792 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
793\r
794 if (KeepUserData) {\r
795 //\r
796 // optional parameter to keep Data after revert\r
797 //\r
798 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
799 ERROR_CHECK(TcgAddUINT32(&CreateStruct, 0x060000)); // weird Value but that's what spec says\r
800 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, KeepUserData));\r
801 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
802 }\r
803\r
804 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
805 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
806 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
807 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
808 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
809\r
810 //\r
811 // Send RevertSP method call\r
812 //\r
a3068f06
ED
813 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
814\r
815 //\r
816 // Session is immediately ended by device after successful revertsp, so no need to end Session\r
817 //\r
818 if (*MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {\r
819 //\r
820 // Caller should take ownership again\r
821 //\r
822 return TcgResultSuccess;\r
823 } else {\r
824 //\r
825 // End Session\r
826 //\r
827 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus\r
828 }\r
829\r
830 return TcgResultSuccess;\r
831}\r
832\r
833\r
834/**\r
835\r
836 The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter\r
837 to keep the user Data is set to True, otherwise the optional parameter is not provided.\r
838\r
839 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP\r
840 @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.\r
841 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
842 @param[in] EstimateTimeCost Estimate the time needed.\r
843\r
844**/\r
845TCG_RESULT\r
a3068f06
ED
846OpalPyrite2AdminRevert(\r
847 OPAL_SESSION *LockingSpSession,\r
848 BOOLEAN KeepUserData,\r
849 UINT8 *MethodStatus,\r
850 UINT32 EstimateTimeCost\r
851 )\r
852{\r
853 UINT8 Buf[BUFFER_SIZE];\r
854 TCG_CREATE_STRUCT CreateStruct;\r
855 UINT32 Size;\r
856 TCG_PARSE_STRUCT ParseStruct;\r
857 TCG_RESULT Ret;\r
858\r
859 NULL_CHECK(LockingSpSession);\r
860 NULL_CHECK(MethodStatus);\r
861\r
862 //\r
863 // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data\r
864 //\r
865 if (KeepUserData) {\r
866 //\r
867 // set readlocked and writelocked to false\r
868 //\r
869 Ret = OpalUpdateGlobalLockingRange(\r
870 LockingSpSession,\r
871 FALSE,\r
872 FALSE,\r
873 MethodStatus);\r
874\r
875 if (Ret != TcgResultSuccess || *MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
876 //\r
877 // bail out\r
878 //\r
879 return Ret;\r
880 }\r
881 }\r
882\r
883 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
884 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
885 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
886 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
887 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCKING_SP_REVERTSP_METHOD));\r
888 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
889\r
890 if (KeepUserData) {\r
891 //\r
892 // optional parameter to keep Data after revert\r
893 //\r
894 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
895 ERROR_CHECK(TcgAddUINT32(&CreateStruct, 0x060000)); // weird Value but that's what spec says\r
896 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, KeepUserData));\r
897 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
898 }\r
899\r
900 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
901 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
902 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
903 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
904 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
905\r
906 //\r
907 // Send RevertSP method call\r
908 //\r
909 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, EstimateTimeCost));\r
9dd05dde
ED
910\r
911 //\r
912 // Session is immediately ended by device after successful revertsp, so no need to end Session\r
913 //\r
914 if (*MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {\r
915 //\r
916 // Caller should take ownership again\r
917 //\r
918 return TcgResultSuccess;\r
919 } else {\r
920 //\r
921 // End Session\r
922 //\r
923 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus\r
924 }\r
925\r
926 return TcgResultSuccess;\r
927}\r
928\r
929/**\r
930\r
931 The function activates the Locking SP.\r
932 Once activated, per Opal spec, the ADMIN SP SID PIN is copied over to the ADMIN1 LOCKING SP PIN.\r
933 If the Locking SP is already enabled, then TcgResultSuccess is returned and no action occurs.\r
934\r
935 @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY to activate Locking SP\r
936 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
937\r
938**/\r
939TCG_RESULT\r
940EFIAPI\r
941OpalActivateLockingSp(\r
942 OPAL_SESSION *AdminSpSession,\r
943 UINT8 *MethodStatus\r
944 )\r
945{\r
946 UINT8 Buf[BUFFER_SIZE];\r
947 TCG_CREATE_STRUCT CreateStruct;\r
948 UINT32 Size;\r
949 TCG_PARSE_STRUCT ParseStruct;\r
950\r
951 NULL_CHECK(AdminSpSession);\r
952 NULL_CHECK(MethodStatus);\r
953\r
954 //\r
955 // Call Activate method on Locking SP\r
956 //\r
957 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
958 ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
959 ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
960 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
961 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_LOCKING_SP, OPAL_ADMIN_SP_ACTIVATE_METHOD));\r
962 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
963 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
964 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
965 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
966 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
967 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
968\r
969 //\r
970 // Send Activate method call\r
971 //\r
a3068f06 972 ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
973 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus\r
974\r
975 return TcgResultSuccess;\r
976}\r
977\r
978/**\r
979\r
980 The function sets the PIN column of the specified cpinRowUid (authority) with the newPin Value.\r
981\r
982 @param[in/out] Session OPAL_SESSION to set password\r
983 @param[in] CpinRowUid UID of row (authority) to update PIN column\r
984 @param[in] NewPin New Pin to set for cpinRowUid specified\r
985 @param[in] NewPinLength Length in bytes of newPin\r
986 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
987\r
988**/\r
989TCG_RESULT\r
990EFIAPI\r
991OpalSetPassword(\r
992 OPAL_SESSION *Session,\r
993 TCG_UID CpinRowUid,\r
994 const VOID *NewPin,\r
995 UINT32 NewPinLength,\r
996 UINT8 *MethodStatus\r
997 )\r
998{\r
999 UINT8 Buf[BUFFER_SIZE];\r
1000 TCG_CREATE_STRUCT CreateStruct;\r
1001 TCG_PARSE_STRUCT ParseStruct;\r
1002 UINT32 Size;\r
1003\r
1004 NULL_CHECK(Session);\r
1005 NULL_CHECK(NewPin);\r
1006 NULL_CHECK(MethodStatus);\r
1007\r
1008 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1009 ERROR_CHECK(TcgCreateSetCPin(\r
1010 &CreateStruct,\r
1011 &Size,\r
1012 Session->OpalBaseComId,\r
1013 Session->ComIdExtension,\r
1014 Session->TperSessionId,\r
1015 Session->HostSessionId,\r
1016 CpinRowUid,\r
1017 NewPin,\r
1018 NewPinLength\r
1019 ));\r
1020\r
a3068f06 1021 ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1022 // exit with success on method failure - user must inspect MethodStatus\r
1023 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
1024\r
1025 return TcgResultSuccess;\r
1026}\r
1027\r
1028/**\r
1029\r
1030 The function sets the Enabled column to TRUE for the authorityUid provided and updates the PIN column for the cpinRowUid provided\r
1031 using the newPin provided. AuthorityUid and cpinRowUid should describe the same authority.\r
1032\r
1033 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to update\r
1034 @param[in] CpinRowUid Row UID of C_PIN table of Locking SP to update PIN\r
1035 @param[in] AuthorityUid UID of Locking SP authority to update Pin column with\r
1036 @param[in] NewPin New Password used to set Pin column\r
1037 @param[in] NewPinLength Length in bytes of new password\r
1038 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
1039\r
1040**/\r
1041TCG_RESULT\r
1042EFIAPI\r
1043OpalSetLockingSpAuthorityEnabledAndPin(\r
1044 OPAL_SESSION *LockingSpSession,\r
1045 TCG_UID CpinRowUid,\r
1046 TCG_UID AuthorityUid,\r
1047 const VOID *NewPin,\r
1048 UINT32 NewPinLength,\r
1049 UINT8 *MethodStatus\r
1050 )\r
1051{\r
1052 UINT8 Buf[BUFFER_SIZE];\r
1053 TCG_CREATE_STRUCT CreateStruct;\r
1054 TCG_PARSE_STRUCT ParseStruct;\r
1055 UINT32 Size;\r
1056 TCG_UID ActiveKey;\r
6e7423c3 1057 TCG_RESULT Ret;\r
9dd05dde
ED
1058\r
1059 NULL_CHECK(LockingSpSession);\r
1060 NULL_CHECK(NewPin);\r
1061 NULL_CHECK(MethodStatus);\r
1062\r
1063 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1064 ERROR_CHECK(TcgSetAuthorityEnabled(\r
1065 &CreateStruct,\r
1066 &Size,\r
1067 LockingSpSession->OpalBaseComId,\r
1068 LockingSpSession->ComIdExtension,\r
1069 LockingSpSession->TperSessionId,\r
1070 LockingSpSession->HostSessionId,\r
1071 AuthorityUid,\r
1072 TRUE));\r
1073\r
a3068f06 1074 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1075\r
1076 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
1077 DEBUG ((DEBUG_INFO, "Send Set Authority error\n"));\r
1078 return TcgResultFailure;\r
1079 }\r
1080\r
1081 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1082\r
1083 ERROR_CHECK(TcgCreateSetCPin(\r
1084 &CreateStruct,\r
1085 &Size,\r
1086 LockingSpSession->OpalBaseComId,\r
1087 LockingSpSession->ComIdExtension,\r
1088 LockingSpSession->TperSessionId,\r
1089 LockingSpSession->HostSessionId,\r
1090 CpinRowUid,\r
1091 NewPin,\r
1092 NewPinLength));\r
1093\r
a3068f06 1094 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1095\r
1096 //\r
1097 // allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked\r
1098 //\r
1099 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1100 ERROR_CHECK(TcgCreateSetAce(\r
1101 &CreateStruct,\r
1102 &Size,\r
1103 LockingSpSession->OpalBaseComId,\r
1104 LockingSpSession->ComIdExtension,\r
1105 LockingSpSession->TperSessionId,\r
1106 LockingSpSession->HostSessionId,\r
1107 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_RDLOCKED,\r
1108 OPAL_LOCKING_SP_USER1_AUTHORITY,\r
1109 TCG_ACE_EXPRESSION_OR,\r
1110 OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
1111 ));\r
1112\r
a3068f06 1113 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1114\r
1115 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
1116 DEBUG ((DEBUG_INFO, "Update ACE for RDLOCKED failed\n"));\r
1117 return TcgResultFailure;\r
1118 }\r
1119\r
1120 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1121 ERROR_CHECK(TcgCreateSetAce(\r
1122 &CreateStruct,\r
1123 &Size,\r
1124 LockingSpSession->OpalBaseComId,\r
1125 LockingSpSession->ComIdExtension,\r
1126 LockingSpSession->TperSessionId,\r
1127 LockingSpSession->HostSessionId,\r
1128 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_SET_WRLOCKED,\r
1129 OPAL_LOCKING_SP_USER1_AUTHORITY,\r
1130 TCG_ACE_EXPRESSION_OR,\r
1131 OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
1132 ));\r
1133\r
a3068f06 1134 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1135\r
1136 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
1137 DEBUG ((DEBUG_INFO, "Update ACE for WRLOCKED failed\n"));\r
1138 return TcgResultFailure;\r
1139 }\r
1140\r
1141 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1142 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession, &CreateStruct, &Size));\r
a3068f06 1143 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde 1144\r
6e7423c3 1145 //\r
b3548d32 1146 // For Pyrite type SSC, it not supports Active Key.\r
6e7423c3
ED
1147 // So here add check logic before enable it.\r
1148 //\r
1149 Ret = OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct, &ActiveKey);\r
1150 if (Ret == TcgResultSuccess) {\r
1151 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1152 ERROR_CHECK(TcgCreateSetAce(\r
1153 &CreateStruct,\r
1154 &Size,\r
1155 LockingSpSession->OpalBaseComId,\r
1156 LockingSpSession->ComIdExtension,\r
1157 LockingSpSession->TperSessionId,\r
1158 LockingSpSession->HostSessionId,\r
1159 (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,\r
1160 OPAL_LOCKING_SP_USER1_AUTHORITY,\r
1161 TCG_ACE_EXPRESSION_OR,\r
1162 OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
1163 ));\r
9dd05dde 1164\r
a3068f06 1165 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde 1166\r
6e7423c3
ED
1167 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
1168 DEBUG ((DEBUG_INFO, "Update ACE for GLOBALRANGE_GENKEY failed\n"));\r
1169 //\r
dbff6ed0 1170 // Disable user1 if all permissions are not granted.\r
6e7423c3
ED
1171 //\r
1172 return TcgResultFailure;\r
1173 }\r
9dd05dde
ED
1174 }\r
1175\r
1176 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1177 ERROR_CHECK(TcgCreateSetAce(\r
1178 &CreateStruct,\r
1179 &Size,\r
1180 LockingSpSession->OpalBaseComId,\r
1181 LockingSpSession->ComIdExtension,\r
1182 LockingSpSession->TperSessionId,\r
1183 LockingSpSession->HostSessionId,\r
1184 OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL,\r
1185 OPAL_LOCKING_SP_USER1_AUTHORITY,\r
1186 TCG_ACE_EXPRESSION_OR,\r
1187 OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
1188 ));\r
1189\r
a3068f06 1190 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1191\r
1192 if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
1193 DEBUG ((DEBUG_INFO, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL failed\n"));\r
1194 return TcgResultFailure;\r
1195 }\r
1196\r
1197 return TcgResultSuccess;\r
1198}\r
1199\r
1200/**\r
1201\r
1202 The function sets the Enabled column to FALSE for the USER1 authority.\r
1203\r
1204 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to disable User1\r
1205 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
1206\r
1207**/\r
1208TCG_RESULT\r
1209EFIAPI\r
1210OpalDisableUser(\r
1211 OPAL_SESSION *LockingSpSession,\r
1212 UINT8 *MethodStatus\r
1213 )\r
1214{\r
1215 UINT8 Buf[BUFFER_SIZE];\r
1216 TCG_CREATE_STRUCT CreateStruct;\r
1217 TCG_PARSE_STRUCT ParseStruct;\r
1218 UINT32 Size;\r
1219\r
1220 NULL_CHECK(LockingSpSession);\r
1221 NULL_CHECK(MethodStatus);\r
1222\r
1223 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1224 ERROR_CHECK(TcgSetAuthorityEnabled(\r
1225 &CreateStruct,\r
1226 &Size,\r
1227 LockingSpSession->OpalBaseComId,\r
1228 LockingSpSession->ComIdExtension,\r
1229 LockingSpSession->TperSessionId,\r
1230 LockingSpSession->HostSessionId,\r
1231 OPAL_LOCKING_SP_USER1_AUTHORITY,\r
1232 FALSE));\r
1233\r
a3068f06 1234 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1235\r
1236 return TcgResultSuccess;\r
1237}\r
1238\r
1239/**\r
1240\r
1241 The function retrieves the active key of the global locking range\r
1242 and calls the GenKey method on the active key retrieved.\r
1243\r
1244 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key\r
1245 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
1246\r
1247**/\r
1248TCG_RESULT\r
1249EFIAPI\r
1250OpalGlobalLockingRangeGenKey(\r
1251 OPAL_SESSION *LockingSpSession,\r
1252 UINT8 *MethodStatus\r
1253 )\r
1254{\r
1255 UINT8 Buf[BUFFER_SIZE];\r
1256 TCG_CREATE_STRUCT CreateStruct;\r
1257 TCG_PARSE_STRUCT ParseStruct;\r
1258 UINT32 Size;\r
1259 TCG_UID ActiveKey;\r
1260\r
1261 NULL_CHECK(LockingSpSession);\r
1262 NULL_CHECK(MethodStatus);\r
1263\r
1264 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1265 //\r
1266 // retrieve the activekey in order to know which globalrange key to generate\r
1267 //\r
1268 ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession, &CreateStruct, &Size));\r
a3068f06 1269 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1270\r
1271 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
1272\r
1273 ERROR_CHECK(OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct, &ActiveKey));\r
1274\r
1275 //\r
1276 // call genkey on ActiveKey UID\r
1277 //\r
1278 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1279 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
1280 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
1281 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
1282 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, ActiveKey, TCG_UID_METHOD_GEN_KEY));\r
1283 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
1284 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
1285 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
1286 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
1287 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
1288 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
1289\r
a3068f06 1290 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1291\r
1292 return TcgResultSuccess;\r
1293}\r
1294\r
1295/**\r
1296\r
1297 The function updates the ReadLocked and WriteLocked columns of the Global Locking Range.\r
0ab475c9 1298 This function is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns\r
9dd05dde
ED
1299 (not ReadLockEnabled and WriteLockEnabled columns).\r
1300\r
1301 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key\r
1302 @param[in] ReadLocked Value to set ReadLocked column for Global Locking Range\r
1303 @param[in] WriteLocked Value to set WriteLocked column for Global Locking Range\r
1304 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
1305\r
1306**/\r
1307TCG_RESULT\r
1308EFIAPI\r
1309OpalUpdateGlobalLockingRange(\r
1310 OPAL_SESSION *LockingSpSession,\r
1311 BOOLEAN ReadLocked,\r
1312 BOOLEAN WriteLocked,\r
1313 UINT8 *MethodStatus\r
1314 )\r
1315{\r
1316 UINT8 Buf[BUFFER_SIZE];\r
1317 TCG_CREATE_STRUCT CreateStruct;\r
1318 TCG_PARSE_STRUCT ParseStruct;\r
1319 UINT32 Size;\r
1320\r
1321 NULL_CHECK(LockingSpSession);\r
1322 NULL_CHECK(MethodStatus);\r
1323\r
1324 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1325\r
1326 //\r
1327 // set global locking range values\r
1328 //\r
1329 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
1330 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
1331 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
1332 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE, TCG_UID_METHOD_SET));\r
1333 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
1334 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1335 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x01)); // "Values"\r
1336 ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
1337\r
1338 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1339 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x07)); // "ReadLocked"\r
1340 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, ReadLocked));\r
1341 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1342\r
1343 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1344 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x08)); // "WriteLocked"\r
1345 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, WriteLocked));\r
1346 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1347\r
1348 ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
1349 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1350 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
1351 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
1352 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
1353 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
1354 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
1355\r
a3068f06 1356 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1357 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
1358\r
1359 return TcgResultSuccess;\r
1360}\r
1361\r
1362/**\r
1363\r
1364 The function updates the RangeStart, RangeLength, ReadLockedEnabled, WriteLockedEnabled, ReadLocked and WriteLocked columns\r
1365 of the specified Locking Range. This function requires admin authority of a locking SP session.\r
1366\r
1367 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key\r
1368 @param[in] LockingRangeUid Locking range UID to set values\r
1369 @param[in] RangeStart Value to set RangeStart column for Locking Range\r
1370 @param[in] RangeLength Value to set RangeLength column for Locking Range\r
1371 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range\r
1372 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range\r
1373 @param[in] ReadLocked Value to set ReadLocked column for Locking Range\r
1374 @param[in] WriteLocked Value to set WriteLocked column for Locking Range\r
1375 @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
1376\r
1377**/\r
1378TCG_RESULT\r
1379EFIAPI\r
1380OpalSetLockingRange(\r
1381 OPAL_SESSION *LockingSpSession,\r
1382 TCG_UID LockingRangeUid,\r
1383 UINT64 RangeStart,\r
1384 UINT64 RangeLength,\r
1385 BOOLEAN ReadLockEnabled,\r
1386 BOOLEAN WriteLockEnabled,\r
1387 BOOLEAN ReadLocked,\r
1388 BOOLEAN WriteLocked,\r
1389 UINT8 *MethodStatus\r
1390 )\r
1391{\r
1392 UINT8 Buf[BUFFER_SIZE];\r
1393 TCG_CREATE_STRUCT CreateStruct;\r
1394 TCG_PARSE_STRUCT ParseStruct;\r
1395 UINT32 Size;\r
1396\r
1397 NULL_CHECK(LockingSpSession);\r
1398 NULL_CHECK(MethodStatus);\r
1399\r
1400 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1401\r
1402 //\r
1403 // set locking range values\r
1404 //\r
1405 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
1406 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
1407 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
1408 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, LockingRangeUid, TCG_UID_METHOD_SET));\r
1409 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
1410 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1411 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x01)); // "Values"\r
1412 ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
1413\r
1414 //\r
1415 // range start and range Length only apply to non-global locking ranges\r
1416 //\r
1417 if (LockingRangeUid != OPAL_LOCKING_SP_LOCKING_GLOBALRANGE) {\r
1418 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1419 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x03)); // "RangeStart"\r
1420 ERROR_CHECK(TcgAddUINT64(&CreateStruct, RangeStart));\r
1421 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1422\r
1423 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1424 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x04)); // "RangeLength"\r
1425 ERROR_CHECK(TcgAddUINT64(&CreateStruct, RangeLength));\r
1426 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1427 }\r
1428\r
1429 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1430 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x05)); // "ReadLockEnabled"\r
1431 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, ReadLockEnabled));\r
1432 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1433\r
1434 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1435 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x06)); // "WriteLockEnabled"\r
1436 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, WriteLockEnabled));\r
1437 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1438\r
1439 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1440 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x07)); // "ReadLocked"\r
1441 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, ReadLocked));\r
1442 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1443\r
1444 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1445 ERROR_CHECK(TcgAddUINT8(&CreateStruct, 0x08)); // "WriteLocked"\r
1446 ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, WriteLocked));\r
1447 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1448\r
1449 ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
1450 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1451 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
1452 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
1453 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
1454 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
1455 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
1456\r
a3068f06 1457 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
9dd05dde
ED
1458 // Exit with success on method failure - user must inspect MethodStatus\r
1459 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
1460\r
1461 return TcgResultSuccess;\r
1462}\r
1463\r
1464/**\r
1465\r
1466 The function populates the CreateStruct with a payload that will retrieve the global locking range active key.\r
1467 It is intended to be called with a session that is already started with a valid credential.\r
1468 The function does not send the payload.\r
1469\r
1470 @param[in] Session OPAL_SESSION to populate command for, needs ComId\r
1471 @param[in/out] CreateStruct Structure to populate with encoded TCG command\r
1472 @param[in/out] Size Size in bytes of the command created.\r
1473\r
1474**/\r
1475TCG_RESULT\r
1476EFIAPI\r
1477OpalCreateRetrieveGlobalLockingRangeActiveKey(\r
1478 const OPAL_SESSION *Session,\r
1479 TCG_CREATE_STRUCT *CreateStruct,\r
1480 UINT32 *Size\r
1481 )\r
1482{\r
1483 NULL_CHECK(Session);\r
1484 NULL_CHECK(CreateStruct);\r
1485 NULL_CHECK(Size);\r
1486\r
1487 // Retrieve the activekey in order to know which globalrange key to generate\r
1488 ERROR_CHECK(TcgStartComPacket(CreateStruct, Session->OpalBaseComId, Session->ComIdExtension));\r
1489 ERROR_CHECK(TcgStartPacket(CreateStruct, Session->TperSessionId, Session->HostSessionId, 0x0, 0x0, 0x0));\r
1490 ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
1491 ERROR_CHECK(TcgStartMethodCall(CreateStruct, OPAL_LOCKING_SP_LOCKING_GLOBALRANGE, TCG_UID_METHOD_GET));\r
1492 ERROR_CHECK(TcgStartParameters(CreateStruct));\r
1493 ERROR_CHECK(TcgAddStartList(CreateStruct));\r
1494 ERROR_CHECK(TcgAddStartName(CreateStruct));\r
1495 ERROR_CHECK(TcgAddUINT8(CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));\r
1496 ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x0A)); // ActiveKey\r
1497 ERROR_CHECK(TcgAddEndName(CreateStruct));\r
1498 ERROR_CHECK(TcgAddStartName(CreateStruct));\r
1499 ERROR_CHECK(TcgAddUINT8(CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));\r
1500 ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x0A));\r
1501 ERROR_CHECK(TcgAddEndName(CreateStruct));\r
1502 ERROR_CHECK(TcgAddEndList(CreateStruct));\r
1503 ERROR_CHECK(TcgEndParameters(CreateStruct));\r
1504 ERROR_CHECK(TcgEndMethodCall(CreateStruct));\r
1505 ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
1506 ERROR_CHECK(TcgEndPacket(CreateStruct));\r
1507 ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
1508\r
1509 return TcgResultSuccess;\r
1510}\r
1511\r
1512/**\r
1513\r
1514 The function acquires the activeKey specified for the Global Locking Range from the ParseStruct.\r
1515\r
1516 @param[in] ParseStruct Structure that contains the device's response with the activekey\r
1517 @param[in/out] ActiveKey The UID of the active key retrieved\r
1518\r
1519**/\r
1520TCG_RESULT\r
1521EFIAPI\r
1522OpalParseRetrieveGlobalLockingRangeActiveKey(\r
1523 TCG_PARSE_STRUCT *ParseStruct,\r
1524 TCG_UID *ActiveKey\r
1525 )\r
1526{\r
1527 UINT32 ColumnName;\r
1528\r
1529 NULL_CHECK(ParseStruct);\r
1530 NULL_CHECK(ActiveKey);\r
1531\r
1532 // parse response\r
1533 ERROR_CHECK(TcgGetNextStartList(ParseStruct));\r
1534 ERROR_CHECK(TcgGetNextStartList(ParseStruct));\r
1535 ERROR_CHECK(TcgGetNextStartName(ParseStruct));\r
1536 ERROR_CHECK(TcgGetNextUINT32(ParseStruct, &ColumnName));\r
1537 ERROR_CHECK(TcgGetNextTcgUid(ParseStruct, ActiveKey));\r
1538 ERROR_CHECK(TcgGetNextEndName(ParseStruct));\r
1539 ERROR_CHECK(TcgGetNextEndList(ParseStruct));\r
1540 ERROR_CHECK(TcgGetNextEndList(ParseStruct));\r
1541 ERROR_CHECK(TcgGetNextEndOfData(ParseStruct));\r
1542\r
1543 if (ColumnName != 0x0A) {\r
1544 DEBUG ((DEBUG_INFO, "Unexpected column name %u (exp 0x0A)\n", ColumnName));\r
1545 return TcgResultFailure;\r
1546 }\r
1547\r
1548 if (*ActiveKey != OPAL_LOCKING_SP_K_AES_256_GLOBALRANGE_KEY && *ActiveKey != OPAL_LOCKING_SP_K_AES_128_GLOBALRANGE_KEY) {\r
1549 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));\r
1550 return TcgResultFailure;\r
1551 }\r
1552\r
1553 return TcgResultSuccess;\r
1554}\r
1555\r
1556/**\r
1557\r
1558 The function retrieves the TryLimit column for the specified rowUid (authority).\r
1559\r
1560 @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve try limit\r
1561 @param[in] RowUid Row UID of the Locking SP C_PIN table to retrieve TryLimit column\r
1562 @param[in/out] TryLimit Value from TryLimit column\r
1563\r
1564**/\r
1565TCG_RESULT\r
1566EFIAPI\r
1567OpalGetTryLimit(\r
1568 OPAL_SESSION *LockingSpSession,\r
1569 TCG_UID RowUid,\r
1570 UINT32 *TryLimit\r
1571 )\r
1572{\r
1573 TCG_CREATE_STRUCT CreateStruct;\r
1574 TCG_PARSE_STRUCT ParseStruct;\r
1575 UINT32 Size;\r
1576 UINT8 MethodStatus;\r
1577 UINT8 Buf[BUFFER_SIZE];\r
1578 UINT32 Col;\r
1579\r
1580 NULL_CHECK(LockingSpSession);\r
1581 NULL_CHECK(TryLimit);\r
1582\r
1583 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
1584 ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
1585 ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
1586 ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
1587 ERROR_CHECK(TcgStartMethodCall(&CreateStruct, RowUid, TCG_UID_METHOD_GET));\r
1588 ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
1589 ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
1590 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1591 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));\r
1592 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));\r
1593 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1594 ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
1595 ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));\r
1596 ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));\r
1597 ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
1598 ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
1599 ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
1600 ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
1601 ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
1602 ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
1603 ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
1604\r
a3068f06 1605 ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, &MethodStatus, 0));\r
9dd05dde
ED
1606 METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
1607\r
1608 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
1609 ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
1610 ERROR_CHECK(TcgGetNextStartName(&ParseStruct));\r
1611 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, &Col));\r
1612 ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, TryLimit));\r
1613 ERROR_CHECK(TcgGetNextEndName(&ParseStruct));\r
1614 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
1615 ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
1616 ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct));\r
1617\r
1618 if (Col != OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL) {\r
1619 DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_LOCKING_SP_C_PIN_TRYLIMIT_COL));\r
1620 return TcgResultFailure;\r
1621 }\r
1622\r
1623 return TcgResultSuccess;\r
1624}\r
1625\r
1626/**\r
1627\r
1628 Get the support attribute info.\r
1629\r
1630 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.\r
1631 @param[out] SupportedAttributes Return the support attribute info.\r
1632 @param[out] OpalBaseComId Return the base com id info.\r
1633\r
1634**/\r
1635TCG_RESULT\r
1636EFIAPI\r
1637OpalGetSupportedAttributesInfo(\r
1638 IN OPAL_SESSION *Session,\r
1639 OUT OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
1640 OUT UINT16 *OpalBaseComId\r
1641 )\r
1642{\r
1643 UINT8 Buffer[BUFFER_SIZE];\r
1644 TCG_SUPPORTED_SECURITY_PROTOCOLS *SupportedProtocols;\r
1645 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;\r
1646 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;\r
a3068f06 1647 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat2;\r
9dd05dde 1648 UINTN Size;\r
a3068f06 1649 UINTN Size2;\r
9dd05dde
ED
1650\r
1651 NULL_CHECK(Session);\r
1652 NULL_CHECK(SupportedAttributes);\r
1653 NULL_CHECK(OpalBaseComId);\r
1654\r
1655 ZeroMem(Buffer, BUFFER_SIZE);\r
1656 ASSERT(sizeof(Buffer) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS));\r
1657\r
1658 //\r
1659 // Retrieve supported protocols verify security protocol 1 is supported\r
1660 //\r
1661 SupportedProtocols = (TCG_SUPPORTED_SECURITY_PROTOCOLS*) Buffer;\r
1662\r
1663 //\r
1664 // Get list of supported protocols\r
1665 //\r
1666 if (OpalRetrieveSupportedProtocolList (Session, sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS), SupportedProtocols) == TcgResultFailure) {\r
1667 DEBUG ((DEBUG_INFO, "OpalRetrieveSupportedProtocolList failed\n"));\r
1668 return TcgResultFailure;\r
1669 }\r
1670\r
1671 SupportedAttributes->Sp1 = TcgIsProtocolSupported (SupportedProtocols, TCG_OPAL_SECURITY_PROTOCOL_1);\r
1672 SupportedAttributes->Sp2 = TcgIsProtocolSupported (SupportedProtocols, TCG_OPAL_SECURITY_PROTOCOL_2);\r
1673 SupportedAttributes->SpIeee1667 = TcgIsProtocolSupported (SupportedProtocols, TCG_SECURITY_PROTOCOL_IEEE_1667);\r
1674\r
1675 DEBUG ((DEBUG_INFO, "Supported Protocols: Sp1 %d Sp2: %d SpIeee1667 %d \n",\r
1676 SupportedAttributes->Sp1,\r
1677 SupportedAttributes->Sp2,\r
1678 SupportedAttributes->SpIeee1667\r
1679 ));\r
1680\r
1681 //\r
1682 // Perform level 0 discovery and assign desired feature info to Opal Disk structure\r
1683 //\r
1684 ZeroMem (Buffer, BUFFER_SIZE);\r
1685 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {\r
1686 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));\r
1687 return TcgResultFailure;\r
1688 }\r
1689\r
1690 //\r
1691 // Check for required feature descriptors\r
1692 //\r
1693 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER*) Buffer;\r
1694\r
1695 Size = 0;\r
1696 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_V2_0_0, &Size);\r
1697 SupportedAttributes->OpalSsc2 = (Feat != NULL);\r
1698\r
1699 *OpalBaseComId = TCG_RESERVED_COMID;\r
1700\r
1701 //\r
1702 // Check Opal SCC V2 has valid settings for SID C_PIN on revert\r
1703 //\r
1704 if (SupportedAttributes->OpalSsc2 && Size >= sizeof (OPAL_SSCV2_FEATURE_DESCRIPTOR)) {\r
1705 //\r
1706 // Want opposite polarity b/c Value is greater than a bit, but we only care about non-zero vs zero\r
1707 //\r
1708 SupportedAttributes->InitCpinIndicator = (Feat->OpalSscV2.InitialCPINSIDPIN == 0);\r
1709 SupportedAttributes->CpinUponRevert = (Feat->OpalSscV2.CPINSIDPINRevertBehavior == 0);\r
1710 DEBUG ((DEBUG_INFO, "Opal SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",\r
1711 SupportedAttributes->InitCpinIndicator,\r
1712 SupportedAttributes->CpinUponRevert\r
1713 ));\r
1714 *OpalBaseComId = SwapBytes16 (Feat->OpalSscV2.BaseComdIdBE);\r
1715 }\r
1716\r
1717 Size = 0;\r
1718 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_LITE, &Size);\r
1719 SupportedAttributes->OpalSscLite = (Feat != NULL);\r
1720\r
1721 if (Feat != NULL && Size >= sizeof (OPAL_SSCLITE_FEATURE_DESCRIPTOR)) {\r
1722 if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
1723 //\r
1724 // Pin values used always match up with ComId used\r
1725 //\r
1726 *OpalBaseComId = SwapBytes16 (Feat->OpalSscLite.BaseComdIdBE);\r
1727 SupportedAttributes->InitCpinIndicator = (Feat->OpalSscV2.InitialCPINSIDPIN == 0);\r
1728 SupportedAttributes->CpinUponRevert = (Feat->OpalSscV2.CPINSIDPINRevertBehavior == 0);\r
1729 DEBUG ((DEBUG_INFO, "Opal SSC Lite InitCpinIndicator %d CpinUponRevert %d \n",\r
1730 SupportedAttributes->InitCpinIndicator,\r
1731 SupportedAttributes->CpinUponRevert\r
1732 ));\r
1733 }\r
1734 }\r
1735\r
a3068f06
ED
1736 //\r
1737 // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 feature data.\r
1738 // so here try to get data from pyrite 2.0 feature data first.\r
1739 //\r
9dd05dde
ED
1740 Size = 0;\r
1741 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC, &Size);\r
a3068f06
ED
1742 Size2 = 0;\r
1743 Feat2 = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC_V2_0_0, &Size2);\r
1744 if (Feat2 != NULL && Size2 >= sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTOR)) {\r
1745 SupportedAttributes->PyriteSscV2 = TRUE;\r
9dd05dde 1746 if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
a3068f06
ED
1747 *OpalBaseComId = SwapBytes16 (Feat2->PyriteSscV2.BaseComdIdBE);\r
1748 SupportedAttributes->InitCpinIndicator = (Feat2->PyriteSscV2.InitialCPINSIDPIN == 0);\r
1749 SupportedAttributes->CpinUponRevert = (Feat2->PyriteSscV2.CPINSIDPINRevertBehavior == 0);\r
1750 DEBUG ((DEBUG_INFO, "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",\r
9dd05dde
ED
1751 SupportedAttributes->InitCpinIndicator,\r
1752 SupportedAttributes->CpinUponRevert\r
1753 ));\r
1754 }\r
a3068f06
ED
1755 } else {\r
1756 SupportedAttributes->PyriteSsc = (Feat != NULL);\r
1757 if (Feat != NULL && Size >= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR)) {\r
1758 if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
1759 *OpalBaseComId = SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE);\r
1760 SupportedAttributes->InitCpinIndicator = (Feat->PyriteSsc.InitialCPINSIDPIN == 0);\r
1761 SupportedAttributes->CpinUponRevert = (Feat->PyriteSsc.CPINSIDPINRevertBehavior == 0);\r
1762 DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",\r
1763 SupportedAttributes->InitCpinIndicator,\r
1764 SupportedAttributes->CpinUponRevert\r
1765 ));\r
1766 }\r
1767 }\r
9dd05dde
ED
1768 }\r
1769\r
1770 Size = 0;\r
1771 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_OPAL_SSC_V1_0_0, &Size);\r
1772 SupportedAttributes->OpalSsc1 = (Feat != NULL);\r
1773 if (Feat != NULL && Size >= sizeof (OPAL_SSCV1_FEATURE_DESCRIPTOR)) {\r
1774 if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
1775 *OpalBaseComId = SwapBytes16 (Feat->OpalSscV1.BaseComdIdBE);\r
1776 }\r
1777 }\r
1778\r
1779 Size = 0;\r
1780 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size);\r
1781 if (Feat != NULL && Size >= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR)) {\r
1782 SupportedAttributes->MediaEncryption = Feat->Locking.MediaEncryption;\r
a3068f06 1783 DEBUG ((DEBUG_INFO, "SupportedAttributes->MediaEncryption 0x%X \n", SupportedAttributes->MediaEncryption));\r
9dd05dde
ED
1784 }\r
1785\r
b20e0d29
ED
1786 Size = 0;\r
1787 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_BLOCK_SID, &Size);\r
1788 if (Feat != NULL && Size >= sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR)) {\r
1789 SupportedAttributes->BlockSid = TRUE;\r
a3068f06
ED
1790 DEBUG ((DEBUG_INFO, "BlockSid Supported!!! Current Status is 0x%X \n", Feat->BlockSid.SIDBlockedState));\r
1791 } else {\r
1792 DEBUG ((DEBUG_INFO, "BlockSid Unsupported!!!"));\r
b20e0d29
ED
1793 }\r
1794\r
a3068f06
ED
1795 Size = 0;\r
1796 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_DATA_REMOVAL, &Size);\r
1797 if (Feat != NULL && Size >= sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR)) {\r
1798 SupportedAttributes->DataRemoval = TRUE;\r
1799 DEBUG ((DEBUG_INFO, "DataRemoval Feature Supported!\n"));\r
1800 DEBUG ((DEBUG_INFO, "Operation Processing = 0x%x\n", Feat->DataRemoval.OperationProcessing));\r
1801 DEBUG ((DEBUG_INFO, "RemovalMechanism = 0x%x\n", Feat->DataRemoval.RemovalMechanism));\r
1802 DEBUG ((DEBUG_INFO, "BIT0 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit0, SwapBytes16 (Feat->DataRemoval.TimeBit0)));\r
1803 DEBUG ((DEBUG_INFO, "BIT1 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit1, SwapBytes16 (Feat->DataRemoval.TimeBit1)));\r
1804 DEBUG ((DEBUG_INFO, "BIT2 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit2, SwapBytes16 (Feat->DataRemoval.TimeBit2)));\r
1805 DEBUG ((DEBUG_INFO, "BIT3 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit3, SwapBytes16 (Feat->DataRemoval.TimeBit3)));\r
1806 DEBUG ((DEBUG_INFO, "BIT4 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit4, SwapBytes16 (Feat->DataRemoval.TimeBit4)));\r
1807 }\r
9dd05dde 1808\r
a3068f06 1809 DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId));\r
9dd05dde
ED
1810\r
1811 return TcgResultSuccess;\r
1812}\r
1813\r
1814/**\r
1815\r
1816 Get the support attribute info.\r
1817\r
1818 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.\r
1819 @param[in/out] LockingFeature Return the Locking info.\r
1820\r
1821**/\r
1822TCG_RESULT\r
1823EFIAPI\r
1824OpalGetLockingInfo(\r
1825 OPAL_SESSION *Session,\r
1826 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature\r
1827 )\r
1828{\r
1829 UINT8 Buffer[BUFFER_SIZE];\r
1830 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;\r
1831 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;\r
1832 UINTN Size;\r
1833\r
1834 NULL_CHECK(Session);\r
1835 NULL_CHECK(LockingFeature);\r
1836\r
1837 ZeroMem(Buffer, BUFFER_SIZE);\r
1838 ASSERT(sizeof(Buffer) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS));\r
1839\r
1840 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {\r
1841 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));\r
1842 return TcgResultFailure;\r
1843 }\r
1844 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER*) Buffer;\r
1845\r
1846 Size = 0;\r
1847 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size);\r
1848 if (Feat != NULL && Size >= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR)) {\r
1849 CopyMem (LockingFeature, &Feat->Locking, sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR));\r
1850 }\r
1851\r
1852 return TcgResultSuccess;\r
1853}\r
1854\r
a3068f06
ED
1855/**\r
1856\r
1857 Get the descriptor for the specific feature code.\r
1858\r
1859 @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.\r
1860 @param[in] FeatureCode The feature code user request.\r
1861 @param[in, out] DataSize The data size.\r
1862 @param[out] Data The data buffer used to save the feature descriptor.\r
1863\r
1864**/\r
1865TCG_RESULT\r
a3068f06
ED
1866OpalGetFeatureDescriptor (\r
1867 IN OPAL_SESSION *Session,\r
1868 IN UINT16 FeatureCode,\r
1869 IN OUT UINTN *DataSize,\r
1870 OUT VOID *Data\r
1871 )\r
1872{\r
1873 UINT8 Buffer[BUFFER_SIZE];\r
1874 TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;\r
1875 OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;\r
1876 UINTN Size;\r
1877\r
1878 NULL_CHECK(Session);\r
1879 NULL_CHECK(DataSize);\r
1880 NULL_CHECK(Data);\r
1881\r
1882 ZeroMem(Buffer, BUFFER_SIZE);\r
1883 ASSERT(sizeof(Buffer) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS));\r
1884\r
1885 if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {\r
1886 DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));\r
1887 return TcgResultFailure;\r
1888 }\r
1889 DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER*) Buffer;\r
1890\r
1891 Size = 0;\r
1892 Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, FeatureCode, &Size);\r
1893 if (Feat != NULL) {\r
1894 if (Size > *DataSize) {\r
1895 *DataSize = Size;\r
1896 return TcgResultFailureBufferTooSmall;\r
1897 }\r
1898\r
1899 *DataSize = Size;\r
1900 CopyMem (Data, Feat, Size);\r
1901 }\r
1902\r
1903 return TcgResultSuccess;\r
1904}\r
1905\r
9dd05dde
ED
1906/**\r
1907\r
1908 The function determines whether or not all of the requirements for the Opal Feature (not full specification)\r
1909 are met by the specified device.\r
1910\r
1911 @param[in] SupportedAttributes Opal device attribute.\r
1912\r
1913**/\r
1914BOOLEAN\r
1915EFIAPI\r
1916OpalFeatureSupported(\r
1917 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes\r
1918 )\r
1919{\r
1920 NULL_CHECK(SupportedAttributes);\r
1921\r
1922 if (SupportedAttributes->Sp1 == 0) {\r
1923 return FALSE;\r
1924 }\r
1925\r
1926 if (SupportedAttributes->OpalSscLite == 0 &&\r
1927 SupportedAttributes->OpalSsc1 == 0 &&\r
1928 SupportedAttributes->OpalSsc2 == 0 &&\r
a3068f06
ED
1929 SupportedAttributes->PyriteSsc == 0 &&\r
1930 SupportedAttributes->PyriteSscV2 == 0\r
9dd05dde
ED
1931 ) {\r
1932 return FALSE;\r
1933 }\r
1934\r
1935 return TRUE;\r
1936}\r
1937\r
1938/**\r
1939\r
1940 The function returns whether or not the device is Opal Enabled.\r
1941 TRUE means that the device is partially or fully locked.\r
1942 This will perform a Level 0 Discovery and parse the locking feature descriptor\r
1943\r
1944 @param[in] SupportedAttributes Opal device attribute.\r
1945 @param[in] LockingFeature Opal device locking status.\r
1946\r
1947\r
1948**/\r
1949BOOLEAN\r
1950EFIAPI\r
1951OpalFeatureEnabled(\r
1952 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
1953 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature\r
1954 )\r
1955{\r
1956 NULL_CHECK(SupportedAttributes);\r
1957 NULL_CHECK(LockingFeature);\r
1958\r
1959 if (!OpalFeatureSupported (SupportedAttributes)) {\r
1960 return FALSE;\r
1961 }\r
1962\r
1963 if (LockingFeature->LockingSupported && LockingFeature->LockingEnabled) {\r
1964 return TRUE;\r
1965 }\r
1966\r
1967 return FALSE;\r
1968}\r
1969\r
1970/**\r
1971\r
1972 The function returns whether or not the device is Opal Locked.\r
1973 TRUE means that the device is partially or fully locked.\r
1974 This will perform a Level 0 Discovery and parse the locking feature descriptor\r
1975\r
1976 @param[in] SupportedAttributes Opal device attribute.\r
1977 @param[in] LockingFeature Opal device locking status.\r
1978\r
1979**/\r
1980BOOLEAN\r
1981OpalDeviceLocked(\r
1982 OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
1983 TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature\r
1984 )\r
1985{\r
1986 NULL_CHECK(SupportedAttributes);\r
1987 NULL_CHECK(LockingFeature);\r
1988\r
1989 if (!OpalFeatureEnabled (SupportedAttributes, LockingFeature)) {\r
1990 return FALSE;\r
1991 }\r
1992\r
1993 return LockingFeature->Locked;\r
1994}\r
1995\r