TianoCore EDK2 master
Loading...
Searching...
No Matches
HddPasswordDxe.c
Go to the documentation of this file.
1
11#include "HddPasswordDxe.h"
12#include <Library/VariablePolicyHelperLib.h>
13
14EFI_GUID mHddPasswordVendorGuid = HDD_PASSWORD_CONFIG_GUID;
15CHAR16 mHddPasswordVendorStorageName[] = L"HDD_PASSWORD_CONFIG";
16LIST_ENTRY mHddPasswordConfigFormList;
17UINT32 mNumberOfHddDevices = 0;
18
19EFI_GUID mHddPasswordDeviceInfoGuid = HDD_PASSWORD_DEVICE_INFO_GUID;
20BOOLEAN mHddPasswordEndOfDxe = FALSE;
21HDD_PASSWORD_REQUEST_VARIABLE *mHddPasswordRequestVariable = NULL;
22UINTN mHddPasswordRequestVariableSize = 0;
23
24HII_VENDOR_DEVICE_PATH mHddPasswordHiiVendorDevicePath = {
25 {
26 {
29 {
30 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
31 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
32 }
33 },
34 HDD_PASSWORD_CONFIG_GUID
35 },
36 {
37 END_DEVICE_PATH_TYPE,
38 END_ENTIRE_DEVICE_PATH_SUBTYPE,
39 {
40 (UINT8)(END_DEVICE_PATH_LENGTH),
41 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
42 }
43 }
44};
45
55BOOLEAN
57 IN CHAR8 *Password
58 )
59{
60 UINTN Index;
61
62 for (Index = 0; Index < HDD_PASSWORD_MAX_LENGTH; Index++) {
63 if (Password[Index] != 0) {
64 return FALSE;
65 }
66 }
67
68 return TRUE;
69}
70
78VOID
80 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry,
82 )
83{
84 TempDevInfo->Device.Bus = (UINT8)ConfigFormEntry->Bus;
85 TempDevInfo->Device.Device = (UINT8)ConfigFormEntry->Device;
86 TempDevInfo->Device.Function = (UINT8)ConfigFormEntry->Function;
87 TempDevInfo->Device.Port = ConfigFormEntry->Port;
88 TempDevInfo->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
89 CopyMem (TempDevInfo->Password, ConfigFormEntry->Password, HDD_PASSWORD_MAX_LENGTH);
90 TempDevInfo->DevicePathLength = (UINT32)GetDevicePathSize (ConfigFormEntry->DevicePath);
91 CopyMem (TempDevInfo->DevicePath, ConfigFormEntry->DevicePath, TempDevInfo->DevicePathLength);
92}
93
98VOID
100 VOID
101 )
102{
103 EFI_STATUS Status;
104 LIST_ENTRY *Entry;
105 HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry;
107 HDD_PASSWORD_DEVICE_INFO *TempDevInfo;
108 UINTN DevInfoLength;
109 UINT8 DummyData;
110 BOOLEAN S3InitDevicesExist;
111 UINTN S3InitDevicesLength;
112 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;
113 EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak;
114
115 //
116 // Build HDD password device info and save them to LockBox.
117 //
118 DevInfoLength = 0;
119 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
120 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
121
122 //
123 // 1. Handle device which already set password.
124 // 2. When request to send freeze command, driver also needs to handle device
125 // which support security feature.
126 //
127 if ((!PasswordIsFullZero (ConfigFormEntry->Password)) ||
128 ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
129 (ConfigFormEntry->IfrData.SecurityStatus.Enabled == 0)))
130 {
131 DevInfoLength += sizeof (HDD_PASSWORD_DEVICE_INFO) +
132 GetDevicePathSize (ConfigFormEntry->DevicePath);
133 }
134 }
135
136 if (DevInfoLength == 0) {
137 return;
138 }
139
140 S3InitDevicesLength = sizeof (DummyData);
141 Status = RestoreLockBox (
142 &gS3StorageDeviceInitListGuid,
143 &DummyData,
144 &S3InitDevicesLength
145 );
146 ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));
147 if (Status == EFI_NOT_FOUND) {
148 S3InitDevices = NULL;
149 S3InitDevicesExist = FALSE;
150 } else if (Status == EFI_BUFFER_TOO_SMALL) {
151 S3InitDevices = AllocatePool (S3InitDevicesLength);
152 ASSERT (S3InitDevices != NULL);
153
154 Status = RestoreLockBox (
155 &gS3StorageDeviceInitListGuid,
156 S3InitDevices,
157 &S3InitDevicesLength
158 );
159 ASSERT_EFI_ERROR (Status);
160 S3InitDevicesExist = TRUE;
161 } else {
162 return;
163 }
164
165 DevInfo = AllocateZeroPool (DevInfoLength);
166 ASSERT (DevInfo != NULL);
167
168 TempDevInfo = DevInfo;
169 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
170 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
171
172 if ((!PasswordIsFullZero (ConfigFormEntry->Password)) ||
173 ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
174 (ConfigFormEntry->IfrData.SecurityStatus.Enabled == 0)))
175 {
176 SaveDeviceInfo (ConfigFormEntry, TempDevInfo);
177
178 S3InitDevicesBak = S3InitDevices;
179 S3InitDevices = AppendDevicePathInstance (
180 S3InitDevicesBak,
181 ConfigFormEntry->DevicePath
182 );
183 if (S3InitDevicesBak != NULL) {
184 FreePool (S3InitDevicesBak);
185 }
186
187 ASSERT (S3InitDevices != NULL);
188
189 TempDevInfo = (HDD_PASSWORD_DEVICE_INFO *)((UINTN)TempDevInfo +
190 sizeof (HDD_PASSWORD_DEVICE_INFO) +
191 TempDevInfo->DevicePathLength);
192 }
193 }
194
195 Status = SaveLockBox (
196 &mHddPasswordDeviceInfoGuid,
197 DevInfo,
198 DevInfoLength
199 );
200 ASSERT_EFI_ERROR (Status);
201
202 Status = SetLockBoxAttributes (
203 &mHddPasswordDeviceInfoGuid,
204 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
205 );
206 ASSERT_EFI_ERROR (Status);
207
208 S3InitDevicesLength = GetDevicePathSize (S3InitDevices);
209 if (S3InitDevicesExist) {
210 Status = UpdateLockBox (
211 &gS3StorageDeviceInitListGuid,
212 0,
213 S3InitDevices,
214 S3InitDevicesLength
215 );
216 ASSERT_EFI_ERROR (Status);
217 } else {
218 Status = SaveLockBox (
219 &gS3StorageDeviceInitListGuid,
220 S3InitDevices,
221 S3InitDevicesLength
222 );
223 ASSERT_EFI_ERROR (Status);
224
225 Status = SetLockBoxAttributes (
226 &gS3StorageDeviceInitListGuid,
227 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
228 );
229 ASSERT_EFI_ERROR (Status);
230 }
231
232 ZeroMem (DevInfo, DevInfoLength);
233 FreePool (DevInfo);
234 FreePool (S3InitDevices);
235}
236
253 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
254 IN UINT16 Port,
255 IN UINT16 PortMultiplierPort
256 )
257{
258 EFI_STATUS Status;
262
263 if (AtaPassThru == NULL) {
264 return EFI_INVALID_PARAMETER;
265 }
266
267 //
268 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
269 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
270 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
271 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
272 // may not be aligned when allocated on stack for some compilers. Hence, we
273 // use the API AllocateAlignedPages to ensure this structure is properly
274 // aligned.
275 //
278 AtaPassThru->Mode->IoAlign
279 );
280 if (Asb == NULL) {
281 return EFI_OUT_OF_RESOURCES;
282 }
283
284 //
285 // Prepare for ATA command block.
286 //
287 ZeroMem (&Acb, sizeof (Acb));
288 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
289 Acb.AtaCommand = ATA_SECURITY_FREEZE_LOCK_CMD;
290 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
291
292 //
293 // Prepare for ATA pass through packet.
294 //
295 ZeroMem (&Packet, sizeof (Packet));
296 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
297 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER;
298 Packet.Asb = Asb;
299 Packet.Acb = &Acb;
300 Packet.Timeout = ATA_TIMEOUT;
301
302 Status = AtaPassThru->PassThru (
303 AtaPassThru,
304 Port,
305 PortMultiplierPort,
306 &Packet,
307 NULL
308 );
309 if (!EFI_ERROR (Status) &&
310 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
311 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
312 {
313 Status = EFI_DEVICE_ERROR;
314 }
315
317
318 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
319 return Status;
320}
321
339 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
340 IN UINT16 Port,
341 IN UINT16 PortMultiplierPort,
342 IN ATA_IDENTIFY_DATA *IdentifyData
343 )
344{
345 EFI_STATUS Status;
349
350 if ((AtaPassThru == NULL) || (IdentifyData == NULL)) {
351 return EFI_INVALID_PARAMETER;
352 }
353
354 //
355 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
356 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
357 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
358 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
359 // may not be aligned when allocated on stack for some compilers. Hence, we
360 // use the API AllocateAlignedPages to ensure this structure is properly
361 // aligned.
362 //
365 AtaPassThru->Mode->IoAlign
366 );
367 if (Asb == NULL) {
368 return EFI_OUT_OF_RESOURCES;
369 }
370
371 //
372 // Prepare for ATA command block.
373 //
374 ZeroMem (&Acb, sizeof (Acb));
375 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
376 Acb.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
377 Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4)));
378
379 //
380 // Prepare for ATA pass through packet.
381 //
382 ZeroMem (&Packet, sizeof (Packet));
383 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
384 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
385 Packet.Asb = Asb;
386 Packet.Acb = &Acb;
387 Packet.InDataBuffer = IdentifyData;
388 Packet.InTransferLength = sizeof (ATA_IDENTIFY_DATA);
389 Packet.Timeout = ATA_TIMEOUT;
390
391 Status = AtaPassThru->PassThru (
392 AtaPassThru,
393 Port,
394 PortMultiplierPort,
395 &Packet,
396 NULL
397 );
398
400
401 return Status;
402}
403
411VOID
413 IN ATA_IDENTIFY_DATA *IdentifyData,
414 IN OUT HDD_PASSWORD_CONFIG *IfrData
415 )
416{
417 IfrData->SecurityStatus.Supported = (IdentifyData->command_set_supported_82 & BIT1) ? 1 : 0;
418 IfrData->SecurityStatus.Enabled = (IdentifyData->security_status & BIT1) ? 1 : 0;
419 IfrData->SecurityStatus.Locked = (IdentifyData->security_status & BIT2) ? 1 : 0;
420 IfrData->SecurityStatus.Frozen = (IdentifyData->security_status & BIT3) ? 1 : 0;
421 IfrData->SecurityStatus.UserPasswordStatus = IfrData->SecurityStatus.Enabled;
422 IfrData->SecurityStatus.MasterPasswordStatus = IfrData->SecurityStatus.Supported;
423
424 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Supported = %x\n", IfrData->SecurityStatus.Supported));
425 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Enabled = %x\n", IfrData->SecurityStatus.Enabled));
426 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Locked = %x\n", IfrData->SecurityStatus.Locked));
427 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Frozen = %x\n", IfrData->SecurityStatus.Frozen));
428 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.UserPasswordStatus = %x\n", IfrData->SecurityStatus.UserPasswordStatus));
429 DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.MasterPasswordStatus = %x\n", IfrData->SecurityStatus.MasterPasswordStatus));
430}
431
441VOID
442EFIAPI
444 EFI_EVENT Event,
445 VOID *Context
446 )
447{
448 LIST_ENTRY *Entry;
449 HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry;
450 EFI_STATUS Status;
451 ATA_IDENTIFY_DATA IdentifyData;
452
453 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
454
455 mHddPasswordEndOfDxe = TRUE;
456
457 if (mHddPasswordRequestVariable != NULL) {
458 //
459 // Free the HDD password request variable buffer here
460 // as the HDD password requests should have been processed.
461 //
462 FreePool (mHddPasswordRequestVariable);
463 mHddPasswordRequestVariable = NULL;
464 mHddPasswordRequestVariableSize = 0;
465 }
466
467 //
468 // If no any device, return directly.
469 //
470 if (IsListEmpty (&mHddPasswordConfigFormList)) {
471 gBS->CloseEvent (Event);
472 return;
473 }
474
476
477 //
478 // Zero passsword and freeze lock device.
479 //
480 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
481 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
482
483 ZeroMem (ConfigFormEntry->Password, HDD_PASSWORD_MAX_LENGTH);
484
485 //
486 // Check whether need send freeze lock command.
487 // Below device will be froze:
488 // 1. Device not enable password.
489 // 2. Device enable password and unlocked.
490 //
491 if ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
492 (ConfigFormEntry->IfrData.SecurityStatus.Locked == 0) &&
493 (ConfigFormEntry->IfrData.SecurityStatus.Frozen == 0))
494 {
495 Status = FreezeLockDevice (ConfigFormEntry->AtaPassThru, ConfigFormEntry->Port, ConfigFormEntry->PortMultiplierPort);
496 DEBUG ((DEBUG_INFO, "FreezeLockDevice return %r!\n", Status));
497 Status = GetHddDeviceIdentifyData (
498 ConfigFormEntry->AtaPassThru,
499 ConfigFormEntry->Port,
500 ConfigFormEntry->PortMultiplierPort,
501 &IdentifyData
502 );
503 GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
504 }
505 }
506
507 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
508
509 gBS->CloseEvent (Event);
510}
511
518VOID
520 IN OUT UINT8 *SaltValue
521 )
522{
523 RandomSeed (NULL, 0);
524 RandomBytes (SaltValue, PASSWORD_SALT_SIZE);
525}
526
539BOOLEAN
541 IN UINT8 *Buffer,
542 IN UINTN BufferSize,
543 IN UINT8 *SaltValue,
544 OUT UINT8 *Credential
545 )
546{
547 BOOLEAN Status;
548 UINTN HashSize;
549 VOID *Hash;
550 VOID *HashData;
551
552 Hash = NULL;
553 HashData = NULL;
554 Status = FALSE;
555
556 HashSize = Sha256GetContextSize ();
557 Hash = AllocateZeroPool (HashSize);
558 ASSERT (Hash != NULL);
559 if (Hash == NULL) {
560 goto Done;
561 }
562
563 Status = Sha256Init (Hash);
564 if (!Status) {
565 goto Done;
566 }
567
568 HashData = AllocateZeroPool (PASSWORD_SALT_SIZE + BufferSize);
569 ASSERT (HashData != NULL);
570 if (HashData == NULL) {
571 goto Done;
572 }
573
574 CopyMem (HashData, SaltValue, PASSWORD_SALT_SIZE);
575 CopyMem ((UINT8 *)HashData + PASSWORD_SALT_SIZE, Buffer, BufferSize);
576
577 Status = Sha256Update (Hash, HashData, PASSWORD_SALT_SIZE + BufferSize);
578 if (!Status) {
579 goto Done;
580 }
581
582 Status = Sha256Final (Hash, Credential);
583
584Done:
585 if (Hash != NULL) {
586 FreePool (Hash);
587 }
588
589 if (HashData != NULL) {
590 ZeroMem (HashData, PASSWORD_SALT_SIZE + BufferSize);
591 FreePool (HashData);
592 }
593
594 return Status;
595}
596
605VOID
607 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry,
608 IN CHAR8 *Password
609 )
610{
611 EFI_STATUS Status;
612 HDD_PASSWORD_VARIABLE *TempVariable;
613 UINTN TempVariableSize;
614 HDD_PASSWORD_VARIABLE *NextNode;
615 HDD_PASSWORD_VARIABLE *Variable;
616 UINTN VariableSize;
617 HDD_PASSWORD_VARIABLE *NewVariable;
618 UINTN NewVariableSize;
619 BOOLEAN Delete;
620 BOOLEAN HashOk;
621 UINT8 HashData[SHA256_DIGEST_SIZE];
622 UINT8 SaltData[PASSWORD_SALT_SIZE];
623
624 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
625
626 Delete = FALSE;
627 if (!PasswordIsFullZero (Password)) {
628 //
629 // It is Set/Update HDD Password.
630 //
631 ZeroMem (HashData, sizeof (HashData));
632 ZeroMem (SaltData, sizeof (SaltData));
633 GenSalt (SaltData);
634 HashOk = GenerateCredential ((UINT8 *)Password, HDD_PASSWORD_MAX_LENGTH, SaltData, HashData);
635 if (!HashOk) {
636 DEBUG ((DEBUG_INFO, "GenerateCredential failed\n"));
637 return;
638 }
639 } else {
640 //
641 // It is Disable HDD Password.
642 // Go to delete the variable node for the HDD password device.
643 //
644 Delete = TRUE;
645 }
646
647 Variable = NULL;
648 VariableSize = 0;
649 NewVariable = NULL;
650 NewVariableSize = 0;
651
652 Status = GetVariable2 (
653 HDD_PASSWORD_VARIABLE_NAME,
654 &mHddPasswordVendorGuid,
655 (VOID **)&Variable,
656 &VariableSize
657 );
658 if (Delete) {
659 if (!EFI_ERROR (Status) && (Variable != NULL)) {
660 TempVariable = Variable;
661 TempVariableSize = VariableSize;
662 while (TempVariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
663 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
664 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
665 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
666 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
667 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
668 {
669 //
670 // Found the node for the HDD password device.
671 // Delete the node.
672 //
673 NextNode = TempVariable + 1;
674 CopyMem (TempVariable, NextNode, (UINTN)Variable + VariableSize - (UINTN)NextNode);
675 NewVariable = Variable;
676 NewVariableSize = VariableSize - sizeof (HDD_PASSWORD_VARIABLE);
677 break;
678 }
679
680 TempVariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
681 TempVariable += 1;
682 }
683
684 if (NewVariable == NULL) {
685 DEBUG ((DEBUG_INFO, "The variable node for the HDD password device is not found\n"));
686 }
687 } else {
688 DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", Status));
689 }
690 } else {
691 if (!EFI_ERROR (Status) && (Variable != NULL)) {
692 TempVariable = Variable;
693 TempVariableSize = VariableSize;
694 while (TempVariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
695 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
696 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
697 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
698 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
699 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
700 {
701 //
702 // Found the node for the HDD password device.
703 // Update the node.
704 //
705 CopyMem (TempVariable->PasswordHash, HashData, sizeof (HashData));
706 CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltData));
707 NewVariable = Variable;
708 NewVariableSize = VariableSize;
709 break;
710 }
711
712 TempVariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
713 TempVariable += 1;
714 }
715
716 if (NewVariable == NULL) {
717 //
718 // The node for the HDD password device is not found.
719 // Create node for the HDD password device.
720 //
721 NewVariableSize = VariableSize + sizeof (HDD_PASSWORD_VARIABLE);
722 NewVariable = AllocateZeroPool (NewVariableSize);
723 ASSERT (NewVariable != NULL);
724 CopyMem (NewVariable, Variable, VariableSize);
725 TempVariable = (HDD_PASSWORD_VARIABLE *)((UINTN)NewVariable + VariableSize);
726 TempVariable->Device.Bus = (UINT8)ConfigFormEntry->Bus;
727 TempVariable->Device.Device = (UINT8)ConfigFormEntry->Device;
728 TempVariable->Device.Function = (UINT8)ConfigFormEntry->Function;
729 TempVariable->Device.Port = ConfigFormEntry->Port;
730 TempVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
731 CopyMem (TempVariable->PasswordHash, HashData, sizeof (HashData));
732 CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltData));
733 }
734 } else {
735 NewVariableSize = sizeof (HDD_PASSWORD_VARIABLE);
736 NewVariable = AllocateZeroPool (NewVariableSize);
737 ASSERT (NewVariable != NULL);
738 NewVariable->Device.Bus = (UINT8)ConfigFormEntry->Bus;
739 NewVariable->Device.Device = (UINT8)ConfigFormEntry->Device;
740 NewVariable->Device.Function = (UINT8)ConfigFormEntry->Function;
741 NewVariable->Device.Port = ConfigFormEntry->Port;
742 NewVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
743 CopyMem (NewVariable->PasswordHash, HashData, sizeof (HashData));
744 CopyMem (NewVariable->PasswordSalt, SaltData, sizeof (SaltData));
745 }
746 }
747
748 if (NewVariable != NULL) {
749 Status = gRT->SetVariable (
750 HDD_PASSWORD_VARIABLE_NAME,
751 &mHddPasswordVendorGuid,
752 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
753 NewVariableSize,
754 NewVariable
755 );
756 if (EFI_ERROR (Status)) {
757 DEBUG ((DEBUG_INFO, "HddPassword variable set failed (%r)\n", Status));
758 }
759 }
760
761 if (NewVariable != Variable) {
762 FreePool (NewVariable);
763 }
764
765 if (Variable != NULL) {
766 FreePool (Variable);
767 }
768
769 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
770}
771
783BOOLEAN
785 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry,
786 OUT HDD_PASSWORD_VARIABLE *HddPasswordVariable
787 )
788{
789 EFI_STATUS Status;
790 HDD_PASSWORD_VARIABLE *TempVariable;
791 HDD_PASSWORD_VARIABLE *Variable;
792 UINTN VariableSize;
793 BOOLEAN Found;
794
795 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
796
797 Variable = NULL;
798 VariableSize = 0;
799
800 Status = GetVariable2 (
801 HDD_PASSWORD_VARIABLE_NAME,
802 &mHddPasswordVendorGuid,
803 (VOID **)&Variable,
804 &VariableSize
805 );
806 if (EFI_ERROR (Status) || (Variable == NULL)) {
807 DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", Status));
808 return FALSE;
809 }
810
811 Found = FALSE;
812 TempVariable = Variable;
813 while (VariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
814 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
815 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
816 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
817 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
818 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
819 {
820 //
821 // Found the node for the HDD password device.
822 // Get the node.
823 //
824 CopyMem (HddPasswordVariable, TempVariable, sizeof (HDD_PASSWORD_VARIABLE));
825 Found = TRUE;
826 break;
827 }
828
829 VariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
830 TempVariable += 1;
831 }
832
833 FreePool (Variable);
834
835 if (!Found) {
836 DEBUG ((DEBUG_INFO, "The variable node for the HDD password device is not found\n"));
837 }
838
839 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
840
841 return Found;
842}
843
859 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry,
860 IN CHAR8 *Password
861 )
862{
863 EFI_STATUS Status;
864 HDD_PASSWORD_VARIABLE HddPasswordVariable;
865 BOOLEAN HashOk;
866 UINT8 HashData[SHA256_DIGEST_SIZE];
867
868 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
869
870 if (!GetSavedHddPasswordVariable (ConfigFormEntry, &HddPasswordVariable)) {
871 DEBUG ((DEBUG_INFO, "GetSavedHddPasswordVariable failed\n"));
872 return EFI_NOT_FOUND;
873 }
874
875 ZeroMem (HashData, sizeof (HashData));
876 HashOk = GenerateCredential ((UINT8 *)Password, HDD_PASSWORD_MAX_LENGTH, HddPasswordVariable.PasswordSalt, HashData);
877 if (!HashOk) {
878 DEBUG ((DEBUG_INFO, "GenerateCredential failed\n"));
879 return EFI_DEVICE_ERROR;
880 }
881
882 if (CompareMem (HddPasswordVariable.PasswordHash, HashData, sizeof (HashData)) != 0) {
883 Status = EFI_INVALID_PARAMETER;
884 } else {
885 Status = EFI_SUCCESS;
886 }
887
888 DEBUG ((DEBUG_INFO, "%a() - exit (%r)\n", __func__, Status));
889 return Status;
890}
891
910 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
911 IN UINT16 Port,
912 IN UINT16 PortMultiplierPort,
913 IN CHAR8 Identifier,
914 IN CHAR8 *Password
915 )
916{
917 EFI_STATUS Status;
921 UINT8 Buffer[HDD_PAYLOAD];
922
923 if ((AtaPassThru == NULL) || (Password == NULL)) {
924 return EFI_INVALID_PARAMETER;
925 }
926
927 //
928 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
929 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
930 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
931 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
932 // may not be aligned when allocated on stack for some compilers. Hence, we
933 // use the API AllocateAlignedPages to ensure this structure is properly
934 // aligned.
935 //
938 AtaPassThru->Mode->IoAlign
939 );
940 if (Asb == NULL) {
941 return EFI_OUT_OF_RESOURCES;
942 }
943
944 //
945 // Prepare for ATA command block.
946 //
947 ZeroMem (&Acb, sizeof (Acb));
948 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
949 Acb.AtaCommand = ATA_SECURITY_UNLOCK_CMD;
950 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
951
952 //
953 // Prepare for ATA pass through packet.
954 //
955 ZeroMem (&Packet, sizeof (Packet));
956 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
957 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
958 Packet.Asb = Asb;
959 Packet.Acb = &Acb;
960
961 ((CHAR16 *)Buffer)[0] = Identifier & BIT0;
962 CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);
963
964 Packet.OutDataBuffer = Buffer;
965 Packet.OutTransferLength = sizeof (Buffer);
966 Packet.Timeout = ATA_TIMEOUT;
967
968 Status = AtaPassThru->PassThru (
969 AtaPassThru,
970 Port,
971 PortMultiplierPort,
972 &Packet,
973 NULL
974 );
975 if (!EFI_ERROR (Status) &&
976 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
977 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
978 {
979 Status = EFI_DEVICE_ERROR;
980 }
981
983
984 ZeroMem (Buffer, sizeof (Buffer));
985
986 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
987 return Status;
988}
989
1008 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1009 IN UINT16 Port,
1010 IN UINT16 PortMultiplierPort,
1011 IN CHAR8 Identifier,
1012 IN CHAR8 *Password
1013 )
1014{
1015 EFI_STATUS Status;
1019 UINT8 Buffer[HDD_PAYLOAD];
1020
1021 if ((AtaPassThru == NULL) || (Password == NULL)) {
1022 return EFI_INVALID_PARAMETER;
1023 }
1024
1025 //
1026 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
1027 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
1028 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
1029 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
1030 // may not be aligned when allocated on stack for some compilers. Hence, we
1031 // use the API AllocateAlignedPages to ensure this structure is properly
1032 // aligned.
1033 //
1034 Asb = AllocateAlignedPages (
1036 AtaPassThru->Mode->IoAlign
1037 );
1038 if (Asb == NULL) {
1039 return EFI_OUT_OF_RESOURCES;
1040 }
1041
1042 //
1043 // Prepare for ATA command block.
1044 //
1045 ZeroMem (&Acb, sizeof (Acb));
1046 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
1047 Acb.AtaCommand = ATA_SECURITY_DIS_PASSWORD_CMD;
1048 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
1049
1050 //
1051 // Prepare for ATA pass through packet.
1052 //
1053 ZeroMem (&Packet, sizeof (Packet));
1054 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
1055 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
1056 Packet.Asb = Asb;
1057 Packet.Acb = &Acb;
1058
1059 ((CHAR16 *)Buffer)[0] = Identifier & BIT0;
1060 CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);
1061
1062 Packet.OutDataBuffer = Buffer;
1063 Packet.OutTransferLength = sizeof (Buffer);
1064 Packet.Timeout = ATA_TIMEOUT;
1065
1066 Status = AtaPassThru->PassThru (
1067 AtaPassThru,
1068 Port,
1069 PortMultiplierPort,
1070 &Packet,
1071 NULL
1072 );
1073 if (!EFI_ERROR (Status) &&
1074 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
1075 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
1076 {
1077 Status = EFI_DEVICE_ERROR;
1078 }
1079
1081
1082 ZeroMem (Buffer, sizeof (Buffer));
1083
1084 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
1085 return Status;
1086}
1087
1108 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1109 IN UINT16 Port,
1110 IN UINT16 PortMultiplierPort,
1111 IN CHAR8 Identifier,
1112 IN CHAR8 SecurityLevel,
1113 IN CHAR16 MasterPasswordIdentifier,
1114 IN CHAR8 *Password
1115 )
1116{
1117 EFI_STATUS Status;
1121 UINT8 Buffer[HDD_PAYLOAD];
1122
1123 if ((AtaPassThru == NULL) || (Password == NULL)) {
1124 return EFI_INVALID_PARAMETER;
1125 }
1126
1127 //
1128 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
1129 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
1130 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
1131 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
1132 // may not be aligned when allocated on stack for some compilers. Hence, we
1133 // use the API AllocateAlignedPages to ensure this structure is properly
1134 // aligned.
1135 //
1136 Asb = AllocateAlignedPages (
1138 AtaPassThru->Mode->IoAlign
1139 );
1140 if (Asb == NULL) {
1141 return EFI_OUT_OF_RESOURCES;
1142 }
1143
1144 //
1145 // Prepare for ATA command block.
1146 //
1147 ZeroMem (&Acb, sizeof (Acb));
1148 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
1149 Acb.AtaCommand = ATA_SECURITY_SET_PASSWORD_CMD;
1150 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
1151
1152 //
1153 // Prepare for ATA pass through packet.
1154 //
1155 ZeroMem (&Packet, sizeof (Packet));
1156 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
1157 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
1158 Packet.Asb = Asb;
1159 Packet.Acb = &Acb;
1160
1161 ((CHAR16 *)Buffer)[0] = (Identifier | (UINT16)(SecurityLevel << 8)) & (BIT0 | BIT8);
1162 CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);
1163 if ((Identifier & BIT0) != 0) {
1164 ((CHAR16 *)Buffer)[17] = MasterPasswordIdentifier;
1165 }
1166
1167 Packet.OutDataBuffer = Buffer;
1168 Packet.OutTransferLength = sizeof (Buffer);
1169 Packet.Timeout = ATA_TIMEOUT;
1170
1171 Status = AtaPassThru->PassThru (
1172 AtaPassThru,
1173 Port,
1174 PortMultiplierPort,
1175 &Packet,
1176 NULL
1177 );
1178 if (!EFI_ERROR (Status) &&
1179 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
1180 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
1181 {
1182 Status = EFI_DEVICE_ERROR;
1183 }
1184
1186
1187 ZeroMem (Buffer, sizeof (Buffer));
1188
1189 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
1190 return Status;
1191}
1192
1200VOID
1202 IN ATA_IDENTIFY_DATA *IdentifyData,
1203 IN OUT CHAR16 *String
1204 )
1205{
1206 UINTN Index;
1207
1208 //
1209 // Swap the byte order in the original module name.
1210 // From Ata spec, the maximum length is 40 bytes.
1211 //
1212 for (Index = 0; Index < 40; Index += 2) {
1213 String[Index] = IdentifyData->ModelName[Index + 1];
1214 String[Index + 1] = IdentifyData->ModelName[Index];
1215 }
1216
1217 //
1218 // Chap it off after 20 characters
1219 //
1220 String[20] = L'\0';
1221
1222 return;
1223}
1224
1238 IN CHAR16 *PopUpString1,
1239 IN CHAR16 *PopUpString2,
1240 IN OUT CHAR8 *Password
1241 )
1242{
1243 EFI_INPUT_KEY Key;
1244 UINTN Length;
1245 CHAR16 Mask[HDD_PASSWORD_MAX_LENGTH + 1];
1246 CHAR16 Unicode[HDD_PASSWORD_MAX_LENGTH + 1];
1247 CHAR8 Ascii[HDD_PASSWORD_MAX_LENGTH + 1];
1248
1249 ZeroMem (Unicode, sizeof (Unicode));
1250 ZeroMem (Ascii, sizeof (Ascii));
1251 ZeroMem (Mask, sizeof (Mask));
1252
1253 gST->ConOut->ClearScreen (gST->ConOut);
1254
1255 Length = 0;
1256 while (TRUE) {
1257 Mask[Length] = L'_';
1258 if (PopUpString2 == NULL) {
1259 CreatePopUp (
1260 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1261 &Key,
1262 PopUpString1,
1263 L"---------------------",
1264 Mask,
1265 NULL
1266 );
1267 } else {
1268 CreatePopUp (
1269 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1270 &Key,
1271 PopUpString1,
1272 PopUpString2,
1273 L"---------------------",
1274 Mask,
1275 NULL
1276 );
1277 }
1278
1279 //
1280 // Check key.
1281 //
1282 if (Key.ScanCode == SCAN_NULL) {
1283 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1284 //
1285 // Add the null terminator.
1286 //
1287 Unicode[Length] = 0;
1288 break;
1289 } else if ((Key.UnicodeChar == CHAR_NULL) ||
1290 (Key.UnicodeChar == CHAR_TAB) ||
1291 (Key.UnicodeChar == CHAR_LINEFEED)
1292 )
1293 {
1294 continue;
1295 } else {
1296 if (Key.UnicodeChar == CHAR_BACKSPACE) {
1297 if (Length > 0) {
1298 Unicode[Length] = 0;
1299 Mask[Length] = 0;
1300 Length--;
1301 }
1302 } else {
1303 Unicode[Length] = Key.UnicodeChar;
1304 Mask[Length] = L'*';
1305 Length++;
1306 if (Length == HDD_PASSWORD_MAX_LENGTH) {
1307 //
1308 // Add the null terminator.
1309 //
1310 Unicode[Length] = 0;
1311 Mask[Length] = 0;
1312 break;
1313 }
1314 }
1315 }
1316 }
1317
1318 if (Key.ScanCode == SCAN_ESC) {
1319 ZeroMem (Unicode, sizeof (Unicode));
1320 ZeroMem (Ascii, sizeof (Ascii));
1321 gST->ConOut->ClearScreen (gST->ConOut);
1322 return EFI_ABORTED;
1323 }
1324 }
1325
1326 UnicodeStrToAsciiStrS (Unicode, Ascii, sizeof (Ascii));
1327 CopyMem (Password, Ascii, HDD_PASSWORD_MAX_LENGTH);
1328 ZeroMem (Unicode, sizeof (Unicode));
1329 ZeroMem (Ascii, sizeof (Ascii));
1330
1331 gST->ConOut->ClearScreen (gST->ConOut);
1332 return EFI_SUCCESS;
1333}
1334
1344VOID
1346 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1347 IN UINT16 Port,
1348 IN UINT16 PortMultiplierPort,
1349 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1350 )
1351{
1352 EFI_STATUS Status;
1353 CHAR16 PopUpString[100];
1354 ATA_IDENTIFY_DATA IdentifyData;
1355 EFI_INPUT_KEY Key;
1356 UINT16 RetryCount;
1357 CHAR8 Password[HDD_PASSWORD_MAX_LENGTH];
1358
1359 RetryCount = 0;
1360
1361 DEBUG ((DEBUG_INFO, "%a()\n", __func__));
1362
1363 UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Unlock: %s", ConfigFormEntry->HddString);
1364
1365 //
1366 // Check the device security status.
1367 //
1368 if ((ConfigFormEntry->IfrData.SecurityStatus.Supported) &&
1369 (ConfigFormEntry->IfrData.SecurityStatus.Enabled))
1370 {
1371 //
1372 // Add PcdSkipHddPasswordPrompt to determin whether to skip password prompt.
1373 // Due to board design, device may not power off during system warm boot, which result in
1374 // security status remain unlocked status, hence we add device security status check here.
1375 //
1376 // If device is in the locked status, device keeps locked and system continues booting.
1377 // If device is in the unlocked status, system is forced shutdown for security concern.
1378 //
1379 if (PcdGetBool (PcdSkipHddPasswordPrompt)) {
1380 if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
1381 return;
1382 } else {
1383 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
1384 }
1385 }
1386
1387 //
1388 // As soon as the HDD password is in enabled state, we pop up a window to unlock hdd
1389 // no matter it's really in locked or unlocked state.
1390 // This way forces user to enter password every time to provide best safety.
1391 //
1392 while (TRUE) {
1393 Status = PopupHddPasswordInputWindows (PopUpString, NULL, Password);
1394 if (!EFI_ERROR (Status)) {
1395 //
1396 // The HDD is in locked state, unlock it by user input.
1397 //
1398 if (!PasswordIsFullZero (Password)) {
1399 if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
1400 Status = UnlockHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, Password);
1401 } else {
1402 //
1403 // Use saved HDD password variable to validate HDD password
1404 // when the device is at frozen state.
1405 //
1406 Status = ValidateHddPassword (ConfigFormEntry, Password);
1407 }
1408 } else {
1409 Status = EFI_INVALID_PARAMETER;
1410 }
1411
1412 if (!EFI_ERROR (Status)) {
1413 CopyMem (ConfigFormEntry->Password, Password, HDD_PASSWORD_MAX_LENGTH);
1414 if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
1415 SaveHddPasswordVariable (ConfigFormEntry, Password);
1416 }
1417
1418 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1419 Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
1420 ASSERT_EFI_ERROR (Status);
1421
1422 //
1423 // Check the device security status again.
1424 //
1425 GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
1426 return;
1427 }
1428
1429 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1430
1431 if (EFI_ERROR (Status)) {
1432 RetryCount++;
1433 if (RetryCount < MAX_HDD_PASSWORD_RETRY_COUNT) {
1434 do {
1435 CreatePopUp (
1436 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1437 &Key,
1438 L"Invalid password.",
1439 L"Press ENTER to retry",
1440 NULL
1441 );
1442 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1443
1444 continue;
1445 } else {
1446 do {
1447 CreatePopUp (
1448 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1449 &Key,
1450 L"Hdd password retry count is expired. Please shutdown the machine.",
1451 L"Press ENTER to shutdown",
1452 NULL
1453 );
1454 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1455
1456 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
1457 break;
1458 }
1459 }
1460 } else if (Status == EFI_ABORTED) {
1461 if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
1462 //
1463 // Current device in the lock status and
1464 // User not input password and press ESC,
1465 // keep device in lock status and continue boot.
1466 //
1467 do {
1468 CreatePopUp (
1469 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1470 &Key,
1471 L"Press ENTER to skip the request and continue boot,",
1472 L"Press ESC to input password again",
1473 NULL
1474 );
1475 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1476
1477 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1478 gST->ConOut->ClearScreen (gST->ConOut);
1479 //
1480 // Keep lock and continue boot.
1481 //
1482 return;
1483 } else {
1484 //
1485 // Let user input password again.
1486 //
1487 continue;
1488 }
1489 } else {
1490 //
1491 // Current device in the unlock status and
1492 // User not input password and press ESC,
1493 // Shutdown the device.
1494 //
1495 do {
1496 CreatePopUp (
1497 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1498 &Key,
1499 L"Press ENTER to shutdown, Press ESC to input password again",
1500 NULL
1501 );
1502 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1503
1504 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1505 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
1506 } else {
1507 //
1508 // Let user input password again.
1509 //
1510 continue;
1511 }
1512 }
1513 }
1514 }
1515 }
1516}
1517
1527VOID
1529 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1530 IN UINT16 Port,
1531 IN UINT16 PortMultiplierPort,
1532 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1533 )
1534{
1535 EFI_STATUS Status;
1536 CHAR16 PopUpString[100];
1537 ATA_IDENTIFY_DATA IdentifyData;
1538 EFI_INPUT_KEY Key;
1539 UINT16 RetryCount;
1540 CHAR8 Password[HDD_PASSWORD_MAX_LENGTH];
1541 CHAR8 PasswordConfirm[HDD_PASSWORD_MAX_LENGTH];
1542
1543 RetryCount = 0;
1544
1545 DEBUG ((DEBUG_INFO, "%a()\n", __func__));
1546
1547 if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
1548 DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry->HddString));
1549 return;
1550 }
1551
1552 if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
1553 DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry->HddString));
1554 return;
1555 }
1556
1557 UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set User Pwd: %s", ConfigFormEntry->HddString);
1558
1559 //
1560 // Check the device security status.
1561 //
1562 if (ConfigFormEntry->IfrData.SecurityStatus.Supported) {
1563 while (TRUE) {
1564 Status = PopupHddPasswordInputWindows (PopUpString, L"Please type in your new password", Password);
1565 if (!EFI_ERROR (Status)) {
1566 Status = PopupHddPasswordInputWindows (PopUpString, L"Please confirm your new password", PasswordConfirm);
1567 if (!EFI_ERROR (Status)) {
1568 if (CompareMem (Password, PasswordConfirm, HDD_PASSWORD_MAX_LENGTH) == 0) {
1569 if (!PasswordIsFullZero (Password)) {
1570 Status = SetHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, 1, 0, Password);
1571 } else {
1572 if (ConfigFormEntry->IfrData.SecurityStatus.Enabled) {
1573 Status = DisableHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, ConfigFormEntry->Password);
1574 } else {
1575 Status = EFI_INVALID_PARAMETER;
1576 }
1577 }
1578
1579 if (!EFI_ERROR (Status)) {
1580 CopyMem (ConfigFormEntry->Password, Password, HDD_PASSWORD_MAX_LENGTH);
1581 SaveHddPasswordVariable (ConfigFormEntry, Password);
1582 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1583 ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
1584 Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
1585 ASSERT_EFI_ERROR (Status);
1586
1587 //
1588 // Check the device security status again.
1589 //
1590 GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
1591 return;
1592 } else {
1593 do {
1594 CreatePopUp (
1595 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1596 &Key,
1597 L"Set/Disable User Pwd failed or invalid password.",
1598 L"Press ENTER to retry",
1599 NULL
1600 );
1601 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1602 }
1603 } else {
1604 do {
1605 CreatePopUp (
1606 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1607 &Key,
1608 L"Passwords are not the same.",
1609 L"Press ENTER to retry",
1610 NULL
1611 );
1612 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1613
1614 Status = EFI_INVALID_PARAMETER;
1615 }
1616 }
1617
1618 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1619 ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
1620
1621 if (EFI_ERROR (Status)) {
1622 RetryCount++;
1623 if (RetryCount >= MAX_HDD_PASSWORD_RETRY_COUNT) {
1624 do {
1625 CreatePopUp (
1626 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1627 &Key,
1628 L"Hdd password retry count is expired.",
1629 L"Press ENTER to skip the request and continue boot",
1630 NULL
1631 );
1632 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1633
1634 gST->ConOut->ClearScreen (gST->ConOut);
1635 return;
1636 }
1637 }
1638 } else if (Status == EFI_ABORTED) {
1639 do {
1640 CreatePopUp (
1641 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1642 &Key,
1643 L"Press ENTER to skip the request and continue boot,",
1644 L"Press ESC to input password again",
1645 NULL
1646 );
1647 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1648
1649 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1650 gST->ConOut->ClearScreen (gST->ConOut);
1651 return;
1652 } else {
1653 //
1654 // Let user input password again.
1655 //
1656 continue;
1657 }
1658 }
1659 }
1660 }
1661}
1662
1672VOID
1674 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1675 IN UINT16 Port,
1676 IN UINT16 PortMultiplierPort,
1677 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1678 )
1679{
1680 EFI_STATUS Status;
1681 CHAR16 PopUpString[100];
1682 EFI_INPUT_KEY Key;
1683 UINT16 RetryCount;
1684 CHAR8 Password[HDD_PASSWORD_MAX_LENGTH];
1685 CHAR8 PasswordConfirm[HDD_PASSWORD_MAX_LENGTH];
1686
1687 RetryCount = 0;
1688
1689 DEBUG ((DEBUG_INFO, "%a()\n", __func__));
1690
1691 if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
1692 DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry->HddString));
1693 return;
1694 }
1695
1696 if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
1697 DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry->HddString));
1698 return;
1699 }
1700
1701 UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set Master Pwd: %s", ConfigFormEntry->HddString);
1702
1703 //
1704 // Check the device security status.
1705 //
1706 if (ConfigFormEntry->IfrData.SecurityStatus.Supported) {
1707 while (TRUE) {
1708 Status = PopupHddPasswordInputWindows (PopUpString, L"Please type in your new password", Password);
1709 if (!EFI_ERROR (Status)) {
1710 Status = PopupHddPasswordInputWindows (PopUpString, L"Please confirm your new password", PasswordConfirm);
1711 if (!EFI_ERROR (Status)) {
1712 if (CompareMem (Password, PasswordConfirm, HDD_PASSWORD_MAX_LENGTH) == 0) {
1713 if (!PasswordIsFullZero (Password)) {
1714 Status = SetHddPassword (AtaPassThru, Port, PortMultiplierPort, 1, 1, 1, Password);
1715 } else {
1716 Status = EFI_INVALID_PARAMETER;
1717 }
1718
1719 if (!EFI_ERROR (Status)) {
1720 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1721 ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
1722 return;
1723 } else {
1724 do {
1725 CreatePopUp (
1726 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1727 &Key,
1728 L"Set Master Pwd failed or invalid password.",
1729 L"Press ENTER to retry",
1730 NULL
1731 );
1732 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1733 }
1734 } else {
1735 do {
1736 CreatePopUp (
1737 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1738 &Key,
1739 L"Passwords are not the same.",
1740 L"Press ENTER to retry",
1741 NULL
1742 );
1743 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1744
1745 Status = EFI_INVALID_PARAMETER;
1746 }
1747 }
1748
1749 ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
1750 ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
1751
1752 if (EFI_ERROR (Status)) {
1753 RetryCount++;
1754 if (RetryCount >= MAX_HDD_PASSWORD_RETRY_COUNT) {
1755 do {
1756 CreatePopUp (
1757 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1758 &Key,
1759 L"Hdd password retry count is expired.",
1760 L"Press ENTER to skip the request and continue boot",
1761 NULL
1762 );
1763 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1764
1765 gST->ConOut->ClearScreen (gST->ConOut);
1766 return;
1767 }
1768 }
1769 } else if (Status == EFI_ABORTED) {
1770 do {
1771 CreatePopUp (
1772 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1773 &Key,
1774 L"Press ENTER to skip the request and continue boot,",
1775 L"Press ESC to input password again",
1776 NULL
1777 );
1778 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1779
1780 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1781 gST->ConOut->ClearScreen (gST->ConOut);
1782 return;
1783 } else {
1784 //
1785 // Let user input password again.
1786 //
1787 continue;
1788 }
1789 }
1790 }
1791 }
1792}
1793
1803VOID
1805 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
1806 IN UINT16 Port,
1807 IN UINT16 PortMultiplierPort,
1808 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1809 )
1810{
1811 EFI_STATUS Status;
1812 HDD_PASSWORD_REQUEST_VARIABLE *TempVariable;
1814 UINTN VariableSize;
1815
1816 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
1817
1818 if (mHddPasswordRequestVariable == NULL) {
1819 Status = GetVariable2 (
1820 HDD_PASSWORD_REQUEST_VARIABLE_NAME,
1821 &mHddPasswordVendorGuid,
1822 (VOID **)&Variable,
1823 &VariableSize
1824 );
1825 if (EFI_ERROR (Status) || (Variable == NULL)) {
1826 return;
1827 }
1828
1829 mHddPasswordRequestVariable = Variable;
1830 mHddPasswordRequestVariableSize = VariableSize;
1831
1832 //
1833 // Delete the HDD password request variable.
1834 //
1835 Status = gRT->SetVariable (
1836 HDD_PASSWORD_REQUEST_VARIABLE_NAME,
1837 &mHddPasswordVendorGuid,
1838 0,
1839 0,
1840 NULL
1841 );
1842 ASSERT_EFI_ERROR (Status);
1843 } else {
1844 Variable = mHddPasswordRequestVariable;
1845 VariableSize = mHddPasswordRequestVariableSize;
1846 }
1847
1848 //
1849 // Process the HDD password requests.
1850 //
1851 TempVariable = Variable;
1852 while (VariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
1853 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
1854 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
1855 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
1856 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
1857 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
1858 {
1859 //
1860 // Found the node for the HDD password device.
1861 //
1862 if (TempVariable->Request.UserPassword != 0) {
1863 ProcessHddPasswordRequestSetUserPwd (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
1864 }
1865
1866 if (TempVariable->Request.MasterPassword != 0) {
1867 ProcessHddPasswordRequestSetMasterPwd (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
1868 }
1869
1870 break;
1871 }
1872
1873 VariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
1874 TempVariable += 1;
1875 }
1876
1877 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
1878}
1879
1886VOID
1888 IN OUT HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1889 )
1890{
1891 EFI_STATUS Status;
1892 HDD_PASSWORD_REQUEST_VARIABLE *TempVariable;
1894 UINTN VariableSize;
1895
1896 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
1897
1898 Variable = NULL;
1899 VariableSize = 0;
1900
1901 Status = GetVariable2 (
1902 HDD_PASSWORD_REQUEST_VARIABLE_NAME,
1903 &mHddPasswordVendorGuid,
1904 (VOID **)&Variable,
1905 &VariableSize
1906 );
1907 if (EFI_ERROR (Status) || (Variable == NULL)) {
1908 return;
1909 }
1910
1911 TempVariable = Variable;
1912 while (VariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
1913 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
1914 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
1915 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
1916 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
1917 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
1918 {
1919 //
1920 // Found the node for the HDD password device.
1921 // Get the HDD password request.
1922 //
1923 CopyMem (&ConfigFormEntry->IfrData.Request, &TempVariable->Request, sizeof (HDD_PASSWORD_REQUEST));
1924 DEBUG ((
1925 DEBUG_INFO,
1926 "HddPasswordRequest got: 0x%x\n",
1927 ConfigFormEntry->IfrData.Request
1928 ));
1929 break;
1930 }
1931
1932 VariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
1933 TempVariable += 1;
1934 }
1935
1936 FreePool (Variable);
1937
1938 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
1939}
1940
1947VOID
1949 IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry
1950 )
1951{
1952 EFI_STATUS Status;
1953 HDD_PASSWORD_REQUEST_VARIABLE *TempVariable;
1954 UINTN TempVariableSize;
1956 UINTN VariableSize;
1957 HDD_PASSWORD_REQUEST_VARIABLE *NewVariable;
1958 UINTN NewVariableSize;
1959
1960 DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));
1961
1962 DEBUG ((
1963 DEBUG_INFO,
1964 "HddPasswordRequest to save: 0x%x\n",
1965 ConfigFormEntry->IfrData.Request
1966 ));
1967
1968 Variable = NULL;
1969 VariableSize = 0;
1970 NewVariable = NULL;
1971 NewVariableSize = 0;
1972
1973 Status = GetVariable2 (
1974 HDD_PASSWORD_REQUEST_VARIABLE_NAME,
1975 &mHddPasswordVendorGuid,
1976 (VOID **)&Variable,
1977 &VariableSize
1978 );
1979 if (!EFI_ERROR (Status) && (Variable != NULL)) {
1980 TempVariable = Variable;
1981 TempVariableSize = VariableSize;
1982 while (TempVariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
1983 if ((TempVariable->Device.Bus == ConfigFormEntry->Bus) &&
1984 (TempVariable->Device.Device == ConfigFormEntry->Device) &&
1985 (TempVariable->Device.Function == ConfigFormEntry->Function) &&
1986 (TempVariable->Device.Port == ConfigFormEntry->Port) &&
1987 (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
1988 {
1989 //
1990 // Found the node for the HDD password device.
1991 // Update the HDD password request.
1992 //
1993 CopyMem (&TempVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
1994 NewVariable = Variable;
1995 NewVariableSize = VariableSize;
1996 break;
1997 }
1998
1999 TempVariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
2000 TempVariable += 1;
2001 }
2002
2003 if (NewVariable == NULL) {
2004 //
2005 // The node for the HDD password device is not found.
2006 // Create node for the HDD password device.
2007 //
2008 NewVariableSize = VariableSize + sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
2009 NewVariable = AllocateZeroPool (NewVariableSize);
2010 ASSERT (NewVariable != NULL);
2011 CopyMem (NewVariable, Variable, VariableSize);
2012 TempVariable = (HDD_PASSWORD_REQUEST_VARIABLE *)((UINTN)NewVariable + VariableSize);
2013 TempVariable->Device.Bus = (UINT8)ConfigFormEntry->Bus;
2014 TempVariable->Device.Device = (UINT8)ConfigFormEntry->Device;
2015 TempVariable->Device.Function = (UINT8)ConfigFormEntry->Function;
2016 TempVariable->Device.Port = ConfigFormEntry->Port;
2017 TempVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
2018 CopyMem (&TempVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
2019 }
2020 } else {
2021 NewVariableSize = sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
2022 NewVariable = AllocateZeroPool (NewVariableSize);
2023 ASSERT (NewVariable != NULL);
2024 NewVariable->Device.Bus = (UINT8)ConfigFormEntry->Bus;
2025 NewVariable->Device.Device = (UINT8)ConfigFormEntry->Device;
2026 NewVariable->Device.Function = (UINT8)ConfigFormEntry->Function;
2027 NewVariable->Device.Port = ConfigFormEntry->Port;
2028 NewVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
2029 CopyMem (&NewVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
2030 }
2031
2032 Status = gRT->SetVariable (
2033 HDD_PASSWORD_REQUEST_VARIABLE_NAME,
2034 &mHddPasswordVendorGuid,
2035 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
2036 NewVariableSize,
2037 NewVariable
2038 );
2039 if (EFI_ERROR (Status)) {
2040 DEBUG ((DEBUG_INFO, "HddPasswordRequest variable set failed (%r)\n", Status));
2041 }
2042
2043 if (NewVariable != Variable) {
2044 FreePool (NewVariable);
2045 }
2046
2047 if (Variable != NULL) {
2048 FreePool (Variable);
2049 }
2050
2051 DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
2052}
2053
2063 IN UINT32 Index
2064 )
2065{
2066 LIST_ENTRY *Entry;
2067 UINT32 CurrentIndex;
2068 HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry;
2069
2070 CurrentIndex = 0;
2071 ConfigFormEntry = NULL;
2072
2073 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
2074 if (CurrentIndex == Index) {
2075 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
2076 break;
2077 }
2078
2079 CurrentIndex++;
2080 }
2081
2082 return ConfigFormEntry;
2083}
2084
2148EFIAPI
2151 IN CONST EFI_STRING Request,
2152 OUT EFI_STRING *Progress,
2153 OUT EFI_STRING *Results
2154 )
2155{
2156 EFI_STATUS Status;
2157 UINTN BufferSize;
2158 HDD_PASSWORD_CONFIG *IfrData;
2160 EFI_STRING ConfigRequestHdr;
2161 EFI_STRING ConfigRequest;
2162 BOOLEAN AllocatedRequest;
2163 UINTN Size;
2164
2165 if ((Progress == NULL) || (Results == NULL)) {
2166 return EFI_INVALID_PARAMETER;
2167 }
2168
2169 *Progress = Request;
2170 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mHddPasswordVendorGuid, mHddPasswordVendorStorageName)) {
2171 return EFI_NOT_FOUND;
2172 }
2173
2174 ConfigRequestHdr = NULL;
2175 ConfigRequest = NULL;
2176 AllocatedRequest = FALSE;
2177 Size = 0;
2178
2179 Private = HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This);
2180 IfrData = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG));
2181 ASSERT (IfrData != NULL);
2182 if (Private->Current != NULL) {
2183 CopyMem (IfrData, &Private->Current->IfrData, sizeof (HDD_PASSWORD_CONFIG));
2184 }
2185
2186 //
2187 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
2188 //
2189 BufferSize = sizeof (HDD_PASSWORD_CONFIG);
2190 ConfigRequest = Request;
2191 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
2192 //
2193 // Request has no request element, construct full request string.
2194 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
2195 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
2196 //
2197 ConfigRequestHdr = HiiConstructConfigHdr (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, Private->DriverHandle);
2198 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
2199 ConfigRequest = AllocateZeroPool (Size);
2200 ASSERT (ConfigRequest != NULL);
2201 AllocatedRequest = TRUE;
2202 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
2203 FreePool (ConfigRequestHdr);
2204 }
2205
2206 Status = gHiiConfigRouting->BlockToConfig (
2208 ConfigRequest,
2209 (UINT8 *)IfrData,
2210 BufferSize,
2211 Results,
2212 Progress
2213 );
2214 FreePool (IfrData);
2215 //
2216 // Free the allocated config request string.
2217 //
2218 if (AllocatedRequest) {
2219 FreePool (ConfigRequest);
2220 ConfigRequest = NULL;
2221 }
2222
2223 //
2224 // Set Progress string to the original request string.
2225 //
2226 if (Request == NULL) {
2227 *Progress = NULL;
2228 } else if (StrStr (Request, L"OFFSET") == NULL) {
2229 *Progress = Request + StrLen (Request);
2230 }
2231
2232 return Status;
2233}
2234
2269EFIAPI
2272 IN CONST EFI_STRING Configuration,
2273 OUT EFI_STRING *Progress
2274 )
2275{
2276 if ((Configuration == NULL) || (Progress == NULL)) {
2277 return EFI_INVALID_PARAMETER;
2278 }
2279
2280 //
2281 // Check routing data in <ConfigHdr>.
2282 // Note: if only one Storage is used, then this checking could be skipped.
2283 //
2284 if (!HiiIsConfigHdrMatch (Configuration, &mHddPasswordVendorGuid, mHddPasswordVendorStorageName)) {
2285 *Progress = Configuration;
2286 return EFI_NOT_FOUND;
2287 }
2288
2289 *Progress = Configuration + StrLen (Configuration);
2290 return EFI_SUCCESS;
2291}
2292
2320EFIAPI
2323 IN EFI_BROWSER_ACTION Action,
2324 IN EFI_QUESTION_ID QuestionId,
2325 IN UINT8 Type,
2326 IN EFI_IFR_TYPE_VALUE *Value,
2327 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
2328 )
2329{
2331 EFI_STRING_ID DeviceFormTitleToken;
2332 HDD_PASSWORD_CONFIG *IfrData;
2333 HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry;
2334
2335 if (ActionRequest != NULL) {
2336 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
2337 } else {
2338 return EFI_INVALID_PARAMETER;
2339 }
2340
2341 if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
2342 //
2343 // Do nothing for other UEFI Action. Only do call back when data is changing or changed.
2344 //
2345 return EFI_UNSUPPORTED;
2346 }
2347
2348 Private = HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This);
2349
2350 //
2351 // Retrive data from Browser
2352 //
2353 IfrData = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG));
2354 ASSERT (IfrData != NULL);
2355 if (!HiiGetBrowserData (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), (UINT8 *)IfrData)) {
2356 FreePool (IfrData);
2357 return EFI_NOT_FOUND;
2358 }
2359
2360 switch (QuestionId) {
2361 case KEY_HDD_USER_PASSWORD:
2362 if (Action == EFI_BROWSER_ACTION_CHANGED) {
2363 DEBUG ((DEBUG_INFO, "KEY_HDD_USER_PASSWORD\n"));
2364 ConfigFormEntry = Private->Current;
2365 ConfigFormEntry->IfrData.Request.UserPassword = Value->b;
2366 SaveHddPasswordRequest (ConfigFormEntry);
2367 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
2368 }
2369
2370 break;
2371 case KEY_HDD_MASTER_PASSWORD:
2372 if (Action == EFI_BROWSER_ACTION_CHANGED) {
2373 DEBUG ((DEBUG_INFO, "KEY_HDD_MASTER_PASSWORD\n"));
2374 ConfigFormEntry = Private->Current;
2375 ConfigFormEntry->IfrData.Request.MasterPassword = Value->b;
2376 SaveHddPasswordRequest (ConfigFormEntry);
2377 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
2378 }
2379
2380 break;
2381
2382 default:
2383 if ((QuestionId >= KEY_HDD_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfHddDevices + KEY_HDD_DEVICE_ENTRY_BASE))) {
2384 if (Action == EFI_BROWSER_ACTION_CHANGING) {
2385 //
2386 // In case goto the device configuration form, update the device form title.
2387 //
2388 ConfigFormEntry = HddPasswordGetConfigFormEntryByIndex ((UINT32)(QuestionId - KEY_HDD_DEVICE_ENTRY_BASE));
2389 ASSERT (ConfigFormEntry != NULL);
2390
2391 DeviceFormTitleToken = (EFI_STRING_ID)STR_HDD_SECURITY_HD;
2392 HiiSetString (Private->HiiHandle, DeviceFormTitleToken, ConfigFormEntry->HddString, NULL);
2393
2394 Private->Current = ConfigFormEntry;
2395 CopyMem (IfrData, &ConfigFormEntry->IfrData, sizeof (HDD_PASSWORD_CONFIG));
2396 }
2397 }
2398
2399 break;
2400 }
2401
2402 //
2403 // Pass changed uncommitted data back to Form Browser
2404 //
2405 HiiSetBrowserData (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), (UINT8 *)IfrData, NULL);
2406
2407 FreePool (IfrData);
2408 return EFI_SUCCESS;
2409}
2410
2432 IN EFI_HII_HANDLE HiiHandle,
2433 IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru,
2434 IN EFI_PCI_IO_PROTOCOL *PciIo,
2435 IN EFI_HANDLE Controller,
2436 IN UINTN Bus,
2437 IN UINTN Device,
2438 IN UINTN Function,
2439 IN UINT16 Port,
2440 IN UINT16 PortMultiplierPort
2441 )
2442{
2443 LIST_ENTRY *Entry;
2444 HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry;
2445 BOOLEAN EntryExisted;
2446 EFI_STATUS Status;
2447 VOID *StartOpCodeHandle;
2448 VOID *EndOpCodeHandle;
2449 EFI_IFR_GUID_LABEL *StartLabel;
2450 EFI_IFR_GUID_LABEL *EndLabel;
2451 CHAR16 HddString[40];
2452 ATA_IDENTIFY_DATA IdentifyData;
2453 EFI_DEVICE_PATH_PROTOCOL *AtaDeviceNode;
2454
2455 ConfigFormEntry = NULL;
2456 EntryExisted = FALSE;
2457
2458 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
2459 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
2460
2461 if ((ConfigFormEntry->Bus == Bus) &&
2462 (ConfigFormEntry->Device == Device) &&
2463 (ConfigFormEntry->Function == Function) &&
2464 (ConfigFormEntry->Port == Port) &&
2465 (ConfigFormEntry->PortMultiplierPort == PortMultiplierPort))
2466 {
2467 EntryExisted = TRUE;
2468 break;
2469 }
2470 }
2471
2472 if (!EntryExisted) {
2473 //
2474 // Add a new form.
2475 //
2476 ConfigFormEntry = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG_FORM_ENTRY));
2477 if (ConfigFormEntry == NULL) {
2478 return EFI_OUT_OF_RESOURCES;
2479 }
2480
2481 InitializeListHead (&ConfigFormEntry->Link);
2482 ConfigFormEntry->Controller = Controller;
2483 ConfigFormEntry->Bus = Bus;
2484 ConfigFormEntry->Device = Device;
2485 ConfigFormEntry->Function = Function;
2486 ConfigFormEntry->Port = Port;
2487 ConfigFormEntry->PortMultiplierPort = PortMultiplierPort;
2488 ConfigFormEntry->AtaPassThru = AtaPassThru;
2489
2490 DEBUG ((DEBUG_INFO, "HddPasswordDxe: Create new form for device[%d][%d] at Bus 0x%x Dev 0x%x Func 0x%x\n", Port, PortMultiplierPort, Bus, Device, Function));
2491
2492 //
2493 // Construct the device path for the HDD password device
2494 //
2495 Status = AtaPassThru->BuildDevicePath (
2496 AtaPassThru,
2497 Port,
2498 PortMultiplierPort,
2499 &AtaDeviceNode
2500 );
2501 if (EFI_ERROR (Status)) {
2502 return Status;
2503 }
2504
2505 ConfigFormEntry->DevicePath = AppendDevicePathNode (DevicePathFromHandle (Controller), AtaDeviceNode);
2506 FreePool (AtaDeviceNode);
2507 if (ConfigFormEntry->DevicePath == NULL) {
2508 return EFI_OUT_OF_RESOURCES;
2509 }
2510
2511 //
2512 // Get attached harddisk model number
2513 //
2514 Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
2515 ASSERT_EFI_ERROR (Status);
2516 if (EFI_ERROR (Status)) {
2517 return Status;
2518 }
2519
2520 GetHddDeviceModelNumber (&IdentifyData, HddString);
2521 //
2522 // Compose the HDD title string and help string of this port and create a new EFI_STRING_ID.
2523 //
2524 UnicodeSPrint (ConfigFormEntry->HddString, sizeof (ConfigFormEntry->HddString), L"HDD %d:%s", mNumberOfHddDevices, HddString);
2525 ConfigFormEntry->TitleToken = HiiSetString (HiiHandle, 0, ConfigFormEntry->HddString, NULL);
2526 ConfigFormEntry->TitleHelpToken = HiiSetString (HiiHandle, 0, L"Request to set HDD Password", NULL);
2527
2528 GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
2529
2530 InsertTailList (&mHddPasswordConfigFormList, &ConfigFormEntry->Link);
2531
2532 //
2533 // Init OpCode Handle
2534 //
2535 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2536 ASSERT (StartOpCodeHandle != NULL);
2537
2538 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2539 ASSERT (EndOpCodeHandle != NULL);
2540
2541 //
2542 // Create Hii Extend Label OpCode as the start opcode
2543 //
2544 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
2546 StartLabel->Number = HDD_DEVICE_ENTRY_LABEL;
2547
2548 //
2549 // Create Hii Extend Label OpCode as the end opcode
2550 //
2551 EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
2553 EndLabel->Number = HDD_DEVICE_LABEL_END;
2554
2555 mNumberOfHddDevices = 0;
2556 BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
2557 ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
2558
2560 StartOpCodeHandle, // Container for dynamic created opcodes
2561 FORMID_HDD_DEVICE_FORM, // Target Form ID
2562 ConfigFormEntry->TitleToken, // Prompt text
2563 ConfigFormEntry->TitleHelpToken, // Help text
2564 EFI_IFR_FLAG_CALLBACK, // Question flag
2565 (UINT16)(KEY_HDD_DEVICE_ENTRY_BASE + mNumberOfHddDevices) // Question ID
2566 );
2567
2568 mNumberOfHddDevices++;
2569 }
2570
2572 HiiHandle,
2573 &mHddPasswordVendorGuid,
2574 FORMID_HDD_MAIN_FORM,
2575 StartOpCodeHandle,
2576 EndOpCodeHandle
2577 );
2578
2579 HiiFreeOpCodeHandle (StartOpCodeHandle);
2580 HiiFreeOpCodeHandle (EndOpCodeHandle);
2581
2582 //
2583 // Check if device is locked and prompt for password.
2584 //
2585 HddPasswordRequestPassword (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
2586
2587 //
2588 // Process HDD password request from last boot.
2589 //
2590 ProcessHddPasswordRequest (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
2591 }
2592
2593 return EFI_SUCCESS;
2594}
2595
2606VOID
2607EFIAPI
2609 IN EFI_EVENT Event,
2610 IN VOID *Context
2611 )
2612{
2613 EFI_STATUS Status;
2615 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
2616 UINT16 Port;
2617 UINT16 PortMultiplierPort;
2618 EFI_HANDLE Controller;
2619 EFI_HANDLE *HandleBuffer;
2620 UINTN HandleCount;
2621 UINTN Index;
2622 EFI_PCI_IO_PROTOCOL *PciIo;
2623 UINTN SegNum;
2624 UINTN BusNum;
2625 UINTN DevNum;
2626 UINTN FuncNum;
2627
2628 if (mHddPasswordEndOfDxe) {
2629 gBS->CloseEvent (Event);
2630 return;
2631 }
2632
2633 Private = (HDD_PASSWORD_DXE_PRIVATE_DATA *)Context;
2634
2635 //
2636 // Locate all handles of AtaPassThru protocol
2637 //
2638 Status = gBS->LocateHandleBuffer (
2639 ByProtocol,
2640 &gEfiAtaPassThruProtocolGuid,
2641 NULL,
2642 &HandleCount,
2643 &HandleBuffer
2644 );
2645 if (EFI_ERROR (Status)) {
2646 return;
2647 }
2648
2649 //
2650 // Check attached hard disk status to see if it's locked
2651 //
2652 for (Index = 0; Index < HandleCount; Index += 1) {
2653 Controller = HandleBuffer[Index];
2654 Status = gBS->HandleProtocol (
2655 Controller,
2656 &gEfiAtaPassThruProtocolGuid,
2657 (VOID **)&AtaPassThru
2658 );
2659 if (EFI_ERROR (Status)) {
2660 break;
2661 }
2662
2663 //
2664 // Ignore those logical ATA_PASS_THRU instance.
2665 //
2666 if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL) == 0) {
2667 continue;
2668 }
2669
2670 Status = gBS->HandleProtocol (
2671 Controller,
2672 &gEfiPciIoProtocolGuid,
2673 (VOID **)&PciIo
2674 );
2675 ASSERT_EFI_ERROR (Status);
2676 if (EFI_ERROR (Status)) {
2677 break;
2678 }
2679
2680 Status = PciIo->GetLocation (
2681 PciIo,
2682 &SegNum,
2683 &BusNum,
2684 &DevNum,
2685 &FuncNum
2686 );
2687 ASSERT_EFI_ERROR (Status);
2688 if (EFI_ERROR (Status)) {
2689 break;
2690 }
2691
2692 //
2693 // Assume and only support Segment == 0.
2694 //
2695 ASSERT (SegNum == 0);
2696
2697 //
2698 // traverse all attached harddisk devices to update form and unlock it
2699 //
2700 Port = 0xFFFF;
2701
2702 while (TRUE) {
2703 Status = AtaPassThru->GetNextPort (AtaPassThru, &Port);
2704 if (EFI_ERROR (Status)) {
2705 //
2706 // We cannot find more legal port then we are done.
2707 //
2708 break;
2709 }
2710
2711 PortMultiplierPort = 0xFFFF;
2712 while (TRUE) {
2713 Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
2714 if (EFI_ERROR (Status)) {
2715 //
2716 // We cannot find more legal port multiplier port number for ATA device
2717 // on the port, then we are done.
2718 //
2719 break;
2720 }
2721
2722 //
2723 // Find out the attached harddisk devices.
2724 // Try to add a HDD Password configuration page for the attached devices.
2725 //
2726 gBS->RestoreTPL (TPL_APPLICATION);
2727 Status = HddPasswordConfigUpdateForm (Private->HiiHandle, AtaPassThru, PciIo, Controller, BusNum, DevNum, FuncNum, Port, PortMultiplierPort);
2728 gBS->RaiseTPL (TPL_CALLBACK);
2729 if (EFI_ERROR (Status)) {
2730 break;
2731 }
2732 }
2733 }
2734 }
2735
2736 FreePool (HandleBuffer);
2737 return;
2738}
2739
2752 )
2753{
2754 EFI_STATUS Status;
2756
2757 InitializeListHead (&mHddPasswordConfigFormList);
2758
2760 if (Private == NULL) {
2761 return EFI_OUT_OF_RESOURCES;
2762 }
2763
2764 Private->Signature = HDD_PASSWORD_DXE_PRIVATE_SIGNATURE;
2765
2766 Private->ConfigAccess.ExtractConfig = HddPasswordFormExtractConfig;
2767 Private->ConfigAccess.RouteConfig = HddPasswordFormRouteConfig;
2768 Private->ConfigAccess.Callback = HddPasswordFormCallback;
2769
2770 //
2771 // Install Device Path Protocol and Config Access protocol to driver handle
2772 //
2773 Status = gBS->InstallMultipleProtocolInterfaces (
2774 &Private->DriverHandle,
2775 &gEfiDevicePathProtocolGuid,
2776 &mHddPasswordHiiVendorDevicePath,
2777 &gEfiHiiConfigAccessProtocolGuid,
2778 &Private->ConfigAccess,
2779 NULL
2780 );
2781 ASSERT_EFI_ERROR (Status);
2782 if (EFI_ERROR (Status)) {
2783 FreePool (Private);
2784 return Status;
2785 }
2786
2787 //
2788 // Publish our HII data
2789 //
2790 Private->HiiHandle = HiiAddPackages (
2791 &mHddPasswordVendorGuid,
2792 Private->DriverHandle,
2793 HddPasswordDxeStrings,
2794 HddPasswordBin,
2795 NULL
2796 );
2797 if (Private->HiiHandle == NULL) {
2798 FreePool (Private);
2799 return EFI_OUT_OF_RESOURCES;
2800 }
2801
2802 *Instance = Private;
2803 return Status;
2804}
2805
2816EFIAPI
2818 IN EFI_HANDLE ImageHandle,
2819 IN EFI_SYSTEM_TABLE *SystemTable
2820 )
2821{
2822 EFI_STATUS Status;
2824 VOID *Registration;
2825 EFI_EVENT EndOfDxeEvent;
2826 EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy;
2827
2828 Private = NULL;
2829
2830 //
2831 // Initialize the configuration form of HDD Password.
2832 //
2833 Status = HddPasswordConfigFormInit (&Private);
2834 if (EFI_ERROR (Status)) {
2835 return Status;
2836 }
2837
2838 //
2839 // Register HddPasswordNotificationEvent() notify function.
2840 //
2842 &gEfiAtaPassThruProtocolGuid,
2843 TPL_CALLBACK,
2845 (VOID *)Private,
2846 &Registration
2847 );
2848
2849 Status = gBS->CreateEventEx (
2850 EVT_NOTIFY_SIGNAL,
2851 TPL_CALLBACK,
2853 NULL,
2854 &gEfiEndOfDxeEventGroupGuid,
2855 &EndOfDxeEvent
2856 );
2857 ASSERT_EFI_ERROR (Status);
2858
2859 //
2860 // Make HDD_PASSWORD_VARIABLE_NAME variable read-only.
2861 //
2862 Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
2863 if (!EFI_ERROR (Status)) {
2864 Status = RegisterBasicVariablePolicy (
2865 VariablePolicy,
2866 &mHddPasswordVendorGuid,
2867 HDD_PASSWORD_VARIABLE_NAME,
2868 VARIABLE_POLICY_NO_MIN_SIZE,
2869 VARIABLE_POLICY_NO_MAX_SIZE,
2870 VARIABLE_POLICY_NO_MUST_ATTR,
2871 VARIABLE_POLICY_NO_CANT_ATTR,
2872 VARIABLE_POLICY_TYPE_LOCK_NOW
2873 );
2874 DEBUG ((DEBUG_INFO, "%a(): Lock %s variable (%r)\n", __func__, HDD_PASSWORD_VARIABLE_NAME, Status));
2875 ASSERT_EFI_ERROR (Status);
2876 }
2877
2878 return Status;
2879}
UINT64 UINTN
#define ATA_ERRREG_ABRT
Aborted Command defined from ATA-1.
Definition: Atapi.h:826
#define ATA_STSREG_ERR
Error defined from ATA-1.
Definition: Atapi.h:841
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
Definition: Atapi.h:542
UINTN EFIAPI Sha256GetContextSize(VOID)
Definition: CryptSha256.c:20
BOOLEAN EFIAPI RandomBytes(OUT UINT8 *Output, IN UINTN Size)
Definition: CryptRand.c:76
BOOLEAN EFIAPI Sha256Init(OUT VOID *Sha256Context)
Definition: CryptSha256.c:44
BOOLEAN EFIAPI Sha256Final(IN OUT VOID *Sha256Context, OUT UINT8 *HashValue)
Definition: CryptSha256.c:161
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI RandomSeed(IN CONST UINT8 *Seed OPTIONAL, IN UINTN SeedSize)
Definition: CryptRand.c:36
BOOLEAN EFIAPI Sha256Update(IN OUT VOID *Sha256Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha256.c:113
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2650
#define BASE_LIST_FOR_EACH(Entry, ListHead)
Definition: BaseLib.h:2913
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathInstance(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI FreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
BOOLEAN GetSavedHddPasswordVariable(IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, OUT HDD_PASSWORD_VARIABLE *HddPasswordVariable)
EFI_STATUS ValidateHddPassword(IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, IN CHAR8 *Password)
EFI_STATUS SetHddPassword(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN CHAR8 Identifier, IN CHAR8 SecurityLevel, IN CHAR16 MasterPasswordIdentifier, IN CHAR8 *Password)
EFI_STATUS UnlockHddPassword(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN CHAR8 Identifier, IN CHAR8 *Password)
VOID GenSalt(IN OUT UINT8 *SaltValue)
EFI_STATUS EFIAPI HddPasswordFormRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress)
EFI_STATUS PopupHddPasswordInputWindows(IN CHAR16 *PopUpString1, IN CHAR16 *PopUpString2, IN OUT CHAR8 *Password)
VOID ProcessHddPasswordRequestSetUserPwd(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
EFI_STATUS EFIAPI HddPasswordDxeInit(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS DisableHddPassword(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN CHAR8 Identifier, IN CHAR8 *Password)
VOID HddPasswordRequestPassword(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
VOID SaveDeviceInfo(IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, IN OUT HDD_PASSWORD_DEVICE_INFO *TempDevInfo)
EFI_STATUS EFIAPI HddPasswordFormExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Request, OUT EFI_STRING *Progress, OUT EFI_STRING *Results)
VOID EFIAPI HddPasswordEndOfDxeEventNotify(EFI_EVENT Event, VOID *Context)
VOID GetHddPasswordSecurityStatus(IN ATA_IDENTIFY_DATA *IdentifyData, IN OUT HDD_PASSWORD_CONFIG *IfrData)
VOID SaveHddPasswordRequest(IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
BOOLEAN GenerateCredential(IN UINT8 *Buffer, IN UINTN BufferSize, IN UINT8 *SaltValue, OUT UINT8 *Credential)
EFI_STATUS GetHddDeviceIdentifyData(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN ATA_IDENTIFY_DATA *IdentifyData)
VOID GetHddDeviceModelNumber(IN ATA_IDENTIFY_DATA *IdentifyData, IN OUT CHAR16 *String)
VOID EFIAPI HddPasswordNotificationEvent(IN EFI_EVENT Event, IN VOID *Context)
BOOLEAN PasswordIsFullZero(IN CHAR8 *Password)
EFI_STATUS HddPasswordConfigFormInit(OUT HDD_PASSWORD_DXE_PRIVATE_DATA **Instance)
VOID GetSavedHddPasswordRequest(IN OUT HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
HDD_PASSWORD_CONFIG_FORM_ENTRY * HddPasswordGetConfigFormEntryByIndex(IN UINT32 Index)
VOID ProcessHddPasswordRequestSetMasterPwd(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
VOID BuildHddPasswordDeviceInfo(VOID)
EFI_STATUS EFIAPI HddPasswordFormCallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest)
VOID SaveHddPasswordVariable(IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, IN CHAR8 *Password)
EFI_STATUS FreezeLockDevice(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort)
VOID ProcessHddPasswordRequest(IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry)
EFI_STATUS HddPasswordConfigUpdateForm(IN EFI_HII_HANDLE HiiHandle, IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_HANDLE Controller, IN UINTN Bus, IN UINTN Device, IN UINTN Function, IN UINT16 Port, IN UINT16 PortMultiplierPort)
EFI_STRING EFIAPI HiiConstructConfigHdr(IN CONST EFI_GUID *Guid OPTIONAL, IN CONST CHAR16 *Name OPTIONAL, IN EFI_HANDLE DriverHandle)
Definition: HiiLib.c:723
BOOLEAN EFIAPI HiiGetBrowserData(IN CONST EFI_GUID *VariableGuid OPTIONAL, IN CONST CHAR16 *VariableName OPTIONAL, IN UINTN BufferSize, OUT UINT8 *Buffer)
Definition: HiiLib.c:2872
UINT8 *EFIAPI HiiCreateGotoOpCode(IN VOID *OpCodeHandle, IN EFI_FORM_ID FormId, IN EFI_STRING_ID Prompt, IN EFI_STRING_ID Help, IN UINT8 QuestionFlags, IN EFI_QUESTION_ID QuestionId)
Definition: HiiLib.c:3551
VOID *EFIAPI HiiAllocateOpCodeHandle(VOID)
Definition: HiiLib.c:3051
VOID EFIAPI HiiFreeOpCodeHandle(VOID *OpCodeHandle)
Definition: HiiLib.c:3085
EFI_HII_HANDLE EFIAPI HiiAddPackages(IN CONST EFI_GUID *PackageListGuid, IN EFI_HANDLE DeviceHandle OPTIONAL,...)
Definition: HiiLib.c:141
UINT8 *EFIAPI HiiCreateGuidOpCode(IN VOID *OpCodeHandle, IN CONST EFI_GUID *Guid, IN CONST VOID *GuidOpCode OPTIONAL, IN UINTN OpCodeSize)
Definition: HiiLib.c:3411
BOOLEAN EFIAPI HiiSetBrowserData(IN CONST EFI_GUID *VariableGuid OPTIONAL, IN CONST CHAR16 *VariableName OPTIONAL, IN UINTN BufferSize, IN CONST UINT8 *Buffer, IN CONST CHAR16 *RequestElement OPTIONAL)
Definition: HiiLib.c:2954
EFI_STATUS EFIAPI HiiUpdateForm(IN EFI_HII_HANDLE HiiHandle, IN EFI_GUID *FormSetGuid OPTIONAL, IN EFI_FORM_ID FormId, IN VOID *StartOpCodeHandle, IN VOID *EndOpCodeHandle OPTIONAL)
Definition: HiiLib.c:4410
BOOLEAN EFIAPI HiiIsConfigHdrMatch(IN CONST EFI_STRING ConfigHdr, IN CONST EFI_GUID *Guid OPTIONAL, IN CONST CHAR16 *Name OPTIONAL)
Definition: HiiLib.c:2813
EFI_STRING_ID EFIAPI HiiSetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId OPTIONAL, IN CONST EFI_STRING String, IN CONST CHAR8 *SupportedLanguages OPTIONAL)
Definition: HiiString.c:52
#define EFI_IFR_EXTEND_OP_LABEL
Definition: MdeModuleHii.h:33
RETURN_STATUS EFIAPI SetLockBoxAttributes(IN GUID *Guid, IN UINT64 Attributes)
RETURN_STATUS EFIAPI RestoreLockBox(IN GUID *Guid, IN VOID *Buffer OPTIONAL, IN OUT UINTN *Length OPTIONAL)
RETURN_STATUS EFIAPI UpdateLockBox(IN GUID *Guid, IN UINTN Offset, IN VOID *Buffer, IN UINTN Length)
RETURN_STATUS EFIAPI SaveLockBox(IN GUID *Guid, IN VOID *Buffer, IN UINTN Length)
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define BASE_CR(Record, TYPE, Field)
Definition: Base.h:891
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
Definition: AtaPassThru.h:33
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
EFI_HII_CONFIG_ROUTING_PROTOCOL * gHiiConfigRouting
VOID * EFI_HII_HANDLE
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
VOID EFIAPI CreatePopUp(IN UINTN Attribute, OUT EFI_INPUT_KEY *Key OPTIONAL,...)
Definition: Console.c:393
@ EfiResetShutdown
#define EFI_VARIABLE_NON_VOLATILE
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_ATA_STATUS_BLOCK * Asb
Definition: AtaPassThru.h:114
EFI_ATA_PASS_THRU_LENGTH Length
Definition: AtaPassThru.h:167
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
Definition: AtaPassThru.h:163
EFI_ATA_COMMAND_BLOCK * Acb
Definition: AtaPassThru.h:119
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2064
Definition: Base.h:213