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