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