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