VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex <kavsrf@gmail.com>2016-08-15 17:11:31 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2016-08-15 17:14:26 +0200
commitb87fc6b140772ba3017de311c7063c259424264c (patch)
tree41ad139e7469380704361ae757a155464e8b68e3
parent68ea2f72cfe6a9b34212ced97882e488c73c8f1d (diff)
downloadVeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.tar.gz
VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.zip
First public release. Used by VeraCrypt 1.18.VeraCrypt_1.18_PreRelease
-rw-r--r--DcsBml/DcsBml.c124
-rw-r--r--DcsBml/DcsBml.inf67
-rw-r--r--DcsBoot/DcsBoot.c104
-rw-r--r--DcsBoot/DcsBoot.inf64
-rw-r--r--DcsCfg/DcsCfg.h166
-rw-r--r--DcsCfg/DcsCfg.inf97
-rw-r--r--DcsCfg/DcsCfg.man120
-rw-r--r--DcsCfg/DcsCfgBeep.c47
-rw-r--r--DcsCfg/DcsCfgBlockio.c52
-rw-r--r--DcsCfg/DcsCfgCrypt.c1324
-rw-r--r--DcsCfg/DcsCfgGraphics.c81
-rw-r--r--DcsCfg/DcsCfgMain.c650
-rw-r--r--DcsCfg/DcsCfgSetup.c39
-rw-r--r--DcsCfg/DcsCfgTouch.c95
-rw-r--r--DcsInt/DcsInt.c1057
-rw-r--r--DcsInt/DcsInt.h235
-rw-r--r--DcsInt/DcsInt.inf93
-rw-r--r--DcsInt/DcsIntName.c173
-rw-r--r--DcsPkg.dec29
-rw-r--r--DcsPkg.dsc96
-rw-r--r--DcsPkg.uni6
-rw-r--r--DcsRe/DcsRe.c330
-rw-r--r--DcsRe/DcsRe.inf74
-rw-r--r--Dcs_bld.bat39
-rw-r--r--Include/Library/CommonLib.h540
-rw-r--r--Include/Library/DcsCfgLib.h213
-rw-r--r--Include/Library/GraphLib.h200
-rw-r--r--Include/Library/PasswordLib.h108
-rw-r--r--Include/Protocol/ConsoleControl.h123
-rw-r--r--Include/Protocol/Speaker.h84
-rw-r--r--LegacySpeaker/ComponentName.c134
-rw-r--r--LegacySpeaker/ComponentName.h90
-rw-r--r--LegacySpeaker/LegacySpeaker.c238
-rw-r--r--LegacySpeaker/LegacySpeaker.h101
-rw-r--r--LegacySpeaker/LegacySpeaker.inf46
-rw-r--r--Library/CommonLib/CommonLib.inf65
-rw-r--r--Library/CommonLib/EfiAttrPrint.c477
-rw-r--r--Library/CommonLib/EfiBeep.c69
-rw-r--r--Library/CommonLib/EfiBio.c232
-rw-r--r--Library/CommonLib/EfiConsole.c347
-rw-r--r--Library/CommonLib/EfiExec.c88
-rw-r--r--Library/CommonLib/EfiFile.c350
-rw-r--r--Library/CommonLib/EfiMem.c74
-rw-r--r--Library/CommonLib/EfiTouch.c47
-rw-r--r--Library/CommonLib/EfiUsb.c88
-rw-r--r--Library/CommonLib/EfiVar.c228
-rw-r--r--Library/CommonLib/IA32/EfiCpuHalt.asm19
-rw-r--r--Library/CommonLib/X64/EfiCpuHalt.asm17
-rw-r--r--Library/DcsCfgLib/DcsCfgLib.inf80
-rw-r--r--Library/DcsCfgLib/DcsRandom.c460
-rw-r--r--Library/DcsCfgLib/GptEdit.c935
-rw-r--r--Library/GraphLib/EfiGraph.c670
-rw-r--r--Library/GraphLib/GraphLib.inf43
-rw-r--r--Library/GraphLib/font.c586
-rw-r--r--Library/PasswordLib/ConsolePassword.c128
-rw-r--r--Library/PasswordLib/PasswordLib.inf46
-rw-r--r--Library/PasswordLib/PicturePassword.c629
-rw-r--r--Library/PasswordLib/PlatformID.c266
-rw-r--r--Library/VeraCryptLib/DcsVeraCrypt.c391
-rw-r--r--Library/VeraCryptLib/DcsVeraCrypt.h84
-rw-r--r--Library/VeraCryptLib/VeraCryptLib.inf120
-rw-r--r--Library/VeraCryptLib/llmath.c383
-rw-r--r--Library/VeraCryptLib/mklinks_src.bat112
-rw-r--r--SecureBoot/certs/DCS_key_exchange.crtbin0 -> 1093 bytes
-rw-r--r--SecureBoot/certs/DCS_platform.crtbin0 -> 1341 bytes
-rw-r--r--SecureBoot/certs/DCS_sign.crtbin0 -> 826 bytes
-rw-r--r--SecureBoot/certs/MicCorUEFCA2011_2011-06-27.crtbin0 -> 1556 bytes
-rw-r--r--SecureBoot/certs/MicWinProPCA2011_2011-10-19.crtbin0 -> 1499 bytes
-rw-r--r--SecureBoot/certs/readme.txt3
-rw-r--r--SecureBoot/efi_sign.bat1
-rw-r--r--SecureBoot/readme.txt13
-rw-r--r--SecureBoot/sb_set_siglists.ps122
-rw-r--r--SecureBoot/siglists/DCS_key_exchange_SigList.binbin0 -> 1137 bytes
-rw-r--r--SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.binbin0 -> 1179 bytes
-rw-r--r--SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin.p7bin0 -> 1996 bytes
-rw-r--r--SecureBoot/siglists/DCS_platform_SigList.binbin0 -> 1385 bytes
-rw-r--r--SecureBoot/siglists/DCS_platform_SigList_Serialization.binbin0 -> 1425 bytes
-rw-r--r--SecureBoot/siglists/DCS_platform_SigList_Serialization.bin.p7bin0 -> 1996 bytes
-rw-r--r--SecureBoot/siglists/DCS_sign_SigList.binbin0 -> 870 bytes
-rw-r--r--SecureBoot/siglists/DCS_sign_SigList_Serialization.binbin0 -> 910 bytes
-rw-r--r--SecureBoot/siglists/DCS_sign_SigList_Serialization.bin.p7bin0 -> 1492 bytes
-rw-r--r--SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList.binbin0 -> 1600 bytes
-rw-r--r--SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.binbin0 -> 1640 bytes
-rw-r--r--SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin.p7bin0 -> 1492 bytes
-rw-r--r--SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList.binbin0 -> 1543 bytes
-rw-r--r--SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.binbin0 -> 1583 bytes
-rw-r--r--SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin.p7bin0 -> 1492 bytes
-rw-r--r--bld.bat7
-rw-r--r--setenv.bat46
89 files changed, 14165 insertions, 0 deletions
diff --git a/DcsBml/DcsBml.c b/DcsBml/DcsBml.c
new file mode 100644
index 0000000..3376936
--- /dev/null
+++ b/DcsBml/DcsBml.c
@@ -0,0 +1,124 @@
+/** @file
+ This is DCS boot menu lock application
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Guid/EventGroup.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+
+typedef struct _BML_GLOBALS {
+ UINT64 Signature;
+ UINTN size;
+} BML_GLOBALS, *PBML_GLOBALS;
+
+STATIC PBML_GLOBALS gBmlData = NULL;
+STATIC BOOLEAN BootMenuLocked = TRUE;
+EFI_EVENT mBmlVirtualAddrChangeEvent;
+EFI_SET_VARIABLE orgSetVariable = NULL;
+
+EFI_STATUS
+BmlSetVaribale(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ ) {
+ // DcsBoot remove?
+ if (VariableName != NULL && StrStr(VariableName, L"BootDC5B") == VariableName && DataSize == 0) {
+ BootMenuLocked = FALSE;
+ }
+
+ if (BootMenuLocked) {
+ // Block all Boot*
+ if (VariableName != NULL && StrStr(VariableName, L"Boot") == VariableName) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ return orgSetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
+}
+
+/**
+Fixup internal data so that EFI can be call in virtual mode.
+Call the passed in Child Notify event and convert any pointers in
+lib to virtual mode.
+
+@param[in] Event The Event that is being processed
+@param[in] Context Event Context
+**/
+
+VOID
+EFIAPI
+BmlVirtualNotifyEvent(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EfiConvertPointer(0x0, (VOID**)&gBmlData);
+ EfiConvertPointer(0x0, (VOID**)&orgSetVariable);
+ return;
+}
+
+/**
+The actual entry point for the application.
+
+@param[in] ImageHandle The firmware allocated handle for the EFI image.
+@param[in] SystemTable A pointer to the EFI System Table.
+
+@retval EFI_SUCCESS The entry point executed successfully.
+@retval other Some error occur when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsBmlMain(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS res;
+
+ res = gBS->AllocatePool(
+ EfiRuntimeServicesData,
+ (UINTN) sizeof(BML_GLOBALS),
+ (VOID**)&gBmlData
+ );
+
+ if (EFI_ERROR(res)) {
+ Print(L"Allocate runtime globals %r\n", res);
+ return res;
+ }
+
+ //
+ // Register for the virtual address change event
+ //
+ res = gBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ BmlVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mBmlVirtualAddrChangeEvent
+ );
+
+ if (EFI_ERROR(res)) {
+ Print(L"Register notify %r\n", res);
+ return res;
+ }
+
+ orgSetVariable = gST->RuntimeServices->SetVariable;
+ gST->RuntimeServices->SetVariable = BmlSetVaribale;
+ return EFI_SUCCESS;
+}
diff --git a/DcsBml/DcsBml.inf b/DcsBml/DcsBml.inf
new file mode 100644
index 0000000..10bdfda
--- /dev/null
+++ b/DcsBml/DcsBml.inf
@@ -0,0 +1,67 @@
+## @file
+# This is DCS boot loader application
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsBml
+ FILE_GUID = E0A7843A-828F-4EDC-AC55-75FE3255ABA5
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DcsBmlMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DcsBml.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ UefiLib
+ UefiRuntimeLib
+ UefiBootServicesTableLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiDcsVariableGuid
+ gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+
+[BuildOptions.IA32]
+RELEASE_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+DEBUG_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+NOOPT_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+
+RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+
+[FeaturePcd]
+
+[Pcd]
+
+[Depex]
+ TRUE
diff --git a/DcsBoot/DcsBoot.c b/DcsBoot/DcsBoot.c
new file mode 100644
index 0000000..bccf216
--- /dev/null
+++ b/DcsBoot/DcsBoot.c
@@ -0,0 +1,104 @@
+/** @file
+ This is DCS boot loader application
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+
+EFI_GUID ImagePartGuid;
+EFI_GUID *gEfiExecPartGuid = &ImagePartGuid;
+CHAR16 *gEfiExecCmdDefault = L"\\EFI\\Microsoft\\Boot\\Bootmgfw.efi";
+CHAR16 *gEfiExecCmd = NULL;
+/**
+The actual entry point for the application.
+
+@param[in] ImageHandle The firmware allocated handle for the EFI image.
+@param[in] SystemTable A pointer to the EFI System Table.
+
+@retval EFI_SUCCESS The entry point executed successfully.
+@retval other Some error occur when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsBootMain(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS res;
+ UINTN len;
+ UINT32 attr;
+ InitBio();
+ res = InitFS();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"InitFS %r\n", res);
+ }
+
+ // Load all drivers
+ res = EfiExec(NULL, L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs");
+
+ res = EfiGetPartGUID(gFileRootHandle, &ImagePartGuid);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nStart partition %r\n", res);
+ return res;
+ }
+
+ EfiSetVar(L"DcsExecPartGuid", NULL, &ImagePartGuid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ EfiSetVar(L"DcsExecCmd", NULL, gEfiExecCmdDefault, (StrLen(gEfiExecCmdDefault) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ // Authorize
+ res = EfiExec(NULL, L"\\EFI\\VeraCrypt\\DcsInt.dcs");
+ if (EFI_ERROR(res)) {
+ // ERR_PRINT(L"\nDcsInt.efi %r\n",res);
+ return res;
+ }
+
+ res = EfiGetVar(L"DcsExecPartGuid", NULL, &gEfiExecPartGuid, &len, &attr);
+ if (EFI_ERROR(res)) {
+ gEfiExecPartGuid = &ImagePartGuid;
+ }
+
+ res = EfiGetVar(L"DcsExecCmd", NULL, &gEfiExecCmd, &len, &attr);
+ if (EFI_ERROR(res)) {
+ gEfiExecCmd = gEfiExecCmdDefault;
+ }
+
+ // Find new start partition
+ ConnectAllEfi();
+ InitBio();
+ res = InitFS();
+// OUT_PRINT(L".");
+ res = EfiFindPartByGUID(gEfiExecPartGuid, &gFileRootHandle);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nCan't find start partition %g\n", gEfiExecPartGuid);
+ EfiCpuHalt();
+ }
+// OUT_PRINT(L".");
+ res = FileOpenRoot(gFileRootHandle, &gFileRoot);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nCan't open start partition\n");
+ EfiCpuHalt();
+ }
+// OUT_PRINT(L".");
+ // Try to exec windows loader...
+ res = EfiExec(NULL, gEfiExecCmd);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nStart %s - %r\n", gEfiExecCmd, res);
+ EfiCpuHalt();
+ }
+ ERR_PRINT(L"???%r");
+ EfiCpuHalt();
+ return EFI_INVALID_PARAMETER;
+}
diff --git a/DcsBoot/DcsBoot.inf b/DcsBoot/DcsBoot.inf
new file mode 100644
index 0000000..9459e92
--- /dev/null
+++ b/DcsBoot/DcsBoot.inf
@@ -0,0 +1,64 @@
+## @file
+# This is DCS boot loader application
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsBoot
+ FILE_GUID = DE8AB4B2-EB47-44E1-A4D7-1001E5E9F0A5
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DcsBootMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DcsBoot.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ BaseLib
+ MemoryAllocationLib
+ CommonLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiDcsVariableGuid
+ gEfiFileInfoGuid
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+
+[BuildOptions.IA32]
+RELEASE_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+DEBUG_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+NOOPT_VS2010x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+
+RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs
+[FeaturePcd]
+
+[Pcd]
+
diff --git a/DcsCfg/DcsCfg.h b/DcsCfg/DcsCfg.h
new file mode 100644
index 0000000..2ffd50d
--- /dev/null
+++ b/DcsCfg/DcsCfg.h
@@ -0,0 +1,166 @@
+
+/** @file
+This is DCS configuration tool. (EFI shell application/wizard)
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#ifndef __DcsCfg_h__
+#define __DcsCfg_h__
+
+#include <Uefi.h>
+#include <Uefi/UefiGpt.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Block I/O
+//////////////////////////////////////////////////////////////////////////
+extern UINTN BioIndexStart;
+extern UINTN BioIndexEnd;
+extern BOOLEAN BioSkipPartitions;
+
+void
+BioPrintDevicePath(
+ UINTN bioIndex
+ );
+
+VOID
+PrintBioList();
+
+EFI_STATUS
+BlockRangeWipe(
+ IN EFI_HANDLE h,
+ IN UINT64 start,
+ IN UINT64 end
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// System crypt
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+VolumeEncrypt(
+ IN UINTN index);
+
+EFI_STATUS
+VolumeDecrypt(
+ IN UINTN index);
+
+EFI_STATUS
+OSRestoreKey();
+
+EFI_STATUS
+OSDecrypt();
+
+EFI_STATUS
+VolumeChangePassword(
+ IN UINTN index);
+
+EFI_STATUS
+CreateVolumeHeaderOnDisk(
+ IN UINTN index,
+ OUT VOID **pinfo,
+ OUT EFI_HANDLE *phDisk,
+ OUT UINT64 *sector
+ );
+
+EFI_STATUS
+GptCryptFile(
+ IN BOOLEAN crypt
+ );
+
+EFI_STATUS
+GptEdit(
+ IN UINTN index
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Security regions
+//////////////////////////////////////////////////////////////////////////
+extern UINTN gSecRigonCount;
+
+EFI_STATUS
+SecRigionMark();
+
+EFI_STATUS
+SecRigionWipe();
+
+EFI_STATUS
+SecRigionAdd(
+ IN UINTN regIdx
+ );
+//////////////////////////////////////////////////////////////////////////
+// Set DcsInt parameters
+//////////////////////////////////////////////////////////////////////////
+VOID
+UpdateDcsBoot();
+
+//////////////////////////////////////////////////////////////////////////
+// DCS authorization check
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+IntCheckVolume(
+ UINTN index
+ );
+
+VOID
+DisksAuthCheck();
+
+VOID
+TestAuthAsk();
+
+
+//////////////////////////////////////////////////////////////////////////
+// RUD / USB
+//////////////////////////////////////////////////////////////////////////
+extern UINTN UsbIndex;
+
+VOID
+PrintUsbList();
+
+VOID
+UsbSelect();
+
+//////////////////////////////////////////////////////////////////////////
+// Beep
+//////////////////////////////////////////////////////////////////////////
+VOID
+PrintSpeakerList();
+
+VOID
+TestSpeaker();
+
+//////////////////////////////////////////////////////////////////////////
+// Graphics
+//////////////////////////////////////////////////////////////////////////
+VOID
+PrintGraphList();
+
+//////////////////////////////////////////////////////////////////////////
+// Touch
+//////////////////////////////////////////////////////////////////////////
+extern UINTN TouchIndex;
+
+VOID
+PrintTouchList();
+
+VOID
+TestTouch();
+
+//////////////////////////////////////////////////////////////////////////
+// Interactive setup
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+DcsInteractiveSetup();
+
+
+
+#endif // DcsCfg_h__
diff --git a/DcsCfg/DcsCfg.inf b/DcsCfg/DcsCfg.inf
new file mode 100644
index 0000000..c7218aa
--- /dev/null
+++ b/DcsCfg/DcsCfg.inf
@@ -0,0 +1,97 @@
+## @file
+# This is DCS configuration EFI shell application
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsCfg
+ FILE_GUID = 4F0E068D-2EA1-4014-943C-3E4B86BB0E43
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DcsCfgMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DcsCfg.h
+ DcsCfgMain.c
+ DcsCfgCrypt.c
+ DcsCfgBeep.c
+ DcsCfgGraphics.c
+ DcsCfgBlockio.c
+ DcsCfgTouch.c
+ DcsCfgSetup.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ BaseLib
+ MemoryAllocationLib
+ CommonLib
+ GraphLib
+ PasswordLib
+ DcsCfgLib
+ VeraCryptLib
+ ShellLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiDcsVariableGuid
+ gEfiPartTypeUnusedGuid
+ gEfiPartTypeSystemPartGuid
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+
+[BuildOptions.IA32]
+RELEASE_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+DEBUG_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+NOOPT_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+
+RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+
+[BuildOptions.X64]
+RELEASE_VS2010x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2010x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2010x86_X64_CC_FLAGS = /D_UEFI
+
+RELEASE_VS2015x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2015x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2015x86_X64_CC_FLAGS = /D_UEFI
+
+DEBUG_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+DEBUG_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+[FeaturePcd]
+
+[Pcd]
+
+[Binaries]
+ UEFI_APP|DcsCfg.man|*
diff --git a/DcsCfg/DcsCfg.man b/DcsCfg/DcsCfg.man
new file mode 100644
index 0000000..bb6fda4
--- /dev/null
+++ b/DcsCfg/DcsCfg.man
@@ -0,0 +1,120 @@
+.TH DcsCfg 0 "Configuration tool of DCS"
+.SH NAME
+Configure boot loader parameters and tests EFI environment for compatibility
+.SH SYNOPSIS
+
+DcsCfg -dl
+DcsCfg -dc -ds <BN> -de <BN> -aa [-rnd rnddata]
+DcsCfg -db <BN>
+DcsCfg -aa
+DcsCfg -dec <BN> -aa [-rnd rnddata]
+DcsCfg -ddc <BN> -aa
+DcsCfg -dcp <BN>
+DcsCfg -ul
+DcsCfg -tl
+DcsCfg -tt <TN>
+DcsCfg -gl
+DcsCfg -gd <GN>
+DcsCfg -gm <mode>
+DcsCfg -bl
+DcsCfg -bt
+DcsCfg -setup
+DcsCfg -ds <BN> -pl
+DcsCfg -pf <gpt_file_name> -pl
+DcsCfg -ds <BN> -pf <gpt_file_name> -ps
+DcsCfg -ds <BN> -pf <gpt_file_name> -pa
+DcsCfg -pf <gpt_file_name> -pe -aa
+DcsCfg -pf <gpt_file_name> -pd -aa
+DcsCfg -pf <gpt_file_name> -pmirror <PNB> <PNM> -ps
+DcsCfg -pf <gpt_file_name> -pnt <PNT> -phide <HS> <HE> -ps
+DcsCfg -kp <key_file>
+DcsCfg -ds <BN> -srm <total_security_regions>
+DcsCfg -ds <BN> -srw <total_security_regions>
+DcsCfg -ds <BN> -sra <security_region>
+DcsCfg -ds <BN> -wipe <start> <end>
+
+.SH OPTIONS
+
+ -dl - block device list (order numbers are used in -db and -se)
+ -ds <BN> – select device
+ -de <BN> – end device to check (starts from select)
+ -dc check devices (try to authorize)
+ -db <BN> - boot partition selection
+ -aa - ask authorization parameters
+ -ach - create header on block device
+ -vec <BN> - block device encrypt
+ -vdc <BN> - block device decrypt
+ -vcp <BN> - block device change password
+ -ul - USB device list
+ -tl - touch device
+ -tt <TN> - Test touch device
+ -gl - graphics device list
+ -gd <GN> - graphics device select
+ -gm <mode> - graphics mode select
+ -bl - Beep device list
+ -bt - Beep device test
+ -setup - interactive setup
+ -pl - GPT list
+ -pf <gpt_file_name> - file with GPT
+ -ps - save GPT to file
+ -pa - applay GPT from file to disk
+ -pe - encrypt GPT
+ -pd - decrypt GPT
+ -pnt <PNT> - partition number as template (from -pl)
+ -phide <PHS> <PHE> - hide partions from <PHS> to <PHE>; <PHS> - start sector of hidden partition, <PHE> - end sector of hidden partition
+ -kp <key_file_name> - keys file of platform to save
+ -srm <SRT> - mark disk as security regions container(write CRC of platform to 61 sector); <SRT> - number of possible security regions
+ -srw <SRT> - wipe security regions data with random data (write random data [62, 62 + 256 * SRT]) it has to be free! check first partition start sector!
+ -sra <SRN> - add <gpt_file_name> to security region <SRN>
+ -wipe <SS SE> - write random data to sectors range [SS,SE]
+
+ .SH DESCRIPTION
+
+NOTES:
+This is test tool for DCS developers. Use it with care.
+
+.SH EXAMPLES
+
+EXAMPLES:
+
+ * To list block devices
+ Shell> dcscfg -dl
+
+ * To change password on block device 1
+ Shell> dcscfg -aa -scp 1
+
+ * To list graphics devices
+ Shell> dcscfg -gl
+
+ * To select graphics devices mode 1 on device 1
+ Shell> dcscfg -gd 1 -gm 1
+
+ * To list GPT
+ Shell> dcscfg -ds 1 -pl
+
+ * To save GPT
+ Shell> dcscfg -ds 1 -pf gpt_org -ps
+
+ * To apply GPT to disk
+ Shell> dcscfg -ds 1 -pf gpt_disk -pa
+
+ * To hide partition [123456,5678910] as template use partition(9)
+ Shell> dcscfg -pf gpt_disk -pht 9 -phide 123456 5678910 -ps
+
+ * To encrypt GPT before adding to security region
+ Shell> dcscfg -aa -pf gpt_hidden_boot -pe -ps
+
+ * To mark USB disk(1) as security regions container(write CRC of platform to 61 sector)
+ Shell> dcscfg -ds 1 -srm 5
+
+ * To wipe 5 security regions with random data (write random data [62, 62 + 256 * 5])
+ Sectors has to free! check first partition start sector!
+ Shell> dcscfg -ds 1 -srw 5
+
+ * To add gpt_hidden_boot to security region 2 on device 1
+ Shell> dcscfg -ds 1 -pf gpt_hidden_boot -sra 2
+
+.SH RETURNVALUES
+
+RETURN VALUES:
+ 0 Exited normally
diff --git a/DcsCfg/DcsCfgBeep.c b/DcsCfg/DcsCfgBeep.c
new file mode 100644
index 0000000..be158ba
--- /dev/null
+++ b/DcsCfg/DcsCfgBeep.c
@@ -0,0 +1,47 @@
+/** @file
+This is DCS configuration, speaker beep
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "DcsCfg.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Speaker beep
+//////////////////////////////////////////////////////////////////////////
+void SpeakerPrintDevicePathByIndex(UINTN index) {
+ OUT_PRINT(L"%V%d%N ", index);
+ EfiPrintDevicePath(gSpeakerHandles[index]);
+}
+
+void SpeakerPrintDevicePaths(CHAR16* msg) {
+ UINTN i;
+ OUT_PRINT(msg);
+ for (i = 0; i < gSpeakerCount; ++i) {
+ SpeakerPrintDevicePathByIndex(i);
+ OUT_PRINT(L"\n");
+ }
+}
+
+VOID
+PrintSpeakerList() {
+ InitSpeaker();
+ SpeakerPrintDevicePaths(L"%HSpeaker handles%N\n");
+}
+
+VOID
+TestSpeaker() {
+ SpeakerBeep((UINT16)gBeepToneDefault, gBeepNumberDefault, gBeepDurationDefault, gBeepIntervalDefault);
+} \ No newline at end of file
diff --git a/DcsCfg/DcsCfgBlockio.c b/DcsCfg/DcsCfgBlockio.c
new file mode 100644
index 0000000..ca9ec09
--- /dev/null
+++ b/DcsCfg/DcsCfgBlockio.c
@@ -0,0 +1,52 @@
+/** @file
+DCS configuration block devices
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Uefi/UefiGpt.h>
+#include <Guid/Gpt.h>
+
+#include "DcsCfg.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Block I/O
+//////////////////////////////////////////////////////////////////////////
+UINTN BioIndexStart = 0;
+UINTN BioIndexEnd = 0;
+BOOLEAN BioSkipPartitions = FALSE;
+
+void BioPrintDevicePath(UINTN bioIndex) {
+ OUT_PRINT(L"%V%d%N ", bioIndex);
+ EfiPrintDevicePath(gBIOHandles[bioIndex]);
+}
+
+void BioPrintDevicePaths(CHAR16* msg) {
+ UINTN i;
+ OUT_PRINT(msg);
+ if (BioIndexStart >= gBIOCount) return;
+ for (i = BioIndexStart; i < gBIOCount; ++i) {
+ if(BioSkipPartitions && EfiIsPartition(gBIOHandles[i])) continue;
+ BioPrintDevicePath(i);
+ OUT_PRINT(L"\n");
+ }
+}
+
+VOID
+PrintBioList() {
+ InitBio();
+ BioPrintDevicePaths(L"%HBlock IO handles%N\n");
+}
+
diff --git a/DcsCfg/DcsCfgCrypt.c b/DcsCfg/DcsCfgCrypt.c
new file mode 100644
index 0000000..d43b473
--- /dev/null
+++ b/DcsCfg/DcsCfgCrypt.c
@@ -0,0 +1,1324 @@
+/** @file
+This is DCS configuration, volume crypt
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ShellLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/Gpt.h>
+#include <Guid/GlobalVariable.h>
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/PasswordLib.h>
+#include <Library/DcsCfgLib.h>
+
+#include "common/Tcdefs.h"
+#include "common/Endian.h"
+#include "common/Crypto.h"
+#include "common/Volumes.h"
+#include "common/Crc.h"
+#include "crypto/cpu.h"
+#include "DcsVeraCrypt.h"
+#include "BootCommon.h"
+
+#include "DcsCfg.h"
+
+PCRYPTO_INFO gAuthCryptInfo = NULL;
+PCRYPTO_INFO gHeaderCryptInfo = NULL;
+CHAR8 Header[512];
+
+EFI_HANDLE SecRegionHandle = NULL;
+UINT64 SecRegionSector = 0;
+UINT8* SecRegionData = NULL;
+UINTN SecRegionSize = 0;
+UINTN SecRegionOffset = 0;
+PCRYPTO_INFO SecRegionCryptInfo = NULL;
+
+//////////////////////////////////////////////////////////////////////////
+// Crypt helpers
+//////////////////////////////////////////////////////////////////////////
+int
+AskEA() {
+ int ea;
+ CHAR16 name[128];
+ for (ea = EAGetFirst(); ea != 0; ea = EAGetNext(ea))
+ {
+ EAGetName(name, ea, 1);
+ OUT_PRINT(L"(%d) %s\n", ea, name);
+ }
+ ea = (int)AskUINTN(":", EAGetFirst());
+ return ea;
+}
+
+int
+AskMode(int ea) {
+ int mode;
+ for (mode = EAGetFirstMode(ea); mode != 0; mode = EAGetNextMode(ea, mode))
+ {
+ EAGetModeName(ea, mode, 1);
+ OUT_PRINT(L"(%d) %s\n", mode, EAGetModeName(ea, mode, 1));
+ }
+ mode = (int)AskUINTN(":", EAGetFirstMode(ea));
+ return mode;
+}
+
+int
+AskPkcs5() {
+ int pkcs5 = 1;
+ Hash *hash;
+ hash = HashGet(pkcs5);
+ while (hash != NULL)
+ {
+ OUT_PRINT(L"(%d) %s\n", pkcs5, hash->Name);
+ ++pkcs5;
+ hash = HashGet(pkcs5);
+ };
+ pkcs5 = (int)AskUINTN(":", gAuthHash);
+ return pkcs5;
+}
+
+EFI_STATUS
+TryHeaderDecrypt(
+ IN CHAR8* header,
+ OUT PCRYPTO_INFO *rci,
+ OUT PCRYPTO_INFO *rhci
+ )
+{
+ int vcres;
+ PCRYPTO_INFO cryptoInfo;
+ PCRYPTO_INFO headerCryptoInfo = NULL;
+
+ if (rhci != NULL) {
+ headerCryptoInfo = crypto_open();
+ }
+
+ vcres = ReadVolumeHeader(
+ gAuthBoot,
+ header,
+ &gAuthPassword,
+ gAuthHash,
+ gAuthPim,
+ gAuthTc,
+ &cryptoInfo,
+ headerCryptoInfo);
+
+ if (vcres != 0) {
+ ERR_PRINT(L"Decrypt error(%x)\n", vcres);
+ return EFI_INVALID_PARAMETER;
+ }
+ OUT_PRINT(L"%H" L"Success\n" L"%N", vcres);
+ OUT_PRINT(L"Start %lld length %lld\nVolumeSize %lld\nhiddenVolumeSize %lld\nflags 0x%x\n",
+ cryptoInfo->EncryptedAreaStart.Value, (uint64)cryptoInfo->EncryptedAreaLength.Value,
+ cryptoInfo->VolumeSize,
+ cryptoInfo->HeaderFlags
+ );
+ if(rci != NULL) *rci = cryptoInfo;
+ if (rhci != NULL) *rhci = headerCryptoInfo;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ChangePassword(
+ IN OUT CHAR8* header
+ )
+{
+ Password newPassword;
+ Password confirmPassword;
+ EFI_STATUS res;
+ PCRYPTO_INFO cryptoInfo, ci;
+ int vcres;
+
+ res = RndPreapare();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Rnd: %r\n", res);
+ return res;
+ }
+
+ if (gAuthPasswordMsg == NULL) {
+ VCAuthAsk();
+ }
+
+ res = TryHeaderDecrypt(header, &cryptoInfo, NULL);
+ if (EFI_ERROR(res)) return res;
+
+ if (AskConfirm("Change pwd[N]?", 1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do {
+ ZeroMem(&newPassword, sizeof(newPassword));
+ ZeroMem(&confirmPassword, sizeof(newPassword));
+ VCAskPwd(AskPwdNew, &newPassword);
+ VCAskPwd(AskPwdConfirm, &confirmPassword);
+ if (newPassword.Length == confirmPassword.Length) {
+ if (CompareMem(newPassword.Text, confirmPassword.Text, confirmPassword.Length) == 0) {
+ break;
+ }
+ }
+ if (AskConfirm("Password mismatch, retry?", 1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } while (TRUE);
+
+ vcres = CreateVolumeHeaderInMemory(
+ gAuthBoot, header,
+ cryptoInfo->ea,
+ cryptoInfo->mode,
+ &newPassword,
+ cryptoInfo->pkcs5,
+ gAuthPim,
+ cryptoInfo->master_keydata,
+ &ci,
+ cryptoInfo->VolumeSize.Value,
+ cryptoInfo->hiddenVolumeSize,
+ cryptoInfo->EncryptedAreaStart.Value,
+ cryptoInfo->EncryptedAreaLength.Value,
+ gAuthTc ? 0 : cryptoInfo->RequiredProgramVersion,
+ cryptoInfo->HeaderFlags,
+ cryptoInfo->SectorSize,
+ FALSE);
+
+ if (vcres != 0) {
+ ERR_PRINT(L"header create error(%x)\n", vcres);
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateVolumeHeader(
+ IN OUT CHAR8* header,
+ OUT PCRYPTO_INFO *rci,
+ IN UINT64 defaultVS,
+ IN UINT64 defaultESS,
+ IN UINT64 defaultESE
+ )
+{
+ INT32 vcres;
+ int mode = 0;
+ int ea = 0;
+ int pkcs5 = 0;
+ UINT64 encSectorStart = defaultESS;
+ UINT64 encSectorEnd = defaultESE;
+ UINT64 hiddenVolumeSize = 0;
+ UINT64 VolumeSize = defaultVS;
+ UINT32 HeaderFlags = 0;
+ int8 master_keydata[MASTER_KEYDATA_SIZE];
+
+ if (!RandgetBytes(master_keydata, MASTER_KEYDATA_SIZE, FALSE)) {
+ ERR_PRINT(L"No randoms\n");
+ return EFI_CRC_ERROR;
+ }
+
+ if (gAuthPasswordMsg == NULL) {
+ VCAuthAsk();
+ }
+
+ ea = AskEA();
+ mode = AskMode(ea);
+ pkcs5 = AskPkcs5();
+ encSectorStart = AskUINT64("encryption start (sector):", encSectorStart);
+ encSectorEnd = AskUINT64("encryption end (sector):", encSectorEnd);
+ VolumeSize = AskUINT64("volume total (sectors):", VolumeSize);
+ hiddenVolumeSize = AskUINT64("hidden volume total (sectors):", hiddenVolumeSize);
+ gAuthBoot = AskConfirm("Boot mode[N]?", 1);
+ HeaderFlags = (UINT32)AskUINTN("flags:", gAuthBoot ? TC_HEADER_FLAG_ENCRYPTED_SYSTEM : 0);
+
+ vcres = CreateVolumeHeaderInMemory(
+ gAuthBoot, Header,
+ ea,
+ mode,
+ &gAuthPassword,
+ pkcs5,
+ gAuthPim,
+ master_keydata,
+ rci,
+ VolumeSize << 9,
+ hiddenVolumeSize << 9,
+ encSectorStart << 9,
+ (encSectorEnd - encSectorStart + 1) << 9,
+ VERSION_NUM,
+ HeaderFlags,
+ 512,
+ FALSE);
+
+ if (vcres != 0) {
+ ERR_PRINT(L"Header error %d\n", vcres);
+ return EFI_CRC_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+UINT8
+AskChoice(
+ CHAR8* prompt,
+ CHAR8* choice,
+ UINT8 visible) {
+ CHAR16 buf[2];
+ UINTN len = 0;
+ UINT8 ret = 0;
+ UINT8 *pos = choice;
+ while (ret == 0) {
+ pos = choice;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, visible);
+ while (*pos != 0 && ret == 0) {
+ if (buf[0] == *pos) {
+ ret = *pos;
+ break;
+ }
+ pos++;
+ }
+ }
+ return ret;
+}
+
+UINT8
+AskARI() {
+ return AskChoice("[a]bort [r]etry [i]gnore?", "aArRiI", 1);
+}
+
+UINTN gScndTotal = 0;
+UINTN gScndCurrent = 0;
+VOID
+AddSecondsDelta()
+{
+ EFI_STATUS res;
+ EFI_TIME time;
+ UINTN secs;
+ UINTN secsDelta;
+ res = gST->RuntimeServices->GetTime(&time, NULL);
+ if (EFI_ERROR(res)) return;
+ secs = (UINTN)time.Second + ((UINTN)time.Minute) * 60 + ((UINTN)time.Hour) * 60 * 60;
+ if (gScndTotal == 0 && gScndCurrent == 0) {
+ gScndCurrent = secs;
+ return;
+ }
+ if (secs > gScndCurrent) {
+ secsDelta = secs - gScndCurrent;
+ } else {
+ secsDelta = 24 * 60 * 60 - gScndCurrent;
+ secsDelta += secs;
+ }
+ gScndCurrent = secs;
+ gScndTotal += secsDelta;
+}
+
+VOID
+RangeCryptProgress(
+ IN UINT64 size,
+ IN UINT64 remains,
+ IN UINT64 pos,
+ IN UINT64 remainsOnStart
+ ) {
+ UINTN percent;
+ percent = (UINTN)(100 * (size - remains) / size);
+ OUT_PRINT(L"%H%d%%%N (%llds %llds) ", percent, pos, remains);
+ AddSecondsDelta();
+ if (gScndTotal > 10) {
+ UINT64 doneBpS = (remainsOnStart - remains) * 512 / gScndTotal;
+ if (doneBpS > 1024 * 1024) {
+ OUT_PRINT(L"%lldMB/s", doneBpS / (1024 * 1024));
+ } else if (doneBpS > 1024) {
+ OUT_PRINT(L"%lldKB/s", doneBpS / 1024);
+ } else {
+ OUT_PRINT(L"%lldB/s", doneBpS);
+ }
+ if (doneBpS > 0) {
+ OUT_PRINT(L"(ETA: %lldm)", (remains * 512 / doneBpS) / 60);
+ }
+ }
+ OUT_PRINT(L" \r");
+}
+
+#define CRYPT_BUF_SECTORS 50*1024*2
+EFI_STATUS
+RangeCrypt(
+ IN EFI_HANDLE disk,
+ IN UINT64 start,
+ IN UINT64 size,
+ IN UINT64 enSize,
+ IN PCRYPTO_INFO info,
+ IN BOOL encrypt,
+ IN PCRYPTO_INFO headerInfo,
+ IN UINT64 headerSector
+ )
+{
+ EFI_STATUS res;
+ EFI_BLOCK_IO_PROTOCOL *io;
+ UINT8* buf;
+ UINT64 remains;
+ UINT64 remainsOnStart;
+ UINT64 pos;
+ UINTN rd;
+
+ io = EfiGetBlockIO(disk);
+ if (!io) {
+ ERR_PRINT(L"no block IO\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ buf = MEM_ALLOC(CRYPT_BUF_SECTORS << 9);
+ if (!buf) {
+ ERR_PRINT(L"no memory for buffer\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (encrypt) {
+ remains = size - enSize;
+ pos = start + enSize;
+ } else {
+ remains = enSize;
+ rd = (UINTN)((remains > CRYPT_BUF_SECTORS) ? CRYPT_BUF_SECTORS : remains);
+ pos = start + enSize - rd;
+ }
+ remainsOnStart = remains;
+ // Start second
+ gScndTotal = 0;
+ gScndCurrent = 0;
+ do {
+ rd = (UINTN)((remains > CRYPT_BUF_SECTORS) ? CRYPT_BUF_SECTORS : remains);
+ RangeCryptProgress(size, remains, pos, remainsOnStart);
+ // Read
+ do {
+ res = io->ReadBlocks(io, io->Media->MediaId, pos, rd << 9, buf);
+ if (EFI_ERROR(res)) {
+ UINT8 ari;
+ ERR_PRINT(L"Read error: %r\n", res);
+ ari = AskARI();
+ switch (ari)
+ {
+ case 'I':
+ case 'i':
+ res = EFI_SUCCESS;
+ break;
+ case 'A':
+ case 'a':
+ goto error;
+ case 'R':
+ case 'r':
+ default:
+ if (rd > 1) rd >>= 1;
+ break;
+ }
+ }
+ } while (EFI_ERROR(res));
+
+ // Crypt
+ if (encrypt) {
+ EncryptDataUnits(buf, (UINT64_STRUCT*)&pos, (UINT32)(rd), info);
+ } else {
+ DecryptDataUnits(buf, (UINT64_STRUCT*)&pos, (UINT32)(rd), info);
+ }
+
+ // Write
+ do {
+ res = io->WriteBlocks(io, io->Media->MediaId, pos, rd << 9, buf);
+ if (EFI_ERROR(res)) {
+ UINT8 ari;
+ ERR_PRINT(L"Write error: %r\n", res);
+ ari = AskARI();
+ switch (ari)
+ {
+ case 'I':
+ case 'i':
+ res = EFI_SUCCESS;
+ break;
+ case 'A':
+ case 'a':
+ goto error;
+ case 'R':
+ case 'r':
+ default:
+ break;
+ }
+ }
+ } while (EFI_ERROR(res));
+
+ if (encrypt) {
+ pos += rd;
+ } else {
+ pos -= rd;
+ }
+ remains -= rd;
+
+ // Update header
+ if (headerInfo != NULL) {
+ res = io->ReadBlocks(io, io->Media->MediaId, headerSector, 512, buf);
+ if (!EFI_ERROR(res)) {
+ UINT32 headerCrc32;
+ UINT64 encryptedAreaLength;
+ UINT8* headerData;
+ if (encrypt) {
+ encryptedAreaLength = (size - remains) << 9;
+ } else {
+ encryptedAreaLength = remains << 9;
+ }
+ DecryptBuffer(buf + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerInfo);
+ if (GetHeaderField32(buf, TC_HEADER_OFFSET_MAGIC) == 0x56455241) {
+ headerData = buf + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH;
+ mputInt64(headerData, encryptedAreaLength);
+ headerCrc32 = GetCrc32(buf + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
+ headerData = buf + TC_HEADER_OFFSET_HEADER_CRC;
+ mputLong(headerData, headerCrc32);
+ EncryptBuffer(buf + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerInfo);
+ res = io->WriteBlocks(io, io->Media->MediaId, headerSector, 512, buf);
+ } else {
+ res = EFI_CRC_ERROR;
+ }
+ }
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Header update: %r\n", res);
+ }
+ }
+
+ // Check ESC
+ {
+ EFI_INPUT_KEY key;
+ res = gBS->CheckEvent(gST->ConIn->WaitForKey);
+ if(!EFI_ERROR(res)) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ if (key.ScanCode == SCAN_ESC) {
+ if (AskConfirm("\n\rStop?", 1)) {
+ res = EFI_NOT_READY;
+ goto error;
+ }
+ }
+ }
+ }
+ } while (remains > 0);
+ RangeCryptProgress(size, remains, pos, remainsOnStart);
+ OUT_PRINT(L"\nDone");
+
+error:
+ OUT_PRINT(L"\n");
+ MEM_FREE(buf);
+ return res;
+}
+
+EFI_STATUS
+VolumeEncrypt(
+ IN UINTN index
+ )
+{
+ EFI_STATUS res;
+ EFI_HANDLE hDisk;
+ int vcres;
+ UINT64 headerSector;
+ EFI_BLOCK_IO_PROTOCOL* io;
+
+ // Write header
+ res = CreateVolumeHeaderOnDisk(index, NULL, &hDisk, &headerSector);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+
+ // Verify header
+ io = EfiGetBlockIO(hDisk);
+ if (!io) {
+ ERR_PRINT(L"can not get block IO\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ res = io->ReadBlocks(io, io->Media->MediaId, headerSector, 512, Header);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read error %r(%x)\n", res, res);
+ return res;
+ }
+
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, &gHeaderCryptInfo);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+
+ // Encrypt range
+ vcres = AskConfirm("Encrypt?", 1);
+ if (!vcres) {
+ ERR_PRINT(L"Encryption stoped\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ res = RangeCrypt(hDisk,
+ gAuthCryptInfo->EncryptedAreaStart.Value >> 9,
+ gAuthCryptInfo->VolumeSize.Value >> 9,
+ gAuthCryptInfo->EncryptedAreaLength.Value >> 9,
+ gAuthCryptInfo, TRUE,
+ gHeaderCryptInfo, headerSector);
+
+ crypto_close(gAuthCryptInfo);
+ crypto_close(gHeaderCryptInfo);
+ return res;
+}
+
+EFI_STATUS
+VolumeDecrypt(
+ IN UINTN index)
+{
+ EFI_BLOCK_IO_PROTOCOL* io;
+ EFI_STATUS res;
+ EFI_LBA vhsector;
+ BioPrintDevicePath(index);
+
+ io = EfiGetBlockIO(gBIOHandles[index]);
+ if (!io) {
+ ERR_PRINT(L"can not get block IO\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (gAuthPasswordMsg == NULL) {
+ VCAuthAsk();
+ }
+
+ vhsector = AskUINT64("header sector:", gAuthBoot? TC_BOOT_VOLUME_HEADER_SECTOR : 0);
+ res = io->ReadBlocks(io, io->Media->MediaId, vhsector, 512, Header);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read error %r(%x)\n", res, res);
+ return res;
+ }
+
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, &gHeaderCryptInfo);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+
+ if (!AskConfirm("Decrypt?", 1)) {
+ ERR_PRINT(L"Decryption stoped\n");
+ res = EFI_INVALID_PARAMETER;
+ goto error;
+ }
+
+ res = RangeCrypt(gBIOHandles[index],
+ gAuthCryptInfo->EncryptedAreaStart.Value >> 9,
+ gAuthCryptInfo->VolumeSize.Value >> 9,
+ gAuthCryptInfo->EncryptedAreaLength.Value >> 9,
+ gAuthCryptInfo, FALSE,
+ gHeaderCryptInfo,
+ vhsector);
+
+error:
+ crypto_close(gHeaderCryptInfo);
+ crypto_close(gAuthCryptInfo);
+ return res;
+}
+
+
+EFI_STATUS
+VolumeChangePassword(
+ IN UINTN index
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL* io;
+ EFI_STATUS res;
+ EFI_LBA vhsector;
+
+ BioPrintDevicePath(index);
+ io = EfiGetBlockIO(gBIOHandles[index]);
+ if (io == NULL) {
+ ERR_PRINT(L" No BIO protocol\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ vhsector = gAuthBoot ? TC_BOOT_VOLUME_HEADER_SECTOR : 0;
+ vhsector = AskUINT64("sector:", vhsector);
+ res = io->ReadBlocks(io, io->Media->MediaId, vhsector, 512, Header);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read error %r(%x)\n", res, res);
+ return res;
+ }
+
+ res = ChangePassword(Header);
+ if (EFI_ERROR(res)) return res;
+
+ if (AskConfirm("Save[N]?", 1)) {
+ res = io->WriteBlocks(io, io->Media->MediaId, vhsector, 512, Header);
+ ERR_PRINT(L"Header saved: %r\n", res);
+ }
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// OS Rescue
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+OSDecrypt()
+{
+
+ EFI_STATUS res;
+ UINTN disk;
+ BOOLEAN doDecrypt = FALSE;
+ EFI_BLOCK_IO_PROTOCOL* io;
+ if (gAuthPasswordMsg == NULL) {
+ VCAuthAsk();
+ }
+
+ for (disk = 0; disk < gBIOCount; ++disk) {
+ if (EfiIsPartition(gBIOHandles[disk])) continue;
+ io = EfiGetBlockIO(gBIOHandles[disk]);
+ if (io == NULL) continue;
+ res = io->ReadBlocks(io, io->Media->MediaId, 62, 512, Header);
+ if (EFI_ERROR(res)) continue;
+ BioPrintDevicePath(disk);
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, &gHeaderCryptInfo);
+ if (EFI_ERROR(res)) continue;
+ doDecrypt = TRUE;
+ break;
+ }
+
+ if (doDecrypt) {
+ if (!AskConfirm("Decrypt?", 1)) {
+ ERR_PRINT(L"Decryption stoped\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ res = RangeCrypt(gBIOHandles[disk],
+ gAuthCryptInfo->EncryptedAreaStart.Value >> 9,
+ gAuthCryptInfo->VolumeSize.Value >> 9,
+ gAuthCryptInfo->EncryptedAreaLength.Value >> 9,
+ gAuthCryptInfo, FALSE,
+ gHeaderCryptInfo,
+ 62);
+ crypto_close(gHeaderCryptInfo);
+ crypto_close(gAuthCryptInfo);
+ }
+ else {
+ res = EFI_NOT_FOUND;
+ }
+ return res;
+}
+
+CHAR16* sOSKeyBackup = L"EFI\\VeraCrypt\\svh_bak";
+// dirty import from GptEdit
+extern DCS_DISK_ENTRY_DISKID DeDiskId;
+
+EFI_STATUS
+OSBackupKeyLoad(
+ UINTN *DiskOS
+ )
+{
+ EFI_STATUS res;
+ UINT8 *restoreData = NULL;
+ UINTN restoreDataSize;
+ UINTN disk;
+ UINTN diskOS;
+ EFI_BLOCK_IO_PROTOCOL* io;
+ UINT64 startUnit = 0;
+ INTN deListHdrIdOk;
+
+ if (gAuthPasswordMsg == NULL) {
+ VCAuthAsk();
+ }
+
+ res = FileLoad(NULL, sOSKeyBackup, &SecRegionData, &SecRegionSize);
+ if (EFI_ERROR(res) || SecRegionSize < 512) {
+ SecRegionSize = 0;
+ MEM_FREE(SecRegionData);
+ }
+ if (SecRegionSize == 0) {
+ res = PlatformGetAuthData(&SecRegionData, &SecRegionSize, &SecRegionHandle);
+ if (EFI_ERROR(res)) {
+ SecRegionSize = 0;
+ }
+ }
+
+ if (SecRegionSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Try decrypt/locate header (in file or on removable flash)
+ do {
+ CopyMem(Header, SecRegionData + SecRegionOffset, 512);
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, NULL);
+ if (EFI_ERROR(res)) {
+ SecRegionOffset += 128 * 1024;
+ if (SecRegionOffset > SecRegionSize) {
+ MEM_FREE(SecRegionData);
+ SecRegionOffset = 0;
+ res = PlatformGetAuthData(&SecRegionData, &SecRegionSize, &SecRegionHandle);
+ if (EFI_ERROR(res)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+ restoreDataSize = (SecRegionSize - SecRegionOffset >= 128 * 1024)? 128 * 1024 : SecRegionSize - SecRegionOffset;
+ restoreData = SecRegionData + SecRegionOffset;
+ } while (EFI_ERROR(res));
+
+ // Parse DE list if present
+ SetMem(&DeDiskId.GptID, sizeof(DeDiskId.GptID), 0x55);
+ SetMem(&DeDiskId.MbrID, sizeof(DeDiskId.MbrID), 0x55);
+ if (restoreDataSize >= 1024) {
+ deListHdrIdOk = CompareMem(restoreData + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID));
+ if (deListHdrIdOk != 0) {
+ DecryptDataUnits(restoreData + 512, (UINT64_STRUCT *)&startUnit, (UINT32)(restoreDataSize >> 9) - 1, gAuthCryptInfo);
+ deListHdrIdOk = CompareMem(restoreData + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID));
+ if (deListHdrIdOk != 0) {
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+ }
+ res = DeListParseSaved(restoreData);
+ if (EFI_ERROR(res)) goto error;
+ }
+
+ // Search and list all disks
+ diskOS = 999;
+ for (disk = 0; disk < gBIOCount; ++disk) {
+ if (EfiIsPartition(gBIOHandles[disk])) continue;
+ io = EfiGetBlockIO(gBIOHandles[disk]);
+ if (io == NULL) continue;
+ res = io->ReadBlocks(io, io->Media->MediaId, 0, 512, Header);
+ if (EFI_ERROR(res)) continue;
+ BioPrintDevicePath(disk);
+ if (DeDiskId.MbrID == *(uint32 *)(Header + 0x1b8)) {
+ res = io->ReadBlocks(io, io->Media->MediaId, 1, 512, Header);
+ if (EFI_ERROR(res)) continue;
+ if (CompareMem(&DeDiskId.GptID, &((EFI_PARTITION_TABLE_HEADER*)Header)->DiskGUID, sizeof(DeDiskId.GptID)) == 0) {
+ diskOS = disk;
+ OUT_PRINT(L"%H[found]%N");
+ }
+ }
+ OUT_PRINT(L"\n");
+ }
+ diskOS = AskUINTN("Select disk:", diskOS);
+ if (diskOS >= gBIOCount) {
+ res = EFI_INVALID_PARAMETER;
+ goto error;
+ }
+
+ if (EfiIsPartition(gBIOHandles[diskOS])) {
+ res = EFI_INVALID_PARAMETER;
+ goto error;
+ }
+ *DiskOS = diskOS;
+ return EFI_SUCCESS;
+
+error:
+ MEM_FREE(SecRegionData);
+ return res;
+}
+
+EFI_STATUS
+OSRestoreKey()
+{
+ EFI_STATUS res;
+ UINTN disk;
+ EFI_BLOCK_IO_PROTOCOL* io;
+
+ res = OSBackupKeyLoad(&disk);
+ if (EFI_ERROR(res)) return res;
+
+ if (!AskConfirm("Restore?", 1)) {
+ res = EFI_INVALID_PARAMETER;
+ goto error;
+ }
+
+ io = EfiGetBlockIO(gBIOHandles[disk]);
+ if (io == NULL) {
+ res = EFI_INVALID_PARAMETER;
+ goto error;
+ }
+
+ res = io->WriteBlocks(io, io->Media->MediaId, 62, 512, SecRegionData + SecRegionOffset);
+
+error:
+ MEM_FREE(SecRegionData);
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Wipe
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+BlockRangeWipe(
+ IN EFI_HANDLE h,
+ IN UINT64 start,
+ IN UINT64 end
+ )
+{
+ EFI_STATUS res;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+ VOID* buf;
+ UINT64 remains;
+ UINT64 pos;
+ UINTN rd;
+ bio = EfiGetBlockIO(h);
+ if (bio == 0) {
+ ERR_PRINT(L"No block device");
+ return EFI_NOT_FOUND;
+ }
+
+ res = RndPreapare();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Rnd: %r\n", res);
+ return res;
+ }
+
+ EfiPrintDevicePath(h);
+
+ OUT_PRINT(L"\nSectors [%lld, %lld]", start, end);
+ if (AskConfirm(", Wipe data?", 1) == 0) return EFI_NOT_READY;
+ buf = MEM_ALLOC(CRYPT_BUF_SECTORS << 9);
+ if (!buf) {
+ ERR_PRINT(L"can not get buffer\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ remains = end -start + 1;
+ pos = start;
+ do {
+ rd = (UINTN)((remains > CRYPT_BUF_SECTORS) ? CRYPT_BUF_SECTORS : remains);
+ RandgetBytes(buf, (UINT32)(rd << 9), FALSE);
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, pos, rd << 9, buf);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write error: %r\n", res);
+ MEM_FREE(buf);
+ return res;
+ }
+ pos += rd;
+ remains -= rd;
+ OUT_PRINT(L"%lld %lld \r", pos, remains);
+ } while (remains > 0);
+ OUT_PRINT(L"\nDone\n", pos, remains);
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// DCS authorization check
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+IntCheckVolume(
+ UINTN index
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL* pBio;
+ EFI_STATUS res;
+ EFI_LBA vhsector;
+
+ BioPrintDevicePath(index);
+ pBio = EfiGetBlockIO(gBIOHandles[index]);
+ if (pBio == NULL) {
+ ERR_PRINT(L" No BIO protocol\n");
+ return EFI_NOT_FOUND;
+ }
+
+ vhsector = gAuthBoot ? TC_BOOT_VOLUME_HEADER_SECTOR : 0;
+ res = pBio->ReadBlocks(pBio, pBio->Media->MediaId, vhsector, 512, Header);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L" %r(%x)\n", res, res);
+ return res;
+ }
+
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, NULL);
+ if (res != 0) {
+ if (gAuthBoot == 0) {
+ OUT_PRINT(L"Try hidden...");
+ res = pBio->ReadBlocks(pBio, pBio->Media->MediaId, TC_VOLUME_HEADER_SIZE / 512, 512, Header);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L" %r(%x)\n", res, res);
+ return res;
+ }
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, NULL);
+ }
+ }
+ return res;
+}
+
+VOID
+DisksAuthCheck() {
+ UINTN i;
+ if (BioIndexStart >= gBIOCount) return;
+ i = BioIndexStart;
+ do {
+ IntCheckVolume(i);
+ ++i;
+ } while ((i < gBIOCount) && (i <= BioIndexEnd));
+}
+
+VOID
+TestAuthAsk() {
+ VCAuthAsk();
+}
+
+EFI_STATUS
+CreateVolumeHeaderOnDisk(
+ IN UINTN index,
+ OUT VOID **pinfo,
+ OUT EFI_HANDLE *phDisk,
+ OUT UINT64 *sector
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL* bio;
+ EFI_STATUS res;
+ UINT64 encSectorStart = 0;
+ UINT64 encSectorEnd = 0;
+ UINT64 VolumeSize = 0;
+ PCRYPTO_INFO ci = 0;
+ EFI_LBA vhsector;
+ EFI_HANDLE hDisk = NULL;
+ HARDDRIVE_DEVICE_PATH hdp;
+ BOOLEAN isPart;
+
+ BioPrintDevicePath(index);
+ OUT_PRINT(L"\n");
+
+ isPart = EfiIsPartition(gBIOHandles[index]);
+ if (isPart) {
+ res = EfiGetPartDetails(gBIOHandles[index], &hdp, &hDisk);
+ if (!EFI_ERROR(res)) {
+ encSectorEnd = hdp.PartitionSize - encSectorStart - 256;
+ VolumeSize = hdp.PartitionSize;
+ }
+ }
+
+ res = CreateVolumeHeader(Header, &ci, VolumeSize, encSectorStart, encSectorEnd);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+
+ if (isPart && gAuthBoot) {
+ OUT_PRINT(L"Boot drive to save is selected. \n");
+ EfiPrintDevicePath(hDisk);
+ OUT_PRINT(L"\n");
+ } else {
+ hDisk = gBIOHandles[index];
+ }
+
+ bio = EfiGetBlockIO(hDisk);
+ if (bio == NULL) {
+ ERR_PRINT(L"No BIO protocol\n");
+ return EFI_NOT_FOUND;
+ }
+
+ vhsector = AskUINT64("save to sector:", gAuthBoot ? 62 : 0);
+ if (AskConfirm("Save [N]?", 1)) {
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, vhsector, 512, Header);
+ ERR_PRINT(L"Write: %r\n", res);
+ }
+
+ if (phDisk != NULL) *phDisk = hDisk;
+ if (pinfo != NULL) {
+ *pinfo = ci;
+ } else {
+ crypto_close(ci);
+ }
+ if (sector != NULL)*sector = vhsector;
+ return res;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// USB
+//////////////////////////////////////////////////////////////////////////
+UINTN UsbIndex = 0;
+void UsbIoPrintDevicePath(UINTN uioIndex) {
+ CHAR8* id = NULL;
+ OUT_PRINT(L"%V%d%N ", uioIndex);
+ EfiPrintDevicePath(gUSBHandles[uioIndex]);
+ UsbGetId(gUSBHandles[uioIndex], &id);
+ if (id != NULL) {
+ UINT32 rud;
+ rud = (UINT32)GetCrc32((unsigned char*)id, (int)AsciiStrLen(id));
+ OUT_PRINT(L" -(%d) %a", rud, id);
+ MEM_FREE(id);
+ }
+}
+
+void UsbIoPrintDevicePaths(CHAR16* msg) {
+ UINTN i;
+ OUT_PRINT(msg);
+ for (i = 0; i < gUSBCount; ++i) {
+ UsbIoPrintDevicePath(i);
+ OUT_PRINT(L"\n");
+ }
+}
+
+VOID
+PrintUsbList() {
+ InitUsb();
+ UsbIoPrintDevicePaths(L"%HUSB IO handles%N\n");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Set DcsInt parameters
+//////////////////////////////////////////////////////////////////////////
+VOID
+UpdateDcsBoot() {
+ EFI_STATUS res;
+ HARDDRIVE_DEVICE_PATH dpVolme;
+ EFI_HANDLE hDisk;
+ if (BioIndexStart >= gBIOCount) {
+ // Delete var
+ res = EfiSetVar(DCS_BOOT_STR, &gEfiDcsVariableGuid, NULL, 0, 0);
+ }
+ else {
+ // Set var
+ EFI_DEVICE_PATH *DevicePath;
+ UINTN len;
+ BioPrintDevicePath(BioIndexStart);
+ res = EfiGetPartDetails(gBIOHandles[BioIndexStart], &dpVolme, &hDisk);
+ if (EFI_ERROR(res)) {
+ OUT_PRINT(L" %r\n", res);
+ return;
+ }
+ DevicePath = DevicePathFromHandle(hDisk);
+ len = GetDevicePathSize(DevicePath);
+// res = EfiSetVar(DCS_BOOT_STR, NULL, DevicePath, len, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ FileSave(NULL, DCS_BOOT_STR, DevicePath, len);
+ OUT_PRINT(L"Boot:");
+ EfiPrintDevicePath(hDisk);
+ OUT_PRINT(L"\n");
+ }
+ OUT_PRINT(L" %r\n", res);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Security region
+//////////////////////////////////////////////////////////////////////////
+UINTN gSecRigonCount = 0;
+
+EFI_STATUS
+SecRigionMark()
+{
+ UINT32 crc;
+ EFI_STATUS res;
+ DCS_AUTH_DATA_MARK* adm;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+
+ res = PlatformGetIDCRC(gBIOHandles[BioIndexStart], &crc);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"CRC: %r\n", res);
+ return res;
+ }
+
+ adm = (DCS_AUTH_DATA_MARK*)MEM_ALLOC(512);
+ if (adm == NULL) {
+ ERR_PRINT(L"no memory\n");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ adm->AuthDataSize = (UINT32)gSecRigonCount;
+ adm->PlatformCrc = crc;
+ res = gBS->CalculateCrc32(&adm->PlatformCrc, sizeof(*adm) - 4, &adm->HeaderCrc);
+
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"CRC: %r\n", res);
+ return res;
+ }
+
+ bio = EfiGetBlockIO(gBIOHandles[BioIndexStart]);
+ if (bio == NULL) {
+ MEM_FREE(adm);
+ ERR_PRINT(L"No block IO");
+ return EFI_ACCESS_DENIED;
+ }
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, 61, 512, adm);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ }
+ MEM_FREE(adm);
+ return res;
+}
+
+EFI_STATUS
+SecRigionWipe()
+{
+ EFI_STATUS res;
+ CHAR8* buf;
+ UINTN i;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+
+ buf = MEM_ALLOC(128 * 1024);
+ if (buf == NULL) {
+ ERR_PRINT(L"no memory\n");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ bio = EfiGetBlockIO(gBIOHandles[BioIndexStart]);
+ if (bio == NULL) {
+ ERR_PRINT(L"No block IO");
+ res = EFI_ACCESS_DENIED;
+ goto error;
+ }
+
+ if (!RandgetBytes(buf, 512, FALSE)) {
+ ERR_PRINT(L"No randoms\n");
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+
+ // Wipe mark
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, 61, 512, buf);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ goto error;
+ }
+
+ // Wipe region
+ for (i = 0; i < gSecRigonCount; ++i) {
+ if (!RandgetBytes(buf, 128 * 1024, FALSE)) {
+ ERR_PRINT(L"No randoms\n");
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, 62 + i * (128 * 1024 / 512), 128 * 1024, buf);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ goto error;
+ }
+ }
+ return EFI_SUCCESS;
+
+error:
+ MEM_FREE(buf);
+ return res;
+}
+
+EFI_STATUS
+SecRigionAdd(
+ IN UINTN regIdx
+)
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+ UINT8* regionData;
+ UINTN regionSize;
+ INTN deListHdrIdOk;
+ res = FileLoad(NULL, (CHAR16*)DcsDiskEntrysFileName, &regionData, &regionSize);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Load %s: %r\n", DcsDiskEntrysFileName, res);
+ return res;
+ }
+ deListHdrIdOk = CompareMem(regionData + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID));
+
+ if (deListHdrIdOk == 0) {
+ ERR_PRINT(L"GPT has to be encrypted\n");
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+
+ bio = EfiGetBlockIO(gBIOHandles[BioIndexStart]);
+ if (bio == NULL) {
+ ERR_PRINT(L"No block IO");
+ res = EFI_ACCESS_DENIED;
+ goto error;
+ }
+
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, 62 + regIdx * (128 * 1024 / 512), regionSize, regionData);
+
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ goto error;
+ }
+
+error:
+ MEM_FREE(regionData);
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// GPT
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+GptCryptFile(
+ IN BOOLEAN crypt
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINT64 startUnit = 0;
+ UINT8* regionData;
+ UINTN regionSize;
+ INTN deListHdrIdOk;
+
+ res = FileLoad(NULL, (CHAR16*)DcsDiskEntrysFileName, &regionData, &regionSize);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Load %s: %r\n", DcsDiskEntrysFileName, res);
+ return res;
+ }
+ deListHdrIdOk = CompareMem(regionData + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID));
+
+ if ((deListHdrIdOk != 0) && crypt) {
+ ERR_PRINT(L"Already encrypted\n");
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+
+ if ((deListHdrIdOk == 0) && !crypt) {
+ ERR_PRINT(L"Already decrypted\n");
+ res = EFI_CRC_ERROR;
+ goto error;
+ }
+
+ DetectX86Features();
+ CopyMem(Header, regionData, sizeof(Header));
+ res = TryHeaderDecrypt(Header, &gAuthCryptInfo, NULL);
+ if(EFI_ERROR(res)){
+ goto error;
+ }
+ startUnit = 0;
+ if (crypt) {
+ EncryptDataUnits(regionData + 512, (UINT64_STRUCT *)&startUnit, (UINT32)(regionSize >> 9) - 1, gAuthCryptInfo);
+ }
+ else {
+ DecryptDataUnits(regionData + 512, (UINT64_STRUCT *)&startUnit, (UINT32)(regionSize >> 9) - 1, gAuthCryptInfo);
+ }
+
+ res = FileSave(NULL, (CHAR16*)DcsDiskEntrysFileName, regionData, regionSize);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Save %s: %r\n", DcsDiskEntrysFileName, res);
+ goto error;
+ }
+
+error:
+ MEM_FREE(regionData);
+ return res;
+}
+
+EFI_STATUS
+GptEdit(
+ IN UINTN index
+ )
+{
+
+ EFI_PARTITION_ENTRY* part = &GptMainEntrys[index];
+
+ ///
+ /// Null-terminated name of the partition.
+ ///
+ CHAR16 PartitionName[36];
+ UINTN len;
+ while (!GptAskGUID("type (msr, data, wre, efi, del or guid)\n\r:", &part->PartitionTypeGUID));
+ if (CompareMem(&part->PartitionTypeGUID, &gEfiPartTypeUnusedGuid, sizeof(EFI_GUID)) == 0) {
+ ZeroMem(part, sizeof(*part));
+ GptSqueze();
+ GptSort();
+ GptSyncMainAlt();
+ return EFI_SUCCESS;
+ }
+ while (!GptAskGUID("id\n\r:", &part->UniquePartitionGUID));
+ part->StartingLBA = AskUINT64("StartingLBA:", part->StartingLBA);
+ part->EndingLBA = AskUINT64("EndingLBA:", part->EndingLBA);
+ part->Attributes = AskHexUINT64("Attributes\n\r:", part->Attributes);
+ OUT_PRINT(L"[%s]\n\r:", part->PartitionName);
+ GetLine(&len, PartitionName, NULL, sizeof(PartitionName) / 2 - 1, 1);
+ if (len != 0) {
+ CopyMem(&part->PartitionName, PartitionName, sizeof(PartitionName));
+ }
+ GptSqueze();
+ GptSort();
+ GptSyncMainAlt();
+ return EFI_SUCCESS;
+}
diff --git a/DcsCfg/DcsCfgGraphics.c b/DcsCfg/DcsCfgGraphics.c
new file mode 100644
index 0000000..3c5addb
--- /dev/null
+++ b/DcsCfg/DcsCfgGraphics.c
@@ -0,0 +1,81 @@
+/** @file
+DCS configuration graphics devices
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ShellLib.h>
+
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "DcsCfg.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// Graphics
+//////////////////////////////////////////////////////////////////////////
+
+void GraphPrintDevicePath(EFI_HANDLE handle) {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL* grfio = NULL;
+ EFI_STATUS res;
+ EfiPrintDevicePath(handle);
+ res = GraphGetIO(handle, &grfio);
+ if (!EFI_ERROR(res) && grfio != NULL) {
+ UINT32 i;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* cout;
+ res = ConsoleGetOutput(handle, &cout);
+ OUT_PRINT(L" - %d [%d (%d,%d) %d] %s",
+ grfio->Mode->MaxMode, grfio->Mode->Mode,
+ grfio->Mode->Info->HorizontalResolution, grfio->Mode->Info->VerticalResolution,
+ grfio->Mode->Info->PixelFormat,
+ EFI_ERROR(res) ? L"" : L"console"
+ );
+
+ for (i = 0; i < grfio->Mode->MaxMode; i++) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ UINTN szInfo;
+ res = grfio->QueryMode(grfio, i, &szInfo, &info);
+ if (!EFI_ERROR(res)) {
+ OUT_PRINT(L"\n [%d (%d,%d) %d]",
+ i,
+ info->HorizontalResolution, info->VerticalResolution,
+ grfio->Mode->Info->PixelFormat
+ );
+ }
+ }
+ }
+}
+
+void GraphPrintDevicePathByIndex(UINTN index) {
+ OUT_PRINT(L"%V%d%N ", index);
+ GraphPrintDevicePath(gGraphHandles[index]);
+}
+
+void GraphPrintDevicePaths(CHAR16* msg) {
+ UINTN i;
+ OUT_PRINT(msg);
+ for (i = 0; i < gGraphCount; ++i) {
+ GraphPrintDevicePathByIndex(i);
+ OUT_PRINT(L"\n");
+ }
+}
+
+VOID
+PrintGraphList() {
+ InitGraph();
+ GraphPrintDevicePaths(L"%HGraphics handles%N\n");
+}
diff --git a/DcsCfg/DcsCfgMain.c b/DcsCfg/DcsCfgMain.c
new file mode 100644
index 0000000..5c2ce2b
--- /dev/null
+++ b/DcsCfg/DcsCfgMain.c
@@ -0,0 +1,650 @@
+/** @file
+This is DCS configuration tool. (EFI shell application/TODO:wizard)
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ShellLib.h>
+
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/GlobalVariable.h>
+
+#include "DcsCfg.h"
+#include "Library/PasswordLib.h"
+
+#include "common/Tcdefs.h"
+#include "crypto/cpu.h"
+#include "Library/DcsCfgLib.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// Main
+//////////////////////////////////////////////////////////////////////////
+#define OPT_DISK_CHECK L"-dc"
+#define OPT_DISK_LIST L"-dl"
+#define OPT_DISK_START L"-ds"
+#define OPT_DISK_END L"-de"
+#define OPT_DISK_BOOT L"-db"
+#define OPT_AUTH_ASK L"-aa"
+#define OPT_AUTH_CREATE_HEADER L"-ach"
+#define OPT_RND L"-rnd"
+#define OPT_RND_GEN L"-rndgen"
+#define OPT_RND_LOAD L"-rndload"
+#define OPT_RND_SAVE L"-rndsave"
+#define OPT_VOLUME_ENCRYPT L"-vec"
+#define OPT_VOLUME_DECRYPT L"-vdc"
+#define OPT_VOLUME_CHANGEPWD L"-vcp"
+#define OPT_USB_LIST L"-ul"
+#define OPT_TOUCH_LIST L"-tl"
+#define OPT_TOUCH_TEST L"-tt"
+#define OPT_GRAPH_LIST L"-gl"
+#define OPT_GRAPH_DEVICE L"-gd"
+#define OPT_GRAPH_MODE L"-gm"
+#define OPT_BEEP_LIST L"-bl"
+#define OPT_BEEP_TEST L"-bt"
+#define OPT_SETUP L"-setup"
+#define OPT_PARTITION_LIST L"-pl"
+#define OPT_PARTITION_FILE L"-pf"
+#define OPT_PARTITION_SAVE L"-ps"
+#define OPT_PARTITION_ZERO L"-pz"
+#define OPT_PARTITION_APPLY L"-pa"
+#define OPT_PARTITION_ENCRYPT L"-pe"
+#define OPT_PARTITION_DECRYPT L"-pd"
+#define OPT_PARTITION_IDX_TEMPLATE L"-pnt"
+#define OPT_PARTITION_HIDE L"-phide"
+#define OPT_PARTITION_EDIT L"-pedt"
+#define OPT_PARTITION_EDIT_EXEC L"-pexec"
+#define OPT_PARTITION_RND_LOAD L"-prndload"
+#define OPT_PARTITION_RND_SAVE L"-prndsave"
+#define OPT_PARTITION_EDIT_PWD_CACHE L"-pwdcache"
+#define OPT_KEYFILE_PLATFORM L"-kp"
+#define OPT_SECREGION_MARK L"-srm"
+#define OPT_SECREGION_WIPE L"-srw"
+#define OPT_SECREGION_ADD L"-sra"
+#define OPT_WIPE L"-wipe"
+#define OPT_OS_DECRYPT L"-osdecrypt"
+#define OPT_OS_RESTORE_KEY L"-osrestorekey"
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ { OPT_DISK_LIST, TypeValue },
+ { OPT_DISK_CHECK, TypeFlag },
+ { OPT_DISK_START, TypeValue },
+ { OPT_DISK_END, TypeValue },
+ { OPT_DISK_BOOT, TypeValue },
+ { OPT_AUTH_ASK, TypeFlag },
+ { OPT_AUTH_CREATE_HEADER, TypeFlag },
+ { OPT_RND, TypeDoubleValue },
+ { OPT_RND_GEN, TypeDoubleValue },
+ { OPT_RND_LOAD, TypeValue },
+ { OPT_RND_SAVE, TypeValue },
+ { OPT_VOLUME_ENCRYPT,TypeValue },
+ { OPT_VOLUME_DECRYPT,TypeValue },
+ { OPT_VOLUME_CHANGEPWD,TypeValue },
+ { OPT_USB_LIST, TypeFlag },
+ { OPT_TOUCH_LIST, TypeFlag },
+ { OPT_TOUCH_TEST, TypeValue },
+ { OPT_GRAPH_LIST, TypeFlag },
+ { OPT_GRAPH_DEVICE, TypeValue },
+ { OPT_GRAPH_MODE, TypeValue },
+ { OPT_BEEP_LIST, TypeFlag },
+ { OPT_BEEP_TEST, TypeFlag },
+ { OPT_SETUP, TypeFlag },
+ { OPT_PARTITION_LIST, TypeFlag },
+ { OPT_PARTITION_SAVE, TypeFlag },
+ { OPT_PARTITION_ZERO, TypeFlag },
+ { OPT_PARTITION_FILE, TypeValue },
+ { OPT_PARTITION_ENCRYPT,TypeFlag },
+ { OPT_PARTITION_DECRYPT,TypeFlag },
+ { OPT_PARTITION_APPLY,TypeFlag },
+ { OPT_PARTITION_HIDE, TypeDoubleValue },
+ { OPT_PARTITION_IDX_TEMPLATE, TypeValue },
+ { OPT_PARTITION_EDIT, TypeValue },
+ { OPT_PARTITION_EDIT_EXEC, TypeFlag },
+ { OPT_PARTITION_EDIT_PWD_CACHE, TypeFlag },
+ { OPT_PARTITION_RND_LOAD, TypeFlag },
+ { OPT_PARTITION_RND_SAVE, TypeFlag },
+ { OPT_KEYFILE_PLATFORM, TypeValue },
+ { OPT_SECREGION_MARK, TypeValue },
+ { OPT_SECREGION_WIPE, TypeValue },
+ { OPT_SECREGION_ADD, TypeValue },
+ { OPT_WIPE, TypeDoubleValue },
+ { OPT_OS_DECRYPT, TypeFlag },
+ { OPT_OS_RESTORE_KEY, TypeFlag },
+ { NULL, TypeMax }
+};
+
+/**
+The actual entry point for the application.
+
+@param[in] ImageHandle The firmware allocated handle for the EFI image.
+@param[in] SystemTable A pointer to the EFI System Table.
+
+@retval EFI_SUCCESS The entry point executed successfully.
+@retval other Some error occur when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsCfgMain(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS res;
+ LIST_ENTRY *Package;
+ SHELL_STATUS ShellStatus;
+ UINTN ParamCount;
+ CHAR16 *ProblemParam;
+ UINTN Size;
+ CHAR16 *PrintString;
+ CHAR16* cmd;
+ UINTN cmdSize;
+ UINT32 cmdAttr;
+
+ Size = 0;
+ ParamCount = 0;
+ ProblemParam = NULL;
+ PrintString = NULL;
+ ShellStatus = SHELL_SUCCESS;
+
+ InitBio();
+ InitFS();
+ DetectX86Features();
+
+ //
+ // initialize the shell lib (we must be in non-auto-init...)
+ //
+ res = EfiGetVar(L"dcscfgcmd", NULL, &cmd, &cmdSize, &cmdAttr);
+ if (!EFI_ERROR(res)) {
+ res = EfiSetVar(L"dcscfgcmd", NULL, NULL, 0, cmdAttr);
+ if (StrStr(cmd, OPT_OS_RESTORE_KEY) != NULL) {
+ return OSRestoreKey();
+ }
+ if (StrStr(cmd, OPT_OS_DECRYPT) != NULL) {
+ return OSDecrypt();
+ }
+ return EFI_INVALID_PARAMETER;
+ }
+
+ res = ShellInitialize();
+ if (EFI_ERROR(res) || gEfiShellProtocol == NULL) {
+ EFI_INPUT_KEY key;
+ key = KeyWait(L"Press any key to start interactive DCS setup %02d\r", 20, 0, 0);
+ if (key.UnicodeChar != 0) {
+ return DcsInteractiveSetup();
+ }
+ return EFI_INVALID_PARAMETER;
+ }
+
+ InitGraph();
+ //
+ // parse the command line
+ //
+ res = ShellCommandLineParseEx(ParamList, &Package, &ProblemParam, TRUE, TRUE);
+ if (EFI_ERROR(res)) {
+ OUT_PRINT(L"syntax error:%s", ProblemParam);
+ return res;
+ }
+ gShellReady = gEfiShellProtocol != NULL;
+ if (gShellReady) {
+ SetShellAPI(gEfiShellProtocol, gEfiShellParametersProtocol);
+ }
+
+ ParamCount = ShellCommandLineGetCount(Package);
+
+ // Common parameters
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_DISK_START);
+ BioIndexStart = StrDecimalToUintn(opt);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_END)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_DISK_END);
+ BioIndexEnd = StrDecimalToUintn(opt);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_FILE)) {
+ DcsDiskEntrysFileName = ShellCommandLineGetValue(Package, OPT_PARTITION_FILE);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_AUTH_ASK)) {
+ TestAuthAsk();
+ }
+
+ // Rescue
+ if (ShellCommandLineGetFlag(Package, OPT_OS_DECRYPT)) {
+ return OSDecrypt();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_OS_RESTORE_KEY)) {
+ return OSRestoreKey();
+ }
+
+ // Beep
+ if (ShellCommandLineGetFlag(Package, OPT_BEEP_LIST)) {
+ PrintSpeakerList();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_BEEP_TEST)) {
+ TestSpeaker();
+ }
+
+ // Touch
+ if (ShellCommandLineGetFlag(Package, OPT_TOUCH_LIST)) {
+ PrintTouchList();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_TOUCH_TEST)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_TOUCH_TEST);
+ TouchIndex= StrDecimalToUintn(opt);
+ TestTouch();
+ }
+
+ // Graph
+ if (ShellCommandLineGetFlag(Package, OPT_GRAPH_DEVICE)) {
+ CONST CHAR16* opt = NULL;
+ UINTN index;
+ opt = ShellCommandLineGetValue(Package, OPT_GRAPH_DEVICE);
+ index = StrDecimalToUintn(opt);
+ if (index < gGraphCount) {
+ GraphGetIO(gGraphHandles[index], &gGraphOut);
+ } else{
+ ERR_PRINT(L"Wrong graph device index");
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_GRAPH_MODE)) {
+ CONST CHAR16* opt = NULL;
+ UINTN index;
+ opt = ShellCommandLineGetValue(Package, OPT_GRAPH_MODE);
+ index = StrDecimalToUintn(opt);
+ if (index < gGraphOut->Mode->MaxMode) {
+ gGraphOut->SetMode(gGraphOut, (UINT32)index);
+ } else {
+ ERR_PRINT(L"Wrong graph mode index");
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_GRAPH_LIST)) {
+ PrintGraphList();
+ }
+
+ // USB
+ if (ShellCommandLineGetFlag(Package, OPT_USB_LIST)) {
+ PrintUsbList();
+ }
+
+ // Create random
+ if (ShellCommandLineGetFlag(Package, OPT_RND)) {
+ CONST CHAR16* opt = NULL;
+ CONST CHAR16* context = NULL;
+ UINTN rndType;
+ opt = ShellCommandLineGetValue(Package, OPT_RND);
+ rndType = StrDecimalToUintn(opt);
+ context = StrStr(opt, L" ");
+ if (context != NULL) {
+ context++;
+ }
+ res = RndInit(rndType, (CHAR16*)context, &gRnd);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_RND_LOAD)) {
+ CONST CHAR16* opt = NULL;
+ UINT8 temp[4];
+ DCS_RND_SAVED *rndSaved;
+ UINTN rndSavedSize;
+ opt = ShellCommandLineGetValue(Package, OPT_RND_LOAD);
+ res = FileLoad(NULL, (CHAR16*)opt, &rndSaved, &rndSavedSize);
+ if (EFI_ERROR(res) ||
+ rndSavedSize != sizeof(DCS_RND_SAVED) ||
+ EFI_ERROR(res = RndLoad(rndSaved,&gRnd)) ||
+ EFI_ERROR(res = RndPreapare()) ||
+ EFI_ERROR(res = RndGetBytes(temp, sizeof(temp)))
+ ) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_RND_LOAD)) {
+ UINT8 temp[4];
+ if (EFI_ERROR(res = DeListLoadFromFile()) || // Load DeList
+ EFI_ERROR(res = DeListRndLoad()) || // Try to load gRdn from list
+ EFI_ERROR(res = RndPreapare()) || // Prepare random
+ EFI_ERROR(res = RndGetBytes(temp, sizeof(temp))) // Test
+ ) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_RND_GEN)) {
+ CONST CHAR16* optSize = NULL;
+ UINTN size;
+ CONST CHAR16* optFile = NULL;
+ UINT8* temp;
+ optSize = ShellCommandLineGetValue(Package, OPT_RND_GEN);
+ size = StrDecimalToUintn(optSize);
+ optFile = StrStr(optSize, L" ");
+ if (optFile != NULL) {
+ optFile++;
+ }
+ res = EFI_BUFFER_TOO_SMALL;
+ temp = MEM_ALLOC(size);
+ if (temp == NULL ||
+ EFI_ERROR(res = RndGetBytes(temp, size) ||
+ EFI_ERROR(res = FileSave(NULL, (CHAR16*)optFile, temp, size)))
+ ) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ MEM_FREE(temp);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_RND_SAVE)) {
+ CONST CHAR16* opt = NULL;
+ UINT8 temp[4];
+ DCS_RND_SAVED *rndSaved = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_RND_SAVE);
+ if (EFI_ERROR(res = RndPreapare()) ||
+ EFI_ERROR(res = RndGetBytes(temp, sizeof(temp))) ||
+ EFI_ERROR(res = RndSave(gRnd, &rndSaved)) ||
+ EFI_ERROR(res = FileSave(NULL, (CHAR16*)opt, rndSaved, sizeof(DCS_RND_SAVED)))
+ ) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ MEM_FREE(rndSaved);
+ }
+
+
+ // Disk
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_BOOT)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_DISK_BOOT);
+ BioIndexEnd = BioIndexStart = StrDecimalToUintn(opt);
+ UpdateDcsBoot();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_LIST)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_DISK_LIST);
+ if (opt == NULL) {
+ BioSkipPartitions = FALSE;
+ } else {
+ BioSkipPartitions = (opt[0] == 'd');
+ }
+ PrintBioList();
+ }
+
+ // Authorization
+ if (ShellCommandLineGetFlag(Package, OPT_AUTH_CREATE_HEADER)) {
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ res = CreateVolumeHeaderOnDisk(BioIndexStart, NULL, NULL, NULL);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ } else {
+ ERR_PRINT(L"Select volume\n");
+ }
+ }
+
+ // GPT and DeList
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_RND_SAVE)) {
+ UINT8 temp[4];
+ if (EFI_ERROR(res = DeListLoadFromFile()) || // Load DeList
+ EFI_ERROR(res = RndGetBytes(temp, sizeof(temp))) || // Test Rnd
+ EFI_ERROR(res = DeListRndSave()) // Try to save RdnRaw to DeList
+ ) {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_HIDE)) {
+ CONST CHAR16* opt1 = NULL;
+ CONST CHAR16* opt2 = NULL;
+ UINTN idx;
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ if (!ShellCommandLineGetFlag(Package, OPT_PARTITION_IDX_TEMPLATE)) {
+ ERR_PRINT(L"No base partition index\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ opt1 = ShellCommandLineGetValue(Package, OPT_PARTITION_IDX_TEMPLATE);
+ idx = StrDecimalToUintn(opt1);
+ CopyMem(&DcsHidePart, &GptMainEntrys[idx], sizeof(DcsHidePart));
+ opt1 = ShellCommandLineGetValue(Package, OPT_PARTITION_HIDE);
+ DcsHidePart.StartingLBA = StrDecimalToUint64(opt1);
+ opt2 = StrStr(opt1, L" ");
+ if (opt2 == NULL) {
+ EFI_ERROR(L"Select end sector\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ DcsHidePart.EndingLBA = StrDecimalToUint64(opt2);
+ GptHideParts();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_EDIT_EXEC)) {
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ DeListExecEdit();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_EDIT_PWD_CACHE)) {
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ DeListPwdCacheEdit();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_EDIT)) {
+ CONST CHAR16* opt1 = NULL;
+ UINTN idx;
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+
+ opt1 = ShellCommandLineGetValue(Package, OPT_PARTITION_EDIT);
+ idx = StrDecimalToUintn(opt1);
+ GptEdit(idx);
+ }
+
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_LIST)) {
+ if (GptMainEntrys == NULL) {
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ res = GptLoadFromDisk(BioIndexStart);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ } else {
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ EFI_ERROR(L"Select file or disk\n");
+ return res;
+ }
+ }
+ }
+ DeListPrint();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_ENCRYPT)) {
+ GptCryptFile(TRUE);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_DECRYPT)) {
+ GptCryptFile(FALSE);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_ZERO)) {
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ DeListZero();
+ DeListSaveToFile();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_SAVE)) {
+ if (GptMainEntrys == NULL && DeList == NULL) {
+ if (!ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ EFI_ERROR(L"Select disk\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ res = GptLoadFromDisk(BioIndexStart);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ }
+ DeListSaveToFile();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_APPLY)) {
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START) &&
+ ShellCommandLineGetFlag(Package, OPT_PARTITION_FILE)
+ ) {
+ res = DeListLoadFromFile();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ DeListApplySectorsToDisk(BioIndexStart);
+ } else {
+ EFI_ERROR(L"Select file and disk\n");
+ }
+ }
+
+ // Key file
+ if (ShellCommandLineGetFlag(Package, OPT_KEYFILE_PLATFORM)) {
+ CONST CHAR16* opt = NULL;
+ CHAR8 *buf;
+ UINTN len;
+ opt = ShellCommandLineGetValue(Package, OPT_KEYFILE_PLATFORM);
+ res = SMBIOSGetSerials();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"SMBIOS: %r\n", res);
+ return res;
+ }
+ res = PlatformGetID(gBIOHandles[BioIndexStart], &buf, &len);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Platform ID: %r\n", res);
+ return res;
+ }
+ res = FileSave(NULL, (CHAR16*)opt, buf, len);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Save: %r\n", res);
+ return res;
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_WIPE)) {
+ CONST CHAR16* opt1 = NULL;
+ CONST CHAR16* opt2 = NULL;
+ UINT64 start;
+ UINT64 end;
+ if (!ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ ERR_PRINT(L"Select disk\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ opt1 = ShellCommandLineGetValue(Package, OPT_WIPE);
+ start = StrDecimalToUint64(opt1);
+ opt2 = StrStr(opt1, L" ") + 1;
+ end = StrDecimalToUint64(opt2);
+ return BlockRangeWipe(gBIOHandles[BioIndexStart], start, end);
+ }
+
+
+ // Security region
+ if (ShellCommandLineGetFlag(Package, OPT_SECREGION_MARK)) {
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_SECREGION_MARK);
+ gSecRigonCount = StrDecimalToUintn(opt);
+ SecRigionMark();
+ } else {
+ ERR_PRINT(L"Select disk and security region count");
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_SECREGION_WIPE)) {
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ CONST CHAR16* opt = NULL;
+ opt = ShellCommandLineGetValue(Package, OPT_SECREGION_WIPE);
+ gSecRigonCount = StrDecimalToUintn(opt);
+ SecRigionWipe();
+ }
+ else {
+ ERR_PRINT(L"Select disk and security region count");
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_SECREGION_ADD)) {
+ if (ShellCommandLineGetFlag(Package, OPT_PARTITION_FILE) &&
+ ShellCommandLineGetFlag(Package, OPT_DISK_START)) {
+ CONST CHAR16* opt = NULL;
+ UINTN secRegionIdx;
+ opt = ShellCommandLineGetValue(Package, OPT_SECREGION_ADD);
+ secRegionIdx = StrDecimalToUintn(opt);
+ SecRigionAdd(secRegionIdx);
+ }
+ else {
+ ERR_PRINT(L"Select disk and GPT file");
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ // Encrypt, decrypt, change password
+ if (ShellCommandLineGetFlag(Package, OPT_DISK_CHECK)) {
+ DisksAuthCheck();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_VOLUME_CHANGEPWD)) {
+ CONST CHAR16* opt = NULL;
+ UINTN disk;
+ opt = ShellCommandLineGetValue(Package, OPT_VOLUME_CHANGEPWD);
+ disk = StrDecimalToUintn(opt);
+ VolumeChangePassword(disk);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_VOLUME_ENCRYPT)) {
+ CONST CHAR16* opt = NULL;
+ UINTN disk;
+ opt = ShellCommandLineGetValue(Package, OPT_VOLUME_ENCRYPT);
+ disk = StrDecimalToUintn(opt);
+ VolumeEncrypt(disk);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_VOLUME_DECRYPT)) {
+ CONST CHAR16* opt = NULL;
+ UINTN disk;
+ opt = ShellCommandLineGetValue(Package, OPT_VOLUME_DECRYPT);
+ disk = StrDecimalToUintn(opt);
+ VolumeDecrypt(disk);
+ }
+
+
+ return EFI_SUCCESS;
+}
diff --git a/DcsCfg/DcsCfgSetup.c b/DcsCfg/DcsCfgSetup.c
new file mode 100644
index 0000000..d773fb7
--- /dev/null
+++ b/DcsCfg/DcsCfgSetup.c
@@ -0,0 +1,39 @@
+/** @file
+DCS configuration tool. Interactive setup.
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+
+#include "DcsCfg.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Interactive setup
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+DcsInteractiveSetup() {
+ EFI_STATUS res = EFI_SUCCESS;
+ CHAR8 cmd[128];
+ InitBio();
+ InitFS();
+ InitGraph();
+ gST->ConOut->EnableCursor(gST->ConOut, TRUE);
+ ERR_PRINT(L"\n\rInteractive setup is not implemented! Press enter to continue\n\r");
+ AskAsciiString("\rDCS>", cmd, sizeof(cmd), 1);
+ return res;
+}
diff --git a/DcsCfg/DcsCfgTouch.c b/DcsCfg/DcsCfgTouch.c
new file mode 100644
index 0000000..3553052
--- /dev/null
+++ b/DcsCfg/DcsCfgTouch.c
@@ -0,0 +1,95 @@
+/** @file
+DCS configuration. Touch devices.
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "DcsCfg.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Touch
+//////////////////////////////////////////////////////////////////////////
+UINTN TouchIndex = 0;
+
+void TouchPrintDevicePath(EFI_HANDLE handle) {
+ EFI_ABSOLUTE_POINTER_PROTOCOL* absio = NULL;
+ EfiPrintDevicePath(handle);
+ TouchGetIO(handle, &absio);
+ if (absio != NULL) {
+ EFI_STATUS res;
+ EFI_ABSOLUTE_POINTER_STATE aps;
+ SetMem(&aps, sizeof(aps), 0);
+ res = absio->GetState(absio, &aps);
+ OUT_PRINT(L" - X[%lld,%lld] Y[%lld,%lld] Z[%lld,%lld] A[0x%x] S[%r (%lld,%lld,%lld), 0x%x]",
+ absio->Mode->AbsoluteMinX, absio->Mode->AbsoluteMaxX,
+ absio->Mode->AbsoluteMinY, absio->Mode->AbsoluteMaxY,
+ absio->Mode->AbsoluteMinZ, absio->Mode->AbsoluteMaxZ,
+ absio->Mode->Attributes,
+ res, aps.CurrentX, aps.CurrentY, aps.CurrentZ, aps.ActiveButtons
+ );
+ }
+}
+
+void TouchPrintDevicePathByIndex(UINTN touchIndex) {
+ OUT_PRINT(L"%V%d%N ", touchIndex);
+ TouchPrintDevicePath(gTouchHandles[touchIndex]);
+}
+
+void TouchPrintDevicePaths(CHAR16* msg) {
+ UINTN i;
+ OUT_PRINT(msg);
+ for (i = 0; i < gTouchCount; ++i) {
+ TouchPrintDevicePathByIndex(i);
+ OUT_PRINT(L"\n");
+ }
+}
+
+VOID
+PrintTouchList() {
+ InitTouch();
+ TouchPrintDevicePaths(L"%HTouch handles%N\n");
+}
+
+VOID
+TestTouch() {
+ EFI_ABSOLUTE_POINTER_PROTOCOL* absio = NULL;
+ EFI_HANDLE handle;
+ EFI_STATUS res;
+
+ InitTouch();
+ if (TouchIndex >= gTouchCount) return;
+ handle = gTouchHandles[TouchIndex];
+ EfiPrintDevicePath(handle);
+ TouchGetIO(handle, &absio);
+ if (absio != NULL) {
+ EFI_ABSOLUTE_POINTER_STATE aps;
+ EFI_EVENT events[2];
+ UINTN EventIndex;
+
+ events[0] = gST->ConIn->WaitForKey;
+ events[1] = absio->WaitForInput;
+ do {
+ gBS->WaitForEvent(2, events, &EventIndex);
+ SetMem(&aps, sizeof(aps), 0);
+ res = absio->GetState(absio, &aps);
+ OUT_PRINT(L" S[%r (%lld,%lld,%lld), 0x%x]",
+ res, aps.CurrentX, aps.CurrentY, aps.CurrentZ, aps.ActiveButtons
+ );
+ } while (EventIndex == 1);
+ }
+}
+
diff --git a/DcsInt/DcsInt.c b/DcsInt/DcsInt.c
new file mode 100644
index 0000000..3867067
--- /dev/null
+++ b/DcsInt/DcsInt.c
@@ -0,0 +1,1057 @@
+/** @file
+Block R/W interceptor
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include "DcsInt.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/PasswordLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DcsCfgLib.h>
+
+#include "common/Tcdefs.h"
+#include "common/Crypto.h"
+#include "common/Volumes.h"
+#include "common/Crc.h"
+#include "crypto/cpu.h"
+#include "BootCommon.h"
+#include "DcsVeraCrypt.h"
+#include <Guid/EventGroup.h>
+
+// #define TRC_HANDLE_PATH(msg,h) \
+// OUT_PRINT(msg); \
+// EfiPrintDevicePath(h); \
+// OUT_PRINT(L"\n")
+#define TRC_HANDLE_PATH(msg,h)
+
+EFI_DEVICE_PATH* gDcsBoot;
+UINTN gDcsBootSize;
+
+DCSINT_BLOCK_IO* DcsIntBlockIoFirst = NULL; //< List of block I/O head
+
+EFI_DRIVER_BINDING_PROTOCOL g_DcsIntDriverBinding = {
+ DcsIntBindingSupported,
+ DcsIntBindingStart,
+ DcsIntBindingStop,
+ DCSINT_DRIVER_VERSION,
+ NULL,
+ NULL
+};
+
+#pragma pack(1)
+typedef struct _BOOT_PARAMS {
+ CHAR8 Offset[TC_BOOT_LOADER_ARGS_OFFSET];
+ BootArguments BootArgs;
+ BOOT_CRYPTO_HEADER BootCryptoInfo;
+ uint16 pad1;
+ SECREGION_BOOT_PARAMS SecRegion;
+} BOOT_PARAMS, *PBOOT_PARAMS;
+#pragma pack()
+
+UINT32 gHeaderSaltCrc32 = 0;
+PBOOT_PARAMS bootParams = NULL;
+//#define EFI_BOOTARGS_REGIONS_TEST ,0x9000000, 0xA000000
+#define EFI_BOOTARGS_REGIONS_TEST
+UINTN BootArgsRegions[] = { EFI_BOOTARGS_REGIONS_HIGH, EFI_BOOTARGS_REGIONS_LOW EFI_BOOTARGS_REGIONS_TEST };
+
+CHAR8 Header[512];
+UINT32 BootDriveSignature;
+EFI_GUID BootDriveSignatureGpt;
+
+EFI_HANDLE SecRegionHandle = NULL;
+UINT64 SecRegionSector = 0;
+UINT8* SecRegionData = NULL;
+UINTN SecRegionSize = 0;
+UINTN SecRegionOffset = 0;
+PCRYPTO_INFO SecRegionCryptInfo = NULL;
+
+void HaltPrint(const CHAR16* Msg)
+{
+ Print(L"%s - system Halted\n", Msg);
+ EfiCpuHalt();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Boot params memory
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+GetBootParamsMemory() {
+ EFI_STATUS status = 0;
+ UINTN index;
+ if (bootParams != NULL) return EFI_SUCCESS;
+ for (index = 0; index < sizeof(BootArgsRegions) / sizeof(BootArgsRegions[1]); ++index) {
+ status = PrepareMemory(BootArgsRegions[index], sizeof(*bootParams), &bootParams);
+ if (!EFI_ERROR(status)) {
+ return status;
+ }
+ }
+ return status;
+}
+
+EFI_STATUS
+SetSecRegionParamsMemory() {
+ EFI_STATUS status = 0;
+ UINTN index;
+ UINT8* secRegion = NULL;
+ UINT32 crc;
+ if (bootParams == NULL) return EFI_NOT_READY;
+
+ bootParams->SecRegion.Ptr = 0;
+ bootParams->SecRegion.Size = 0;
+ if (DeList != NULL) {
+ for (index = 0; index < sizeof(BootArgsRegions) / sizeof(BootArgsRegions[1]); ++index) {
+ status = PrepareMemory(BootArgsRegions[index], DeList->DataSize, &secRegion);
+ if (!EFI_ERROR(status)) {
+// OUT_PRINT(L"bootParams %08x SecRegion %08x\n", (UINTN)bootParams, (UINTN)secRegion);
+ CopyMem(secRegion, SecRegionData + SecRegionOffset, DeList->DataSize);
+ bootParams->SecRegion.Ptr = (UINT64)secRegion;
+ bootParams->SecRegion.Size = DeList->DataSize;
+ break;
+ }
+ }
+ }
+ status = gBS->CalculateCrc32(&bootParams->SecRegion, sizeof(SECREGION_BOOT_PARAMS) - 4, &crc);
+ bootParams->SecRegion.Crc = crc;
+ return status;
+}
+
+EFI_STATUS
+PrepareBootParams(
+ IN UINT32 bootDriveSignature,
+ IN PCRYPTO_INFO cryptoInfo)
+{
+ BootArguments *bootArgs;
+ if (bootParams == NULL) return EFI_UNSUPPORTED;
+ bootArgs = &bootParams->BootArgs;
+ TC_SET_BOOT_ARGUMENTS_SIGNATURE(bootArgs->Signature);
+ bootArgs->BootLoaderVersion = VERSION_NUM;
+ bootArgs->CryptoInfoOffset = (uint16)(FIELD_OFFSET(BOOT_PARAMS, BootCryptoInfo));
+ bootArgs->CryptoInfoLength = (uint16)(sizeof(BOOT_CRYPTO_HEADER) + 2 + sizeof(SECREGION_BOOT_PARAMS));
+ bootArgs->HeaderSaltCrc32 = gHeaderSaltCrc32;
+ CopyMem(&bootArgs->BootPassword, &gAuthPassword, sizeof(gAuthPassword));
+ bootArgs->HiddenSystemPartitionStart = 0;
+ bootArgs->DecoySystemPartitionStart = 0;
+ bootArgs->BootDriveSignature = bootDriveSignature;
+ bootArgs->Flags = (uint32)(gAuthPim << 16);
+ bootArgs->BootArgumentsCrc32 = GetCrc32((byte *)bootArgs, (int)((byte *)&bootArgs->BootArgumentsCrc32 - (byte *)bootArgs));
+ bootParams->BootCryptoInfo.ea = (uint16)cryptoInfo->ea;
+ bootParams->BootCryptoInfo.mode = (uint16)cryptoInfo->mode;
+ bootParams->BootCryptoInfo.pkcs5 = (uint16)cryptoInfo->pkcs5;
+ SetSecRegionParamsMemory();
+
+ // Clean auth data
+ ZeroMem(&gAuthPassword, sizeof(gAuthPassword));
+ gAuthPim = 0;
+
+ return EFI_SUCCESS;
+}
+
+void GetIntersection(uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength)
+{
+ uint64 end1 = start1 + length1 - 1;
+ uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
+
+ *intersectStart = (start1 >= start2) ? start1 : start2;
+ *intersectLength = (uint32)((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart);
+
+ if (*intersectLength == 0)
+ *intersectStart = start1;
+}
+
+VOID UpdateDataBuffer(
+ IN OUT UINT8* buf,
+ IN UINT32 bufSize,
+ IN UINT64 sector
+ ) {
+ UINT64 intersectStart;
+ UINT32 intersectLength;
+ UINTN i;
+ if (DeList == NULL) return;
+ for (i = 0; i < DeList->Count; ++i) {
+ if (DeList->DE[i].Type == DE_Sectors) {
+ GetIntersection(
+ sector << 9, bufSize,
+ DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1,
+ &intersectStart, &intersectLength
+ );
+ if (intersectLength != 0) {
+// OUT_PRINT(L"S %d : %lld, %d\n", i, intersectStart, intersectLength);
+// OUT_PRINT(L"S");
+ CopyMem(
+ buf + (intersectStart - (sector << 9)),
+ SecRegionData + SecRegionOffset + DeList->DE[i].Sectors.Offset + (intersectStart - (sector << 9)),
+ intersectLength
+ );
+ }
+ }
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+// List of block I/O
+//////////////////////////////////////////////////////////////////////////
+DCSINT_BLOCK_IO*
+GetBlockIoByHandle(
+ IN EFI_HANDLE handle)
+{
+ DCSINT_BLOCK_IO *DcsIntBlockIo = DcsIntBlockIoFirst;
+ while (DcsIntBlockIo != NULL) {
+ if (DcsIntBlockIo->Controller == handle) {
+ return DcsIntBlockIo;
+ }
+ DcsIntBlockIo = DcsIntBlockIo->Next;
+ }
+ return NULL;
+}
+
+DCSINT_BLOCK_IO*
+GetBlockIoByProtocol(
+ IN EFI_BLOCK_IO_PROTOCOL* protocol)
+{
+ DCSINT_BLOCK_IO *DcsIntBlockIo = DcsIntBlockIoFirst;
+ while (DcsIntBlockIo != NULL) {
+ if (DcsIntBlockIo->BlockIo == protocol) {
+ return DcsIntBlockIo;
+ }
+ DcsIntBlockIo = DcsIntBlockIo->Next;
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Read/Write
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+IntBlockIO_Write(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ DCSINT_BLOCK_IO *DcsIntBlockIo = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_LBA startSector;
+ DcsIntBlockIo = GetBlockIoByProtocol(This);
+
+ if (DcsIntBlockIo) {
+ startSector = Lba;
+ startSector += gAuthBoot ? 0 : DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9;
+ //Print(L"This[0x%x] mid %x Write: lba=%lld, size=%d %r\n", This, MediaId, Lba, BufferSize, Status);
+ if ((startSector >= DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9) &&
+ (startSector < ((DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value + DcsIntBlockIo->CryptInfo->EncryptedAreaLength.Value) >> 9))) {
+ VOID* writeCrypted;
+ writeCrypted = MEM_ALLOC(BufferSize);
+ if (writeCrypted == NULL) {
+ Status = EFI_BAD_BUFFER_SIZE;
+
+ }
+ CopyMem(writeCrypted, Buffer, BufferSize);
+ // Print(L"*");
+ UpdateDataBuffer(writeCrypted, (UINT32)BufferSize, startSector);
+ EncryptDataUnits(writeCrypted, (UINT64_STRUCT*)&startSector, (UINT32)(BufferSize >> 9), DcsIntBlockIo->CryptInfo);
+ Status = DcsIntBlockIo->LowWrite(This, MediaId, startSector, BufferSize, writeCrypted);
+ MEM_FREE(writeCrypted);
+ }
+ else {
+ Status = DcsIntBlockIo->LowWrite(This, MediaId, startSector, BufferSize, Buffer);
+ }
+ }
+ else {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+ return Status;
+}
+
+EFI_STATUS
+IntBlockIO_Read(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ DCSINT_BLOCK_IO *DcsIntBlockIo = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_LBA startSector;
+
+ DcsIntBlockIo = GetBlockIoByProtocol(This);
+ if (DcsIntBlockIo) {
+ startSector = Lba;
+ startSector += gAuthBoot ? 0 : DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9;
+ Status = DcsIntBlockIo->LowRead(This, MediaId, startSector, BufferSize, Buffer);
+ //Print(L"This[0x%x] mid %x ReadBlock: lba=%lld, size=%d %r\n", This, MediaId, Lba, BufferSize, Status);
+ if ((startSector >= DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9) &&
+ (startSector < ((DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value + DcsIntBlockIo->CryptInfo->EncryptedAreaLength.Value) >> 9))) {
+ // Print(L".");
+ DecryptDataUnits(Buffer, (UINT64_STRUCT*)&startSector, (UINT32)(BufferSize >> 9), DcsIntBlockIo->CryptInfo);
+ }
+ UpdateDataBuffer(Buffer, (UINT32)BufferSize, startSector);
+ }
+ else {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+ return Status;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Block IO hook
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+IntBlockIo_Hook(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ DCSINT_BLOCK_IO *DcsIntBlockIo = 0;
+ EFI_STATUS Status;
+// EFI_TPL Tpl;
+
+ // Already hook?
+ DcsIntBlockIo = GetBlockIoByHandle(DeviceHandle);
+ if (DcsIntBlockIo != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gBS->OpenProtocol(
+ DeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&BlockIo,
+ This->DriverBindingHandle,
+ DeviceHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (!EFI_ERROR(Status)) {
+ // Check is this protocol already hooked
+ DcsIntBlockIo = (DCSINT_BLOCK_IO *)MEM_ALLOC(sizeof(DCSINT_BLOCK_IO));
+ if (DcsIntBlockIo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // construct new DcsIntBlockIo
+ DcsIntBlockIo->Sign = DCSINT_BLOCK_IO_SIGN;
+ DcsIntBlockIo->Controller = DeviceHandle;
+ DcsIntBlockIo->BlockIo = BlockIo;
+ DcsIntBlockIo->IsReinstalled = 0;
+
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol(
+ DeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ This->DriverBindingHandle,
+ DeviceHandle
+ );
+ MEM_FREE(DcsIntBlockIo);
+ return EFI_UNSUPPORTED;
+ }
+ // Block
+// Tpl = gBS->RaiseTPL(TPL_NOTIFY);
+ // Install new routines
+ DcsIntBlockIo->CryptInfo = SecRegionCryptInfo;
+ DcsIntBlockIo->LowRead = BlockIo->ReadBlocks;
+ DcsIntBlockIo->LowWrite = BlockIo->WriteBlocks;
+ BlockIo->ReadBlocks = IntBlockIO_Read;
+ BlockIo->WriteBlocks = IntBlockIO_Write;
+
+ // close protocol before reinstall
+ gBS->CloseProtocol(
+ DeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ This->DriverBindingHandle,
+ DeviceHandle
+ );
+
+ // add to global list
+ if (DcsIntBlockIoFirst == NULL) {
+ DcsIntBlockIoFirst = DcsIntBlockIo;
+ }
+ else {
+ DcsIntBlockIoFirst->Next = DcsIntBlockIoFirst;
+ DcsIntBlockIoFirst = DcsIntBlockIo;
+ }
+
+ // reinstall BlockIo protocol
+ Status = gBS->ReinstallProtocolInterface(
+ DeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ BlockIo,
+ BlockIo
+ );
+
+// gBS->RestoreTPL(Tpl);
+ DcsIntBlockIo->IsReinstalled = 1;
+
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// DriverBinding routines
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+DcsIntBindingStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+
+ TRC_HANDLE_PATH(L"t: ", Controller);
+
+ // hook blockIo
+ Status = IntBlockIo_Hook(This, Controller);
+ if (EFI_ERROR(Status)) {
+ HaltPrint(L"Failed");
+ }
+ return Status;
+}
+
+EFI_STATUS
+DcsIntBindingSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_DEVICE_PATH *DevicePath;
+ DevicePath = DevicePathFromHandle(Controller);
+ if ((DevicePath != NULL) && CompareMem(DevicePath, gDcsBoot, gDcsBootSize) == 0) {
+ DCSINT_BLOCK_IO* DcsIntBlockIo = NULL;
+ // Is installed?
+ DcsIntBlockIo = GetBlockIoByHandle(Controller);
+ if (DcsIntBlockIo != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+DcsIntBindingStop(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ TRC_HANDLE_PATH(L"p: ", Controller);
+ return EFI_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Security regions
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+SecRegionLoadDefault(EFI_HANDLE partHandle)
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ HARDDRIVE_DEVICE_PATH dpVolme;
+ EFI_BLOCK_IO_PROTOCOL *bio = NULL;
+ EFI_PARTITION_TABLE_HEADER* gptHdr;
+ res = EfiGetPartDetails(partHandle, &dpVolme, &SecRegionHandle);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Part details: %r\n,", res);
+ return res;
+ }
+
+ // get BlockIo protocol
+ bio = EfiGetBlockIO(SecRegionHandle);
+ if (bio == NULL) {
+ ERR_PRINT(L"Block io not supported\n,");
+ return EFI_NOT_FOUND;
+ }
+
+ SecRegionData = MEM_ALLOC(512);
+ if (SecRegionData == NULL) {
+ ERR_PRINT(L"No memory\n,");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ SecRegionSize = 512;
+
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 0, 512, SecRegionData);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read: %r\n", res);
+ goto error;
+ }
+
+ BootDriveSignature = *(uint32 *)(SecRegionData + 0x1b8);
+
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 1, 512, SecRegionData);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read: %r\n", res);
+ goto error;
+ }
+
+ gptHdr = (EFI_PARTITION_TABLE_HEADER*)SecRegionData;
+ CopyMem(&BootDriveSignatureGpt, &gptHdr->DiskGUID, sizeof(BootDriveSignatureGpt));
+
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, TC_BOOT_VOLUME_HEADER_SECTOR, 512, SecRegionData);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read: %r\n", res);
+ goto error;
+ }
+
+ return EFI_SUCCESS;
+error:
+ MEM_FREE(SecRegionData);
+ SecRegionData = NULL;
+ SecRegionSize = 0;
+ return res;
+}
+
+EFI_STATUS
+SecRegionChangePwd() {
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL* bio = NULL;
+ PCRYPTO_INFO cryptoInfo, ci;
+ Password newPassword;
+ Password confirmPassword;
+ INT32 vcres;
+
+ Status = RndPreapare();
+ if (EFI_ERROR(Status)) {
+ ERR_PRINT(L"Rnd: %r\n", Status);
+ return Status;
+ }
+
+ do {
+ ZeroMem(&newPassword, sizeof(newPassword));
+ ZeroMem(&confirmPassword, sizeof(newPassword));
+ VCAskPwd(AskPwdNew, &newPassword);
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return EFI_NOT_READY;
+ }
+ VCAskPwd(AskPwdConfirm, &confirmPassword);
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return EFI_NOT_READY;
+ }
+ if (newPassword.Length == confirmPassword.Length) {
+ if (CompareMem(newPassword.Text, confirmPassword.Text, confirmPassword.Length) == 0) {
+ break;
+ }
+ }
+ ERR_PRINT(L"Password mismatch");
+ } while (TRUE);
+
+ OUT_PRINT(L"Generate...\n\r");
+ cryptoInfo = SecRegionCryptInfo;
+ vcres = CreateVolumeHeaderInMemory(
+ gAuthBoot, Header,
+ cryptoInfo->ea,
+ cryptoInfo->mode,
+ &newPassword,
+ cryptoInfo->pkcs5,
+ gAuthPim,
+ cryptoInfo->master_keydata,
+ &ci,
+ cryptoInfo->VolumeSize.Value,
+ 0, //(volumeType == TC_VOLUME_TYPE_HIDDEN) ? cryptoInfo->hiddenVolumeSize : 0,
+ cryptoInfo->EncryptedAreaStart.Value,
+ cryptoInfo->EncryptedAreaLength.Value,
+ gAuthTc ? 0 : cryptoInfo->RequiredProgramVersion,
+ cryptoInfo->HeaderFlags,
+ cryptoInfo->SectorSize,
+ FALSE);
+
+ if (vcres != 0) {
+ ERR_PRINT(L"header create error(%x)\n", vcres);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // get BlockIo protocol
+ bio = EfiGetBlockIO(SecRegionHandle);
+ if (bio == NULL) {
+ ERR_PRINT(L"Block io not supported\n,");
+ return EFI_NOT_FOUND;
+ }
+
+ Status = bio->WriteBlocks(bio, bio->Media->MediaId, SecRegionSector, 512, Header);
+ if (EFI_ERROR(Status)) {
+ ERR_PRINT(L"Write: %r\n", Status);
+ return Status;
+ }
+ CopyMem(&gAuthPassword, &newPassword, sizeof(gAuthPassword));
+ CopyMem(SecRegionData + SecRegionOffset, Header, 512);
+ ERR_PRINT(L"Update (%r)\n", Status);
+ return Status;
+}
+
+EFI_STATUS
+SelectDcsBootBySignature()
+{
+ EFI_STATUS res = EFI_NOT_FOUND;
+ EFI_BLOCK_IO_PROTOCOL* bio = NULL;
+ EFI_PARTITION_TABLE_HEADER* gptHdr;
+ UINTN i;
+ for (i = 0; i < gBIOCount; ++i) {
+ if(EfiIsPartition(gBIOHandles[i])) continue;
+ bio = EfiGetBlockIO(gBIOHandles[i]);
+ if(bio == NULL) continue;
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 0, 512, Header);
+ if(EFI_ERROR(res)) continue;
+ if((*(UINT32*)(Header+0x1b8)) != BootDriveSignature) continue;
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 1, 512, Header);
+ if (EFI_ERROR(res)) continue;
+ gptHdr = (EFI_PARTITION_TABLE_HEADER*)Header;
+ if (CompareMem(&BootDriveSignatureGpt, &gptHdr->DiskGUID, sizeof(BootDriveSignatureGpt)) != 0) continue;
+ gDcsBoot = DevicePathFromHandle(gBIOHandles[i]);
+ gDcsBootSize = GetDevicePathSize(gDcsBoot);
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+SecRegionTryDecrypt()
+{
+ int vcres = 1;
+ EFI_STATUS res = EFI_SUCCESS;
+
+ PlatformGetID(SecRegionHandle, &gPlatformKeyFile, &gPlatformKeyFileSize);
+
+ do {
+ SecRegionOffset = 0;
+ VCAuthAsk();
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return EFI_NOT_READY;
+ }
+ OUT_PRINT(L"Authorize...\n\r");
+ do {
+ CopyMem(Header, SecRegionData + SecRegionOffset, 512);
+ vcres = ReadVolumeHeader(gAuthBoot, Header, &gAuthPassword, gAuthHash, gAuthPim, gAuthTc, &SecRegionCryptInfo, NULL);
+ SecRegionOffset += (vcres != 0) ? 1024 * 128 : 0;
+ } while (SecRegionOffset < SecRegionSize && vcres != 0);
+ if (vcres == 0) {
+ OUT_PRINT(L"Success\n");
+ OUT_PRINT(L"start %lld len %lld\n", SecRegionCryptInfo->EncryptedAreaStart.Value, SecRegionCryptInfo->EncryptedAreaLength.Value);
+ break;
+ } else {
+ ERR_PRINT(L"Decript error(%x)\n\r", vcres);
+ }
+ } while (vcres != 0 && gAuthRetry != 0);
+ if (vcres != 0) {
+ return EFI_CRC_ERROR;
+ }
+
+ SecRegionSector = 62 + SecRegionOffset / 512;
+ DeList = NULL;
+ if (SecRegionSize > 512) {
+ UINT64 startUnit = 0;
+ DecryptDataUnits(SecRegionData + SecRegionOffset + 512, (UINT64_STRUCT*)&startUnit,(UINT32)255, SecRegionCryptInfo);
+ if (CompareMem(SecRegionData + SecRegionOffset + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID)) != 0) {
+ ERR_PRINT(L"Wrong DCS list header");
+ return EFI_CRC_ERROR;
+ }
+ DeList = (DCS_DISK_ENTRY_LIST *)(SecRegionData + SecRegionOffset + 512);
+ CopyMem(&BootDriveSignature, &DeList->DE[DE_IDX_DISKID].DiskId.MbrID, sizeof(BootDriveSignature));
+ CopyMem(&BootDriveSignatureGpt, &DeList->DE[DE_IDX_DISKID].DiskId.GptID, sizeof(BootDriveSignatureGpt));
+
+ if (DeList->DE[DE_IDX_EXEC].Type == DE_ExecParams) {
+ DCS_DEP_EXEC *execParams = NULL;
+ execParams = (DCS_DEP_EXEC *)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_EXEC].Offset);
+ EfiSetVar(L"DcsExecPartGuid", NULL, &execParams->ExecPartGuid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ EfiSetVar(L"DcsExecCmd", NULL, &execParams->ExecCmd, (StrLen((CHAR16*)&execParams->ExecCmd) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ }
+
+ if (DeList->DE[DE_IDX_PWDCACHE].Type == DE_PwdCache) {
+ DCS_DEP_PWD_CACHE *pwdCache = NULL;
+ UINT64 sector = 0;
+ pwdCache = (DCS_DEP_PWD_CACHE *)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_PWDCACHE].Offset);
+ EncryptDataUnits((UINT8*)pwdCache, (UINT64_STRUCT*)&sector, 1, SecRegionCryptInfo);
+ }
+
+ if (DeList->DE[DE_IDX_RND].Type == DE_Rnd) {
+ UINT8 temp[4];
+ UINT64 sector = 0;
+ DCS_RND_SAVED* rndNewSaved;
+ DCS_RND_SAVED* rndSaved = (DCS_RND_SAVED*)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_RND].Offset);
+ if (DeList->DE[DE_IDX_RND].Length == sizeof(DCS_RND_SAVED)) {
+ if (!EFI_ERROR(res = RndLoad(rndSaved, &gRnd)) &&
+ !EFI_ERROR(res = RndGetBytes(temp, sizeof(temp))) &&
+ !EFI_ERROR(res = RndSave(gRnd, &rndNewSaved))
+ ) {
+ EFI_BLOCK_IO_PROTOCOL *bio = NULL;
+ sector = (DeList->DE[DE_IDX_RND].Offset >> 9) - 1;
+ OUT_PRINT(L"Last login %H%t%N\n", &rndSaved->SavedAt);
+
+ EncryptDataUnits((UINT8*)rndNewSaved, (UINT64_STRUCT*)&sector, 1, SecRegionCryptInfo);
+ sector = SecRegionSector + (DeList->DE[DE_IDX_RND].Offset >> 9);
+
+ // get BlockIo protocol
+ bio = EfiGetBlockIO(SecRegionHandle);
+ if (bio == NULL) {
+ ERR_PRINT(L"Block io not supported\n,");
+ }
+
+ res = bio->WriteBlocks(bio, bio->Media->MediaId, sector, 512, rndNewSaved);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ }
+ }
+ }
+ }
+ }
+
+ // Select boot device
+ res = SelectDcsBootBySignature();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Decrypt device not found\n");
+ return res;
+ }
+
+ // Change password if requested
+ if (gAuthPwdCode == AskPwdRetChange && gRnd != NULL) {
+ res = RndPreapare();
+ if (!EFI_ERROR(res)) {
+ res = SecRegionChangePwd();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ } else {
+ ERR_PRINT(L"Random: %r\n", res);
+ }
+ }
+ gHeaderSaltCrc32 = GetCrc32(SecRegionData + SecRegionOffset, PKCS5_SALT_SIZE);
+ return EFI_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Exit action
+//////////////////////////////////////////////////////////////////////////
+enum OnExitTypes{
+ OnExitAuthFaild = 1,
+ OnExitAuthNotFound,
+ OnExitSuccess
+};
+
+BOOLEAN
+AsciiCharNCmp(
+ IN CHAR8 ch1,
+ IN CHAR8 ch2
+ )
+{
+ return (ch1 | 0x20) == (ch2 | 0x20);
+}
+
+CHAR8*
+AsciiStrNStr(
+ IN CHAR8* str,
+ IN CHAR8* pattern)
+{
+ CHAR8* pos1 = str;
+ CHAR8* pos2;
+ CHAR8* posp;
+ while (*pos1 != 0) {
+ posp = pattern;
+ pos2 = pos1;
+ while (*posp != 0 && *pos2 != 0 && AsciiCharNCmp(*pos2,*posp)) {
+ ++posp;
+ ++pos2;
+ }
+ if (*pos2 == 0) return NULL;
+ if (*posp == 0) return pos1;
+ ++pos1;
+ }
+ return NULL;
+}
+
+BOOLEAN
+OnExitGetParam(
+ IN CHAR8 *action,
+ IN CHAR8 *name,
+ OUT CHAR8 **value,
+ OUT CHAR16 **valueU
+ )
+{
+ CHAR8* pos;
+ UINTN len = 0;
+ UINTN i = 0;
+ pos = AsciiStrNStr(action, name);
+ if (pos == NULL) return FALSE;
+ pos += AsciiStrLen(name);
+ if(*pos != '(') return FALSE;
+ pos++;
+ while (pos[len] != 0 && pos[len] != ')') len++;
+ if (pos[len] == 0) return FALSE;
+ if (value != NULL) *value = MEM_ALLOC(len + 1);
+ if (valueU != NULL) *valueU = MEM_ALLOC((len + 1) * 2);
+ for (i = 0; i < len; ++i) {
+ if (value != NULL) (*value)[i] = pos[i];
+ if (valueU != NULL) (*valueU)[i] = pos[i];
+ }
+ return TRUE;
+}
+
+EFI_STATUS
+OnExit(
+ IN CHAR8 *action,
+ IN UINTN type,
+ IN EFI_STATUS retValue)
+{
+ CHAR8* guidStr = NULL;
+ CHAR8* exitStatusStr = NULL;
+ CHAR8* messageStr = NULL;
+ CHAR8* delayStr = NULL;
+ EFI_GUID *guid = NULL;
+ CHAR16 *fileStr = NULL;
+ if (action == NULL) return retValue;
+ if (OnExitGetParam(action, "guid", &guidStr, NULL)) {
+ EFI_GUID tmp;
+ if (AsciiStrToGuid(&tmp, guidStr)) {
+ guid = MEM_ALLOC(sizeof(EFI_GUID));
+ CopyMem(guid, &tmp, sizeof(EFI_GUID));
+ }
+ }
+
+ if (OnExitGetParam(action, "status", &exitStatusStr, NULL)) {
+ retValue = AsciiStrDecimalToUintn(exitStatusStr);
+ }
+
+ OnExitGetParam(action, "file", NULL, &fileStr);
+
+
+ if (OnExitGetParam(action, "printinfo", NULL, NULL)) {
+ OUT_PRINT(L"type %d\naction %a\n", type, action);
+ if (guid != NULL) OUT_PRINT(L"guid %g\n", guid);
+ if (fileStr != NULL) OUT_PRINT(L"file %s\n", fileStr);
+ if (exitStatusStr != NULL) OUT_PRINT(L"status %d, %r\n", retValue, retValue);
+ }
+
+ if (OnExitGetParam(action, "message", &messageStr, NULL)) {
+ OUT_PRINT(L"%a", messageStr);
+ }
+
+ if (OnExitGetParam(action, "delay", &delayStr, NULL)) {
+ UINTN delay;
+ EFI_INPUT_KEY key;
+ delay = AsciiStrDecimalToUintn(delayStr);
+ OUT_PRINT(L"\n");
+ key = KeyWait(L"\r%d ", delay, 0, 0);
+ if (key.UnicodeChar != 0) GetKey();
+ }
+
+ if (AsciiStrNStr(action, "halt") == action) {
+ EfiCpuHalt();
+ }
+
+ if (AsciiStrNStr(action, "exec") == action) {
+ if (guid != NULL) {
+ EFI_STATUS res;
+ EFI_HANDLE h;
+ res = EfiFindPartByGUID(guid, &h);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nCan't find start partition\n");
+ EfiCpuHalt();
+ }
+ // Try to exec
+ res = EfiExec(h, fileStr);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"\nStart %s - %r\n", fileStr, res);
+ EfiCpuHalt();
+ }
+ }
+
+ if (fileStr != NULL) {
+ EfiSetVar(L"DcsExecCmd", NULL, fileStr, (StrLen(fileStr) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ }
+ goto exit;
+ }
+
+ if (AsciiStrNStr(action, "postexec") == action) {
+ if (guid != NULL) {
+ EfiSetVar(L"DcsExecPartGuid", NULL, &guid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ }
+ if (fileStr != NULL) {
+ EfiSetVar(L"DcsExecCmd", NULL, fileStr, (StrLen(fileStr) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ }
+ goto exit;
+ }
+
+ if (AsciiStrStr(action, "exit") == action) {
+ goto exit;
+ }
+
+exit:
+ MEM_FREE(guidStr);
+ MEM_FREE(exitStatusStr);
+ MEM_FREE(messageStr);
+ MEM_FREE(delayStr);
+ MEM_FREE(guid);
+ MEM_FREE(fileStr);
+ return retValue;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Exit boot loader event
+//////////////////////////////////////////////////////////////////////////
+EFI_EVENT mVirtualAddrChangeEvent;
+VOID
+EFIAPI
+VirtualNotifyEvent(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ // Clean all sensible info and keys before transfer to OS
+ if (SecRegionCryptInfo != NULL) {
+ ZeroMem(SecRegionCryptInfo, sizeof(*SecRegionCryptInfo));
+ }
+
+ if (gRnd != NULL) {
+ ZeroMem(gRnd, sizeof(*gRnd));
+ }
+
+ if (SecRegionData != NULL) {
+ ZeroMem(SecRegionData, SecRegionSize);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Driver Entry Point
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+UefiMain(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS res;
+
+ InitBio();
+ InitFS();
+
+ // Remove BootNext to restore boot order
+ BootMenuItemRemove(L"BootNext");
+
+ // Load auth parameters
+ VCAuthLoadConfig();
+ if (gAuthSecRegionSearch) {
+ res = PlatformGetAuthData(&SecRegionData, &SecRegionSize, &SecRegionHandle);
+ if (!EFI_ERROR(res)) {
+ EFI_INPUT_KEY key;
+ EfiPrintDevicePath(SecRegionHandle);
+ OUT_PRINT(L"\n");
+ key = KeyWait(L"%2d \r", 2, 0, 0);
+ if (key.UnicodeChar != 0) {
+ GetKey();
+ }
+ }
+ } else if (gRUD != 0) {
+ // RUD defined
+ UINTN i;
+ BOOLEAN devFound = FALSE;
+ InitUsb();
+ for (i = 0; i < gUSBCount; ++i) {
+ CHAR8* id = NULL;
+ res = UsbGetId(gUSBHandles[i], &id);
+ if (!EFI_ERROR(res) && id != NULL) {
+ INT32 rud;
+ rud = GetCrc32((unsigned char*)id, (int)AsciiStrLen(id));
+ MEM_FREE(id);
+ if (rud == gRUD) {
+ devFound = TRUE;
+ break;
+ }
+ }
+ }
+ if (!devFound) return OnExit(gOnExitNotFound, OnExitAuthNotFound, EFI_NOT_FOUND);
+ }
+
+ // Try to find by OS partition GUID
+ if (SecRegionData == NULL && gPartitionGuidOS != NULL) {
+ UINTN i;
+ for (i = 0; i < gBIOCount; ++i) {
+ EFI_GUID guid;
+ res = EfiGetPartGUID(gBIOHandles[i], &guid);
+ if(EFI_ERROR(res)) continue;
+ if (memcmp(gPartitionGuidOS, &guid, sizeof(guid)) == 0) {
+ res = SecRegionLoadDefault(gBIOHandles[i]);
+ if (EFI_ERROR(res)) {
+ return OnExit(gOnExitNotFound, OnExitAuthNotFound, res);
+ }
+ }
+ }
+ }
+
+ // ask any way? (by DcsBoot flag)
+ if (SecRegionData == NULL) {
+ if (gDcsBootForce != 0) {
+ res = SecRegionLoadDefault(gFileRootHandle);
+ if (EFI_ERROR(res)) {
+ return OnExit(gOnExitNotFound, OnExitAuthNotFound, res);
+ }
+ } else {
+ return OnExit(gOnExitNotFound, OnExitAuthNotFound, EFI_NOT_FOUND);
+ }
+ }
+
+ res = GetBootParamsMemory();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"No boot args memory: %r\n\r", res);
+ KeyWait(L"%02d\r", 10, 0, 0);
+ return res;
+ }
+
+ DetectX86Features();
+ res = SecRegionTryDecrypt();
+ if (EFI_ERROR(res)) {
+ return OnExit(gOnExitFailed, OnExitAuthFaild, res);
+ }
+
+ res = PrepareBootParams(BootDriveSignature, SecRegionCryptInfo);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Can not set params for OS: %r", res);
+ return OnExit(gOnExitFailed, OnExitAuthFaild, res);
+ }
+
+ // Lock EFI boot variables
+ EfiExec(NULL, L"EFI\\VeraCrypt\\DcsBml.dcs");
+
+ // Install decrypt
+ res = EfiLibInstallDriverBindingComponentName2(
+ ImageHandle,
+ SystemTable,
+ &g_DcsIntDriverBinding,
+ ImageHandle,
+ &gDcsIntComponentName,
+ &gDcsIntComponentName2);
+
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Bind %r\n", res);
+ return OnExit(gOnExitFailed, OnExitAuthFaild, res);
+ }
+
+ res = gBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ VirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mVirtualAddrChangeEvent
+ );
+
+ return OnExit(gOnExitSuccess, OnExitSuccess, res);
+}
diff --git a/DcsInt/DcsInt.h b/DcsInt/DcsInt.h
new file mode 100644
index 0000000..ad0e40c
--- /dev/null
+++ b/DcsInt/DcsInt.h
@@ -0,0 +1,235 @@
+/** @file
+Block R/W interceptor
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#ifndef __DCSINT_H__
+#define __DCSINT_H__
+
+#include <Uefi.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/DriverBinding.h>
+
+#define DCSINT_DRIVER_VERSION 1
+#define DCS_SIGNATURE_16(A, B) ((A) | (B << 8))
+#define DCS_SIGNATURE_32(A, B, C, D) (DCS_SIGNATURE_16 (A, B) | (DCS_SIGNATURE_16 (C, D) << 16))
+
+#define DCSINT_BLOCK_IO_SIGN DCS_SIGNATURE_32('D','C','S', 'I')
+
+extern EFI_COMPONENT_NAME_PROTOCOL gDcsIntComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gDcsIntComponentName2;
+
+typedef struct _DCSINT_BLOCK_IO DCSINT_BLOCK_IO, *PDCSINT_BLOCK_IO;
+typedef struct CRYPTO_INFO_t CRYPTO_INFO, *PCRYPTO_INFO;
+
+typedef struct _DCSINT_BLOCK_IO {
+ UINT32 Sign;
+ EFI_HANDLE Controller;
+
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_BLOCK_READ LowRead;
+ EFI_BLOCK_WRITE LowWrite;
+ UINT32 IsReinstalled;
+ PCRYPTO_INFO CryptInfo;
+ DCSINT_BLOCK_IO* Next;
+} DCSINT_BLOCK_IO, *PDCSINT_BLOCK_IO;
+
+//
+// Functions for Driver Binding Protocol
+//
+
+/**
+ Check whether the controller is a supported.
+
+ @param This The driver binding protocol.
+ @param Controller The controller handle to check.
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS The driver supports this controller.
+ @retval other This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts the BlockIo device with this driver.
+
+ @param This The driver binding protocol.
+ @param Controller The Block MMIO device to start on
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS This driver supports this device.
+ @retval EFI_UNSUPPORTED This driver does not support this device.
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ALREADY_STARTED This driver has been started.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop controlling the device.
+
+ @param This The driver binding
+ @param Controller The device controller controlled by the driver.
+ @param NumberOfChildren The number of children of this device
+ @param ChildHandleBuffer The buffer of children handle.
+
+ @retval EFI_SUCCESS The driver stopped from controlling the device.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+ @retval EFI_UNSUPPORTED Block I/O Protocol is not installed on Controller.
+ @retval Others Failed to stop the driver
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Functions for Block I/O Protocol
+//
+
+//
+// EFI Component Name Functions
+//
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+ @param DriverName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+ @param ChildHandle The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+ @param Language A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+ @param ControllerName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+#endif \ No newline at end of file
diff --git a/DcsInt/DcsInt.inf b/DcsInt/DcsInt.inf
new file mode 100644
index 0000000..e79dcc6
--- /dev/null
+++ b/DcsInt/DcsInt.inf
@@ -0,0 +1,93 @@
+# Block R/W interceptor
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DcsInt
+ FILE_GUID = 26BC5841-0606-450F-A39B-F2DB0D7E002E
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DcsInt.c
+ DcsInt.h
+ DcsIntName.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiLib
+ BaseLib
+ MemoryAllocationLib
+ GraphLib
+ CommonLib
+ PasswordLib
+ DcsCfgLib
+ VeraCryptLib
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiLoadedImageProtocolGuid
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiDcsVariableGuid
+ gEfiFileInfoGuid
+ gEfiPartTypeUnusedGuid
+ gEfiPartTypeSystemPartGuid
+ gEfiEventVirtualAddressChangeGuid
+
+[BuildOptions.IA32]
+
+RELEASE_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+DEBUG_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+NOOPT_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+
+RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+
+[BuildOptions.X64]
+RELEASE_VS2010x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2010x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2010x86_X64_CC_FLAGS = /D_UEFI
+
+RELEASE_VS2015x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2015x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2015x86_X64_CC_FLAGS = /D_UEFI
+
+DEBUG_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+DEBUG_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+
+[FeaturePcd]
+
+[Pcd]
+
diff --git a/DcsInt/DcsIntName.c b/DcsInt/DcsIntName.c
new file mode 100644
index 0000000..ccf8698
--- /dev/null
+++ b/DcsInt/DcsIntName.c
@@ -0,0 +1,173 @@
+/** @file
+Block R/W interceptor
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include "DcsInt.h"
+#include <Protocol/ComponentName.h>
+#include <Protocol/ComponentName2.h>
+#include <Library/UefiLib.h>
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gDcsIntComponentName = {
+ DcsIntComponentNameGetDriverName,
+ DcsIntComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gDcsIntComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) DcsIntComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) DcsIntComponentNameGetControllerName,
+ "en"
+};
+
+//
+// Driver name table for module.
+// It is shared by the implementation of ComponentName & ComponentName2 Protocol.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDcsIntComponentNameDriverNameTable[] = {
+ {
+ "eng;en",
+ (CHAR16 *)L"DCSINT Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+ @param DriverName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mDcsIntComponentNameDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gDcsIntComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+ @param ChildHandle The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+ @param Language A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+ @param ControllerName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsIntComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+} \ No newline at end of file
diff --git a/DcsPkg.dec b/DcsPkg.dec
new file mode 100644
index 0000000..539fda8
--- /dev/null
+++ b/DcsPkg.dec
@@ -0,0 +1,29 @@
+## @file DcsPkg.dec
+# This Package provides all definitions, library classes and libraries instances.
+#
+##
+
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = DcsPkg
+ PACKAGE_UNI_FILE = DcsPkg.uni
+ PACKAGE_GUID = 9974377F-5593-492A-A54E-7B23126DE450
+ PACKAGE_VERSION = 1.0
+
+
+[Includes]
+ Include
+ Library/VeraCryptLib
+ Library/VeraCryptLib/crypto
+
+[LibraryClasses]
+ CommonLib|Include/Library/CommonLib.h
+ GraphLib|Include/Library/GraphLib.h
+ PasswordLib|Include/Library/PasswordLib.h
+ DcsCfgLib|Include/Library/DcsCfgLib.h
+
+[Guids]
+ # Include/CommonLib.h
+ # {101F8560-D73A-4FF7-89F6-8170F6615587}
+ gEfiDcsVariableGuid = { 0x101f8560, 0xd73a, 0x4ff7, { 0x89, 0xf6, 0x81, 0x70, 0xf6, 0x61, 0x55, 0x87 } }
diff --git a/DcsPkg.dsc b/DcsPkg.dsc
new file mode 100644
index 0000000..e3e4963
--- /dev/null
+++ b/DcsPkg.dsc
@@ -0,0 +1,96 @@
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = DcsPkg
+ PLATFORM_GUID = 5a9e7754-d81b-49ea-85ad-69eaa7b1539b
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/DcsPkg
+ SUPPORTED_ARCHITECTURES = X64 | IA32
+ BUILD_TARGETS = DEBUG|RELEASE
+
+[BuildOptions]
+ GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
+ GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+ INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+ MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+ GCC:*_*_*_CC_FLAGS = -mno-mmx -mno-sse
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+
+ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+ Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+ Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
+ TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+ CommonLib|DcsPkg/Library/CommonLib/CommonLib.inf
+ GraphLib|DcsPkg/Library/GraphLib/GraphLib.inf
+ PasswordLib|DcsPkg/Library/PasswordLib/PasswordLib.inf
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+ DcsCfgLib|DcsPkg/Library/DcsCfgLib/DcsCfgLib.inf
+ VeraCryptLib|DcsPkg/Library/VeraCryptLib/VeraCryptLib.inf
+
+ [LibraryClasses.common.UEFI_APPLICATION]
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+ [LibraryClasses.common.UEFI_DRIVER]
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+ DcsPkg/DcsInt/DcsInt.inf
+ DcsPkg/DcsCfg/DcsCfg.inf
+ DcsPkg/DcsBoot/DcsBoot.inf
+ DcsPkg/DcsRe/DcsRe.inf
+ DcsPkg/DcsBml/DcsBml.inf
+ DcsPkg/LegacySpeaker/LegacySpeaker.inf
diff --git a/DcsPkg.uni b/DcsPkg.uni
new file mode 100644
index 0000000..61700c9
--- /dev/null
+++ b/DcsPkg.uni
@@ -0,0 +1,6 @@
+// /** @file
+// This Package provides all definitions, library classes and libraries instances.
+//
+// **/
+
+#string STR_PACKAGE_ABSTRACT #language en-US "This Package provides all definitions, library classes and libraries instances." \ No newline at end of file
diff --git a/DcsRe/DcsRe.c b/DcsRe/DcsRe.c
new file mode 100644
index 0000000..9c59dfc
--- /dev/null
+++ b/DcsRe/DcsRe.c
@@ -0,0 +1,330 @@
+/** @file
+ This is DCS recovery loader application
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/GlobalVariable.h>
+#include "common/Tcdefs.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Menu
+//////////////////////////////////////////////////////////////////////////
+typedef EFI_STATUS(*MENU_ACTION)();
+
+typedef struct _MENU_ITEM MENU_ITEM;
+typedef struct _MENU_ITEM {
+ CHAR16 Text[128];
+ CHAR16 Select;
+ MENU_ACTION Action;
+ MENU_ITEM *Next;
+} MENU_ITEM, *PMENU_ITEM;
+
+BOOLEAN gContiniue = TRUE;
+PMENU_ITEM gMenu = NULL;
+
+PMENU_ITEM
+AppendMenu(
+ IN PMENU_ITEM menu,
+ IN CHAR16 *text,
+ IN CHAR16 select,
+ IN MENU_ACTION action
+ ) {
+ PMENU_ITEM item;
+ item = (PMENU_ITEM)MEM_ALLOC(sizeof(MENU_ITEM));
+ if (item == NULL) return item;
+ item->Action = action;
+ StrCat(item->Text, text);
+ item->Select = select;
+ if (menu != NULL) {
+ menu->Next = item;
+ }
+ return item;
+}
+
+VOID
+PrintMenu(
+ PMENU_ITEM head) {
+ PMENU_ITEM menu;
+ UINTN i = 0;
+ menu = head;
+ while (menu != NULL) {
+ OUT_PRINT(L"%H%c%N) %s\n", menu->Select, &menu->Text);
+ i++;
+ if (i == 22) {
+ ConsoleShowTip(L"Pause 60s", 60000000);
+ i = 0;
+ }
+ menu = menu->Next;
+ }
+ OUT_PRINT(L"[");
+ menu = head;
+ while (menu != NULL) {
+ OUT_PRINT(L"%H%c%N", menu->Select);
+ menu = menu->Next;
+ }
+ OUT_PRINT(L"]:");
+}
+//////////////////////////////////////////////////////////////////////////
+// EFI volume
+//////////////////////////////////////////////////////////////////////////
+UINTN EfiBootVolumeIndex = 0;
+EFI_FILE *EfiBootVolume = NULL;
+VOID
+SelectEfiVolume()
+{
+ UINTN i;
+ EFI_STATUS res;
+ EFI_FILE *file;
+ EFI_FILE **efiVolumes;
+ UINTN efiVolumesCount = 0;
+ EFI_HANDLE startHandle;
+ if (EfiBootVolume != NULL) return;
+ res = EfiGetStartDevice(&startHandle);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"GetStartDevice %r", res);
+ return;
+ }
+ efiVolumes = MEM_ALLOC(sizeof(EFI_FILE*) * gFSCount);
+ for (i = 0; i < gFSCount; ++i) {
+ res = FileOpenRoot(gFSHandles[i], &file);
+ if(EFI_ERROR(res)) continue;
+ if (!EFI_ERROR(FileExist(file, L"EFI\\Boot\\bootx64.efi"))) {
+ efiVolumesCount++;
+ efiVolumes[i] = file;
+ if (gFSHandles[i] != startHandle) {
+ EfiBootVolumeIndex = i;
+ EfiBootVolume = file;
+ }
+ } else {
+ FileClose(file);
+ }
+ }
+
+ for (i = 0; i < gFSCount; ++i) {
+ OUT_PRINT(L"%H%d)%N ", i);
+ if (efiVolumes[i] != NULL) {
+ if (gFSHandles[i] == startHandle) {
+ OUT_PRINT(L"%V [Boot Rescue] %N");
+ }
+ else {
+ OUT_PRINT(L"%V [Boot] %N");
+ }
+ EfiPrintDevicePath(gFSHandles[i]);
+ }
+ OUT_PRINT(L"\n");
+ }
+
+ do {
+ EfiBootVolumeIndex = AskUINTN("Select EFI boot volume:", EfiBootVolumeIndex);
+ if (EfiBootVolumeIndex >= gFSCount) continue;
+ EfiBootVolume = efiVolumes[EfiBootVolumeIndex];
+ } while (EfiBootVolume == NULL);
+ MEM_FREE(efiVolumes);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Actions
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+ActionBootWinPE() {
+ return EfiExec(NULL, L"EFI\\Boot\\WinPE_bootx64.efi");
+}
+
+EFI_STATUS
+ActionShell() {
+ return EfiExec(NULL, L"EFI\\Shell\\Shell.efi");
+}
+
+EFI_STATUS
+ActionDcsBoot() {
+ return EfiExec(NULL, L"EFI\\VeraCrypt\\DcsBoot.efi");
+}
+
+CHAR16* DcsBootBins[] = {
+ L"EFI\\VeraCrypt\\DcsBoot.efi",
+ L"EFI\\VeraCrypt\\DcsInt.dcs",
+ L"EFI\\VeraCrypt\\DcsBml.dcs",
+ L"EFI\\VeraCrypt\\DcsCfg.dcs",
+ L"EFI\\VeraCrypt\\LegacySpeaker.dcs"
+};
+
+/**
+Copy DCS binaries from rescue disk to EFI boot volume
+*/
+EFI_STATUS
+ActionRestoreDcsLoader() {
+ EFI_STATUS res = EFI_NOT_READY;
+ UINTN i;
+ SelectEfiVolume();
+ if (EfiBootVolume == NULL) return EFI_NOT_READY;
+ for (i = 0; i < sizeof(DcsBootBins) / sizeof(CHAR16*); ++i) {
+ res = FileCopy(NULL, DcsBootBins[i], EfiBootVolume, DcsBootBins[i], 1024 * 1024);
+ if (EFI_ERROR(res)) return res;
+ }
+ return res;
+}
+
+CHAR16* sDcsBootEfi = L"EFI\\VeraCrypt\\DcsBoot.efi";
+CHAR16* sDcsBootEfiDesc = L"VeraCrypt(DCS) loader";
+/**
+Update boot menu
+*/
+EFI_STATUS
+ActionRestoreDcsBootMenu()
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ SelectEfiVolume();
+ if (EfiBootVolume == NULL) return EFI_NOT_READY;
+ // Prepare BootDC5B
+ res = BootMenuItemCreate(L"BootDC5B", sDcsBootEfiDesc, gFSHandles[EfiBootVolumeIndex], sDcsBootEfi, TRUE);
+ if (EFI_ERROR(res)) return res;
+ res = BootOrderInsert(L"BootOrder", 0, 0x0DC5B);
+ return res;
+}
+
+EFI_STATUS
+ActionRemoveDcsBootMenu()
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ BootMenuItemRemove(L"BootDC5B");
+ res = BootOrderRemove(L"BootOrder", 0x0DC5B);
+ return res;
+}
+
+/**
+Copy DcsProp from rescue disk to EFI boot volume
+*/
+EFI_STATUS
+ActionRestoreDcsProp() {
+ SelectEfiVolume();
+ if (EfiBootVolume == NULL) return EFI_NOT_READY;
+ return FileCopy(NULL, L"EFI\\VeraCrypt\\DcsProp", EfiBootVolume, L"EFI\\VeraCrypt\\DcsProp", 1024*1024);
+}
+
+#define OPT_OS_DECRYPT L"-osdecrypt"
+#define OPT_OS_RESTORE_KEY L"-osrestorekey"
+
+CHAR16* sOSDecrypt = OPT_OS_DECRYPT;
+CHAR16* sOSRestoreKey = OPT_OS_RESTORE_KEY;
+CHAR16* sDcsCfg = L"EFI\\VeraCrypt\\DcsCfg.dcs";
+
+EFI_STATUS
+ActionRestoreHeader() {
+ EFI_STATUS res = EFI_NOT_READY;
+ res = EfiSetVar(L"dcscfgcmd", NULL, sOSRestoreKey, StrSize(sOSRestoreKey), EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ return EfiExec(NULL, sDcsCfg);
+}
+
+EFI_STATUS
+ActionDecryptOS() {
+ EFI_STATUS res = EFI_NOT_READY;
+ res = EfiSetVar(L"dcscfgcmd", NULL, sOSDecrypt, StrSize(sOSDecrypt), EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ return EfiExec(NULL, sDcsCfg);
+}
+
+EFI_STATUS
+ActionExit() {
+ gContiniue = FALSE;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ActionHelp() {
+OUT_PRINT(L"\
+%HRescue disk for VeraCrypt OS encryption%N\n\r\
+Help message to be defined\n\r\
+");
+ return EFI_SUCCESS;
+}
+
+/**
+The actual entry point for the application.
+
+@param[in] ImageHandle The firmware allocated handle for the EFI image.
+@param[in] SystemTable A pointer to the EFI System Table.
+
+@retval EFI_SUCCESS The entry point executed successfully.
+@retval other Some error occur when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+DcsReMain(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS res;
+ EFI_INPUT_KEY key;
+ PMENU_ITEM item = gMenu;
+ InitBio();
+ res = InitFS();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"InitFS %r\n", res);
+ return res;
+ }
+
+ item = AppendMenu(NULL, L"Decrypt OS", 'd', ActionDecryptOS);
+ gMenu = item;
+ item = AppendMenu(item, L"Restore VeraCrypt loader to boot menu", 'm', ActionRestoreDcsBootMenu);
+ item = AppendMenu(item, L"Remove VeraCrypt loader from boot menu", 'z' , ActionRemoveDcsBootMenu);
+
+ if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\DcsProp"))) {
+ item = AppendMenu(item, L"Restore VeraCrypt loader configuration to system disk", 'c', ActionRestoreDcsProp);
+ }
+
+ if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\svh_bak"))) {
+ item = AppendMenu(item, L"Restore OS header keys", 'k', ActionRestoreHeader);
+ }
+
+ if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\DcsBoot.efi"))) {
+ item = AppendMenu(item, L"Restore VeraCrypt loader binaries to system disk", 'r', ActionRestoreDcsLoader);
+ item = AppendMenu(item, L"Boot VeraCrypt loader from rescue disk", 'v', ActionDcsBoot);
+ }
+
+ if (!EFI_ERROR(FileExist(NULL, L"EFI\\Boot\\WinPE_bootx64.efi"))) {
+ item = AppendMenu(item, L"Boot Windows PE from rescue disk", 'w', ActionBootWinPE);
+ }
+
+ if (!EFI_ERROR(FileExist(NULL, L"EFI\\Shell\\Shell.efi"))) {
+ item = AppendMenu(item, L"Boot Shell.efi from rescue disk", 's', ActionShell);
+ }
+
+ item = AppendMenu(item, L"Help", 'h', ActionHelp);
+ item = AppendMenu(item, L"Exit", 'e', ActionExit);
+ OUT_PRINT(L"%V%a rescue disk %a%N\n", TC_APP_NAME, VERSION_STRING);
+ gBS->SetWatchdogTimer(0, 0, 0, NULL);
+ do {
+ PrintMenu(gMenu);
+ item = NULL;
+ key.UnicodeChar = 0;
+ while (item == NULL) {
+ item = gMenu;
+ key = GetKey();
+ while (item != NULL) {
+ if (item->Select == key.UnicodeChar) break;
+ item = item->Next;
+ }
+ }
+ OUT_PRINT(L"%c\n",key.UnicodeChar);
+ res = item->Action();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ }
+ } while (gContiniue);
+ return EFI_INVALID_PARAMETER;
+}
diff --git a/DcsRe/DcsRe.inf b/DcsRe/DcsRe.inf
new file mode 100644
index 0000000..e103865
--- /dev/null
+++ b/DcsRe/DcsRe.inf
@@ -0,0 +1,74 @@
+## @file
+# This is DCS boot loader application
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsRe
+ FILE_GUID = 31D0F9D8-ABA6-4D43-96BB-C602BAFF26AF
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DcsReMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DcsRe.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ BaseLib
+ MemoryAllocationLib
+ CommonLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiDcsVariableGuid
+ gEfiFileInfoGuid
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+
+[BuildOptions.IA32]
+RELEASE_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+DEBUG_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+NOOPT_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI
+
+RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI
+
+[BuildOptions.X64]
+RELEASE_VS2010x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2010x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2010x86_X64_CC_FLAGS = /D_UEFI
+
+RELEASE_VS2015x86_X64_CC_FLAGS = /D_UEFI
+DEBUG_VS2015x86_X64_CC_FLAGS = /D_UEFI
+NOOPT_VS2015x86_X64_CC_FLAGS = /D_UEFI
+
+[FeaturePcd]
+
+[Pcd]
+
diff --git a/Dcs_bld.bat b/Dcs_bld.bat
new file mode 100644
index 0000000..ff55c73
--- /dev/null
+++ b/Dcs_bld.bat
@@ -0,0 +1,39 @@
+pushd "%~dp0"
+
+set dcsarch=X64
+set dcstype=DEBUG
+set dcsbldtoolset=VS2010x86
+set dcspkgpath="%~dp0DcsPkg.dsc"
+
+if /I NOT ["%1"]==["X64Rel"] goto :IA32
+set dcsarch=X64
+set dcstype=RELEASE
+goto :bld
+
+:IA32
+if /I NOT ["%1"]==["IA32"] goto :IA32Rel
+set dcsarch=IA32
+set dcstype=DEBUG
+goto :bld
+
+:IA32Rel
+if /I NOT ["%1"]==["IA32rel"] goto :bld
+set dcsarch=IA32
+set dcstype=RELEASE
+
+:bld
+if /I ["%2"]==["VS2015"] set dcsbldtoolset=VS2015x86
+call bld.bat -t %dcsbldtoolset% -DSECURE_BOOT_ENABLE=1 -p %dcspkgpath% -b %dcstype% -a %dcsarch%
+
+if ERRORLEVEL 1 goto :exit
+if not exist SecureBoot\keys\DCS_sign.pfx goto :exit
+
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\DcsBml.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\DcsBoot.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\DcsCfg.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\DcsInt.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\DcsRe.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+call SecureBoot\efi_sign.bat ..\Build\DcsPkg\%dcstype%_%dcsbldtoolset%\%dcsarch%\LegacySpeaker.efi SecureBoot\keys\DCS_sign.pfx SecureBoot\certs\DCS_sign.crt
+
+:exit
+popd
diff --git a/Include/Library/CommonLib.h b/Include/Library/CommonLib.h
new file mode 100644
index 0000000..395d4c4
--- /dev/null
+++ b/Include/Library/CommonLib.h
@@ -0,0 +1,540 @@
+/** @file
+EFI common library (helpers)
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#ifndef __COMMONLIB_H__
+#define __COMMONLIB_H__
+
+#include <Uefi.h>
+#include <Protocol/BlockIo.h>
+#include <Library/UefiLib.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/AbsolutePointer.h>
+#include <Guid/FileInfo.h>
+
+#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+#define FIELD_OFFSET(t, f) ((UINTN)(&((t*)0)->f))
+
+//////////////////////////////////////////////////////////////////////////
+// Memory procedures wrappers
+//////////////////////////////////////////////////////////////////////////
+
+#define MEM_ALLOC MemAlloc
+#define MEM_FREE MemFree
+#define MEM_REALLOC MemRealloc
+
+VOID*
+MemAlloc(
+ IN UINTN size
+ );
+
+VOID
+MemFree(
+ IN VOID* ptr
+ );
+
+VOID*
+MemRealloc(
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ );
+
+EFI_STATUS
+PrepareMemory(
+ IN UINTN address,
+ IN UINTN len,
+ OUT VOID** mem
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// handles
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiGetHandles(
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol, OPTIONAL
+ IN VOID *SearchKey, OPTIONAL
+ OUT EFI_HANDLE **Buffer,
+ OUT UINTN *Count
+ );
+
+EFI_STATUS
+EfiGetStartDevice(
+ OUT EFI_HANDLE* handle
+ );
+//////////////////////////////////////////////////////////////////////////
+// Print handle info
+//////////////////////////////////////////////////////////////////////////
+
+VOID EfiPrintDevicePath(
+ IN EFI_HANDLE handle
+ );
+
+VOID
+EfiPrintProtocols(
+ IN EFI_HANDLE handle
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Block I/O
+//////////////////////////////////////////////////////////////////////////
+
+EFI_BLOCK_IO_PROTOCOL*
+EfiGetBlockIO(
+ IN EFI_HANDLE handle
+ );
+
+extern EFI_HANDLE* gBIOHandles;
+extern UINTN gBIOCount;
+
+EFI_STATUS
+InitBio();
+
+BOOLEAN
+EfiIsPartition(
+ IN EFI_HANDLE h
+ );
+
+EFI_STATUS
+EfiGetPartDetails(
+ IN EFI_HANDLE h,
+ OUT HARDDRIVE_DEVICE_PATH* dpVolme,
+ OUT EFI_HANDLE* hDisk
+ );
+
+EFI_STATUS
+EfiGetPartGUID(
+ IN EFI_HANDLE h,
+ OUT EFI_GUID* guid
+ );
+
+EFI_STATUS
+EfiFindPartByGUID(
+ IN EFI_GUID* guid,
+ OUT EFI_HANDLE* h
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// USB
+//////////////////////////////////////////////////////////////////////////
+extern EFI_HANDLE* gUSBHandles;
+extern UINTN gUSBCount;
+
+EFI_STATUS
+InitUsb();
+
+EFI_STATUS
+UsbGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo
+ );
+
+EFI_STATUS
+UsbGetIOwithDescriptor(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo,
+ OUT EFI_USB_DEVICE_DESCRIPTOR* UsbDescriptor
+ );
+
+EFI_STATUS
+UsbGetId(
+ IN EFI_HANDLE Handle,
+ OUT CHAR8** id
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Touch
+//////////////////////////////////////////////////////////////////////////
+
+extern EFI_HANDLE* gTouchHandles;
+extern UINTN gTouchCount;
+extern int gTouchSimulate;
+extern EFI_ABSOLUTE_POINTER_PROTOCOL* gTouchPointer;
+extern UINT32 gTouchSimulateStep;
+
+EFI_STATUS
+InitTouch();
+
+EFI_STATUS
+TouchGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_ABSOLUTE_POINTER_PROTOCOL** io
+ );
+
+
+//////////////////////////////////////////////////////////////////////////
+// Console I/O
+//////////////////////////////////////////////////////////////////////////
+
+#define OUT_PRINT(format, ...) AttrPrintEx(-1,-1, format, ##__VA_ARGS__)
+#define ERR_PRINT(format, ...) AttrPrintEx(-1,-1, L"%E" format L"%N" , ##__VA_ARGS__)
+
+EFI_STATUS
+ConsoleGetOutput(
+ IN EFI_HANDLE handle,
+ OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL** io
+ );
+
+VOID
+FlushInput();
+
+VOID
+FlushInputDelay(
+ IN UINTN delay
+ );
+
+EFI_INPUT_KEY
+KeyWait(
+ CHAR16* Prompt,
+ UINTN mDelay,
+ UINT16 scanCode,
+ UINT16 unicodeChar);
+
+EFI_INPUT_KEY
+GetKey(void);
+
+VOID
+ConsoleShowTip(
+ IN CHAR16* tip,
+ IN UINTN delay);
+
+VOID
+GetLine(
+ UINTN *length,
+ CHAR16 *line,
+ CHAR8 *asciiLine,
+ UINTN line_max,
+ UINT8 show);
+
+int
+AskAsciiString(
+ CHAR8* prompt,
+ CHAR8* str,
+ UINTN max_len,
+ UINT8 visible);
+
+int
+AskInt(
+ CHAR8* prompt,
+ UINT8 visible);
+
+
+UINT8
+AskConfirm(
+ CHAR8* prompt,
+ UINT8 visible);
+
+UINT64
+AskUINT64(
+ IN char* prompt,
+ IN UINT64 def);
+
+UINT64
+AskHexUINT64(
+ IN char* prompt,
+ IN UINT64 def);
+
+UINTN
+AskUINTN(
+ IN char* prompt,
+ IN UINTN def);
+
+BOOLEAN
+AsciiHexToDigit(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ );
+
+BOOLEAN
+AsciiHexToByte(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ );
+
+BOOLEAN
+AsciiStrToGuid(
+ OUT EFI_GUID *guid,
+ IN CHAR8 *str
+ );
+
+
+//////////////////////////////////////////////////////////////////////////
+// Attribute print
+//////////////////////////////////////////////////////////////////////////
+
+extern BOOLEAN gShellReady;
+
+VOID
+SetShellAPI(
+ IN VOID* shellProtocol,
+ IN VOID* shellParametersProtocol
+ );
+
+/**
+Print at a specific location on the screen.
+
+This function will move the cursor to a given screen location and print the specified string.
+
+If -1 is specified for either the Row or Col the current screen location for BOTH
+will be used.
+
+If either Row or Col is out of range for the current console, then ASSERT.
+If Format is NULL, then ASSERT.
+
+In addition to the standard %-based flags as supported by UefiLib Print() this supports
+the following additional flags:
+%N - Set output attribute to normal
+%H - Set output attribute to highlight
+%E - Set output attribute to error
+%B - Set output attribute to blue color
+%V - Set output attribute to green color
+
+Note: The background color is controlled by the shell command cls.
+
+@param[in] Col the column to print at
+@param[in] Row the row to print at
+@param[in] Format the format string
+@param[in] ... The variable argument list.
+
+@return EFI_SUCCESS The printing was successful.
+@return EFI_DEVICE_ERROR The console device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+AttrPrintEx(
+ IN INT32 Col OPTIONAL,
+ IN INT32 Row OPTIONAL,
+ IN CONST CHAR16 *Format,
+ ...
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Console control
+//////////////////////////////////////////////////////////////////////////
+
+extern EFI_HANDLE* gConsoleControlHandles;
+extern UINTN gConsoleControlCount;
+
+EFI_STATUS
+InitConsoleControl();
+
+//////////////////////////////////////////////////////////////////////////
+// Beep
+//////////////////////////////////////////////////////////////////////////
+extern EFI_HANDLE* gSpeakerHandles;
+extern UINTN gSpeakerCount;
+extern EFI_GUID gSpeakerGuid;
+
+extern int gBeepEnabled;
+extern BOOLEAN gBeepControlEnabled;
+extern int gBeepDevice;
+extern int gBeepNumberDefault;
+extern int gBeepDurationDefault;
+extern int gBeepIntervalDefault;
+extern int gBeepToneDefault;
+
+
+EFI_STATUS
+InitSpeaker();
+
+EFI_STATUS
+SpeakerBeep(
+ IN UINT16 Tone,
+ IN UINTN NumberOfBeeps,
+ IN UINTN Duration,
+ IN UINTN Interval
+ );
+
+EFI_STATUS
+SpeakerSelect(
+ IN UINTN index
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Efi variables
+//////////////////////////////////////////////////////////////////////////
+
+#define DCS_BOOT_STR L"DcsBoot"
+
+extern EFI_GUID gEfiDcsVariableGuid;
+
+EFI_STATUS
+EfiGetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ OUT VOID** varValue,
+ OUT UINTN* varSize,
+ OUT UINT32* varAttr
+ );
+
+EFI_STATUS
+EfiSetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ IN VOID* varValue,
+ IN UINTN varSize,
+ IN UINT32 varAttr
+ );
+
+EFI_STATUS
+BootOrderInsert(
+ IN CHAR16 *OrderVarName,
+ IN UINTN index,
+ UINT16 value);
+
+EFI_STATUS
+BootOrderRemove(
+ IN CHAR16 *OrderVarName,
+ UINT16 value
+ );
+
+EFI_STATUS
+BootMenuItemCreate(
+ IN CHAR16 *VarName,
+ IN CHAR16 *Desc,
+ IN EFI_HANDLE volumeHandle,
+ IN CHAR16 *Path,
+ IN BOOLEAN Reduced
+ );
+
+EFI_STATUS
+BootMenuItemRemove(
+ IN CHAR16 *VarName
+ );
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// File
+//////////////////////////////////////////////////////////////////////////
+
+
+extern EFI_FILE* gFileRoot;
+extern EFI_HANDLE gFileRootHandle;
+
+extern EFI_HANDLE* gFSHandles;
+extern UINTN gFSCount;
+
+EFI_STATUS
+InitFS();
+
+EFI_STATUS
+FileOpenRoot(
+ IN EFI_HANDLE rootHandle,
+ OUT EFI_FILE** rootFile);
+
+EFI_STATUS
+FileOpen(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT EFI_FILE** file,
+ IN UINT64 mode,
+ IN UINT64 attributes
+ );
+
+EFI_STATUS
+FileClose(
+ IN EFI_FILE* f);
+
+EFI_STATUS
+FileDelete(
+ IN EFI_FILE* root,
+ IN CHAR16* name
+ );
+
+EFI_STATUS
+FileRead(
+ IN EFI_FILE* f,
+ OUT VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position);
+
+EFI_STATUS
+FileWrite(
+ IN EFI_FILE* f,
+ IN VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position);
+
+EFI_STATUS
+FileGetInfo(
+ IN EFI_FILE* f,
+ OUT EFI_FILE_INFO** info,
+ OUT UINTN* size
+ );
+
+EFI_STATUS
+FileGetSize(
+ IN EFI_FILE* f,
+ OUT UINTN* size
+ );
+
+EFI_STATUS
+FileLoad(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT VOID** data,
+ OUT UINTN* size
+ );
+
+EFI_STATUS
+FileSave(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ IN VOID* data,
+ IN UINTN size
+ );
+
+EFI_STATUS
+FileExist(
+ IN EFI_FILE* root,
+ IN CHAR16* name
+ );
+
+EFI_STATUS
+FileRename(
+ IN EFI_FILE* root,
+ IN CHAR16* src,
+ IN CHAR16* dst
+ );
+
+EFI_STATUS
+FileCopy(
+ IN EFI_FILE* srcroot,
+ IN CHAR16* src,
+ IN EFI_FILE* dstroot,
+ IN CHAR16* dst,
+ IN UINTN bufSz
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// Exec
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiExec(
+ IN EFI_HANDLE deviceHandle,
+ IN CHAR16* path
+ );
+
+EFI_STATUS
+ConnectAllEfi(
+ VOID
+ );
+
+VOID
+EfiCpuHalt();
+
+#endif \ No newline at end of file
diff --git a/Include/Library/DcsCfgLib.h b/Include/Library/DcsCfgLib.h
new file mode 100644
index 0000000..6d74729
--- /dev/null
+++ b/Include/Library/DcsCfgLib.h
@@ -0,0 +1,213 @@
+/** @file
+DCS configuration
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the [to be defined License, Version]. The full text of the license may be found at
+[opensource license to be defined]
+**/
+
+#ifndef __DCSCFGLIB_H__
+#define __DCSCFGLIB_H__
+
+#include <Uefi.h>
+
+//////////////////////////////////////////////////////////////////////////
+// DeList and GPT
+//////////////////////////////////////////////////////////////////////////
+#define EFI_PART_TYPE_BASIC_DATA_PART_GUID \
+ { \
+ 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 } \
+ }
+
+#define EFI_PART_TYPE_MS_RESERVED_PART_GUID \
+ { \
+ 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE } \
+ }
+
+#define EFI_PART_TYPE_MS_RECOVERY_PART_GUID \
+ { \
+ 0xDE94BBA4, 0x06D1, 0x06D1, { 0xA1, 0x6A, 0xBF, 0xD5, 0x01, 0x79, 0xD6, 0xAC } \
+ }
+
+typedef struct _DCS_DISK_ENTRY_LIST DCS_DISK_ENTRY_LIST;
+typedef struct _DCS_DEP_EXEC DCS_DEP_EXEC;
+
+extern EFI_GUID gEfiPartTypeBasicDataPartGuid;
+extern EFI_GUID gEfiPartTypeMsReservedPartGuid;
+extern EFI_GUID gEfiPartTypeMsRecoveryPartGuid;
+
+extern UINT64 gDcsDiskEntryListHeaderID;
+
+extern DCS_DISK_ENTRY_LIST *DeList;
+extern DCS_DEP_EXEC *DeExecParams;
+
+// DcsCfg data
+extern CONST CHAR16* DcsDiskEntrysFileName;
+extern EFI_PARTITION_ENTRY DcsHidePart;
+extern EFI_PARTITION_ENTRY *GptMainEntrys;
+extern UINTN BootPartIdx;
+extern UINTN MirrorPartIdx;
+
+EFI_STATUS
+DeListParseSaved(
+ IN UINT8 *DeBuffer
+ );
+
+EFI_STATUS
+DeListLoadFromFile();
+
+EFI_STATUS
+DeListZero();
+
+VOID
+DeListPrint();
+
+VOID
+DeListSaveToFile();
+
+EFI_STATUS
+DeListApplySectorsToDisk(
+ IN UINTN diskIdx
+ );
+
+EFI_STATUS
+DeListExecEdit();
+
+EFI_STATUS
+DeListPwdCacheEdit();
+
+EFI_STATUS
+DeListRndSave();
+
+EFI_STATUS
+DeListRndLoad();
+
+EFI_STATUS
+GptLoadFromDisk(
+ IN UINTN diskIdx
+ );
+
+VOID
+GptHideParts();
+
+VOID
+GptSort();
+
+VOID
+GptSqueze();
+
+EFI_STATUS
+GptSyncMainAlt();
+
+BOOLEAN
+GptAskGUID(
+ IN char* prompt,
+ IN OUT EFI_GUID* guid
+ );
+
+BOOLEAN
+IsRegionOverlap(UINT64 start1, UINT64 end1, UINT64 start2, UINT64 end2);
+
+//////////////////////////////////////////////////////////////////////////
+// Random
+//////////////////////////////////////////////////////////////////////////
+enum RndGeneratorTypes {
+ RndTypeNone = 0,
+ RndTypeFile,
+ RndTypeRDRand,
+ RndTypeDtrmHmacSha512
+};
+
+#define RND_HEADER_SIGN SIGNATURE_64('D','C','S','_','R','A','N','D')
+
+typedef struct _DCS_RND DCS_RND;
+
+typedef
+EFI_STATUS
+(*DCS_RND_PREPARE)(
+ IN OUT DCS_RND *Rnd
+ );
+
+typedef
+EFI_STATUS
+(*DCS_RND_GET_BYTES)(
+ IN DCS_RND *Rnd,
+ OUT UINT8 *buf,
+ IN UINTN len
+ );
+
+#pragma pack(1)
+/* state of DRBG HMAC SHA512 */
+typedef struct _RND_DTRM_HMAC_SHA512_STATE
+{
+ UINT8 V[64]; /* internal state 10.1.1.1 1a) */
+ UINT8 C[64]; /* hmac key */
+ UINT64 ReseedCtr; /* Number of RNG requests since last reseed --* 10.1.1.1 1c)*/
+} RND_DTRM_HMAC_SHA512_STATE;
+
+typedef struct _RND_FILE_STATE
+{
+ CHAR16 *FileName;
+ UINT8 *Data;
+ UINTN Size;
+ UINTN Pos;
+} RND_FILE_STATE;
+
+typedef union _DCS_RND_STATE {
+ RND_DTRM_HMAC_SHA512_STATE HMacSha512;
+ RND_FILE_STATE File;
+} DCS_RND_STATE;
+
+typedef struct _DCS_RND_SAVED {
+ UINT64 Sign;
+ UINT32 CRC;
+ UINT32 Size;
+ UINT32 Type;
+ UINT32 Pad;
+ EFI_TIME SavedAt;
+ DCS_RND_STATE State;
+ UINT8 pad[512 - 8 - 4 - 4 - 4 - 4 - sizeof(EFI_TIME) - sizeof(DCS_RND_STATE)];
+} DCS_RND_SAVED;
+#pragma pack()
+static_assert(sizeof(DCS_RND_SAVED) == 512, "Wrong size DCS_RND_SAVED");
+
+typedef struct _DCS_RND {
+ DCS_RND_PREPARE Prepare;
+ DCS_RND_GET_BYTES GetBytes;
+ UINT32 Type;
+ UINT32 Pad;
+ DCS_RND_STATE State;
+} DCS_RND;
+
+EFI_STATUS
+RndInit(
+ IN UINTN rndType,
+ IN VOID* Context,
+ OUT DCS_RND **rnd);
+
+// Serialize rnd with state to/from memory
+EFI_STATUS
+RndLoad(
+ IN DCS_RND_SAVED *rndSaved,
+ OUT DCS_RND **rndOut
+ );
+
+EFI_STATUS
+RndSave(
+ DCS_RND *rnd,
+ DCS_RND_SAVED **rndSaved);
+
+// Global RND
+extern DCS_RND* gRnd;
+
+EFI_STATUS
+RndGetBytes(UINT8 *buf, UINTN len);
+
+EFI_STATUS
+RndPreapare();
+
+#endif
+
diff --git a/Include/Library/GraphLib.h b/Include/Library/GraphLib.h
new file mode 100644
index 0000000..49cea5c
--- /dev/null
+++ b/Include/Library/GraphLib.h
@@ -0,0 +1,200 @@
+/** @file
+Graph library
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#ifndef __GRAPHLIB_H__
+#define __GRAPHLIB_H__
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Graph
+//////////////////////////////////////////////////////////////////////////
+
+extern EFI_HANDLE* gGraphHandles;
+extern UINTN gGraphCount;
+extern EFI_GRAPHICS_OUTPUT_PROTOCOL* gGraphOut;
+
+EFI_STATUS
+InitGraph();
+
+EFI_STATUS
+GraphGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_GRAPHICS_OUTPUT_PROTOCOL** io
+ );
+
+EFI_STATUS
+GraphGetModeInfo(
+ IN UINTN mode,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **info,
+ OUT UINTN* szInfo
+ );
+
+typedef struct _RECT {
+ UINT32 left;
+ UINT32 top;
+ UINT32 right;
+ UINT32 bottom;
+} RECT, *PRECT;
+
+#pragma pack(1)
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ RECT Dirty;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixels[0];
+} BLT_HEADER;
+#pragma pack()
+
+enum DRAW_OPERATION {
+ DrawOpSet = 0,
+ DrawOpOr,
+ DrawOpXor,
+ DrawOpClear,
+ DrawOpAlpha
+};
+
+typedef struct _DRAW_CONTEXT {
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
+ UINT32 Op;
+ UINT32 DashLine;
+ UINT32 Alpha; //< 0..255
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL AlphaColor;
+ INT32* Brush; // brush points(default 1)
+} DRAW_CONTEXT, *PDRAW_CONTEXT;
+
+extern DRAW_CONTEXT gDrawContext;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorBlack;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorWhite;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorBlue;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorGreen;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorRed;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorGray;
+extern INT32 gBrush3[5 * 2];
+
+EFI_STATUS
+ScreenGetSize(
+ OUT UINTN *Height,
+ OUT UINTN *Width
+ );
+
+EFI_STATUS ScreenFillRect(
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *color,
+ IN UINTN x,
+ IN UINTN y,
+ IN UINTN width,
+ IN UINTN height
+ );
+
+EFI_STATUS ScreenDrawBlt(
+ IN BLT_HEADER *blt,
+ IN UINTN x,
+ IN UINTN y
+ );
+
+EFI_STATUS
+ScreenSaveBlt(
+ OUT BLT_HEADER **bltScreen
+ );
+
+EFI_STATUS ScreenUpdateDirty(
+ IN BLT_HEADER *blt
+ );
+
+EFI_STATUS
+BltDrawBlt(
+ IN OUT BLT_HEADER* canvas,
+ IN BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y
+ );
+
+EFI_STATUS
+RectMarkDirty(
+ IN OUT PRECT rect,
+ IN UINTN x,
+ IN UINTN y
+ );
+
+EFI_STATUS
+BltPoint(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN UINTN x,
+ IN UINTN y
+ );
+
+VOID
+BltLine(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1);
+
+VOID
+BltBox(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1);
+
+VOID
+BltCircle(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 xm,
+ IN INT32 ym,
+ IN INT32 r,
+ IN BOOLEAN fill);
+
+VOID
+BltText(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x,
+ IN INT32 y,
+ IN INT32 scale, // 0..256 reduce 256... enlarge
+ IN CONST CHAR8 *text);
+
+
+EFI_STATUS
+BmpGetSize(
+ IN const unsigned char* BmpImage,
+ IN UINTN BmpImageSize,
+ OUT UINTN *Height,
+ OUT UINTN *Width
+ );
+
+EFI_STATUS
+BmpToBlt(
+ IN CONST VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ OUT BLT_HEADER **blt
+ );
+
+VOID
+BltFill(
+ IN BLT_HEADER* blt,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL fill,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1
+ );
+
+#endif \ No newline at end of file
diff --git a/Include/Library/PasswordLib.h b/Include/Library/PasswordLib.h
new file mode 100644
index 0000000..62cad21
--- /dev/null
+++ b/Include/Library/PasswordLib.h
@@ -0,0 +1,108 @@
+/** @file
+Password library
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#ifndef __PASSWORDLIB_H__
+#define __PASSWORDLIB_H__
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+
+extern CHAR16* gPasswordPictureFileName;
+
+extern CHAR8* gPasswordPictureChars;
+extern CHAR8* gPasswordPictureCharsDefault;
+extern UINTN gPasswordPictureCharsLen;
+extern UINT8 gPasswordVisible;
+extern int gPasswordShowMark;
+
+extern int gPlatformLocked;
+extern int gTPMLocked;
+extern int gSCLocked;
+
+enum AskPwdType {
+ AskPwdLogin = 1,
+ AskPwdNew,
+ AskPwdConfirm
+};
+
+enum AskPwdRetCode {
+ AskPwdRetCancel = 0,
+ AskPwdRetLogin = 1,
+ AskPwdRetChange
+};
+
+VOID
+AskPictPwdInt(
+ IN UINTN pwdType,
+ IN UINTN pwdMax,
+ OUT CHAR8* pwd,
+ OUT UINT32* pwdLen,
+ OUT INT32* retCode
+ );
+
+VOID
+AskConsolePwdInt(
+ OUT UINT32 *length,
+ OUT CHAR8 *asciiLine,
+ OUT INT32 *retCode,
+ IN UINTN line_max,
+ IN UINT8 show
+ );
+
+extern EFI_GUID* gSmbSystemUUID; // Universal unique ID
+extern CHAR8* gSmbSystemSerial; // System serial
+extern CHAR8* gSmbSystemSKU; // SKU number
+extern CHAR8* gSmbBaseBoardSerial; // Base board serial
+extern UINT64* gSmbProcessorID; // Processor ID
+
+EFI_STATUS
+SMBIOSGetSerials();
+
+EFI_STATUS
+PaltformGetIDCRC(
+ IN EFI_HANDLE handle,
+ OUT UINT32 *crc32
+ );
+
+EFI_STATUS
+PlatformGetID(
+ IN EFI_HANDLE handle,
+ OUT CHAR8 **id,
+ OUT UINTN *idLen
+ );
+
+EFI_STATUS
+PlatformGetIDCRC(
+ IN EFI_HANDLE handle,
+ OUT UINT32 *crc32
+ );
+
+extern UINTN gBioIndexAuth;
+extern BOOLEAN gBioIndexAuthOnRemovable;
+
+typedef struct _DCS_AUTH_DATA_MARK {
+ UINT32 HeaderCrc;
+ UINT32 PlatformCrc;
+ UINT32 AuthDataSize;
+ UINT32 Reserved;
+} DCS_AUTH_DATA_MARK;
+
+
+EFI_STATUS
+PlatformGetAuthData(
+ OUT UINT8 **data,
+ OUT UINTN *len,
+ OUT EFI_HANDLE *secRegionHandle
+ );
+
+#endif \ No newline at end of file
diff --git a/Include/Protocol/ConsoleControl.h b/Include/Protocol/ConsoleControl.h
new file mode 100644
index 0000000..c935970
--- /dev/null
+++ b/Include/Protocol/ConsoleControl.h
@@ -0,0 +1,123 @@
+/*++
+
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ConsoleControl.h
+
+Abstract:
+
+ Abstraction of a Text mode or GOP/UGA screen
+
+--*/
+
+#ifndef __CONSOLE_CONTROL_H__
+#define __CONSOLE_CONTROL_H__
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+ { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} }
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL;
+
+
+typedef enum {
+ EfiConsoleControlScreenText,
+ EfiConsoleControlScreenGraphics,
+ EfiConsoleControlScreenMaxValue
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+ OUT BOOLEAN *GopUgaExists, OPTIONAL
+ OUT BOOLEAN *StdInLocked OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Return the current video mode information. Also returns info about existence
+ of Graphics Output devices or UGA Draw devices in system, and if the Std In
+ device is locked. All the arguments are optional and only returned if a non
+ NULL pointer is passed in.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Are we in text of grahics mode.
+ GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device
+ StdInLocked - TRUE if StdIn device is keyboard locked
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+ )
+/*++
+
+ Routine Description:
+ Set the current mode to either text or graphics. Graphics is
+ for Quiet Boot.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Mode to set the
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN CHAR16 *Password
+ )
+/*++
+
+ Routine Description:
+ Lock Std In devices until Password is typed.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Password - Password needed to unlock screen. NULL means unlock keyboard
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_DEVICE_ERROR - Std In not locked
+
+--*/
+;
+
+
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+ EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
+};
+
+extern EFI_GUID gEfiConsoleControlProtocolGuid;
+
+#endif
diff --git a/Include/Protocol/Speaker.h b/Include/Protocol/Speaker.h
new file mode 100644
index 0000000..938f575
--- /dev/null
+++ b/Include/Protocol/Speaker.h
@@ -0,0 +1,84 @@
+/*++
+
+ Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+
+
+ This program and the accompanying materials are licensed and made available under
+
+ the terms and conditions of the BSD License that accompanies this distribution.
+
+
+The full text of the license may be found at
+
+ http://opensource.org/licenses/bsd-license.php.
+
+
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+
+
+Module Name:
+
+ Speaker.h
+
+Abstract:
+
+ EFI Speaker Interface Protocol
+
+Revision History
+
+**/
+
+#ifndef _EFI_SPEAKER_H
+#define _EFI_SPEAKER_H
+
+#include <Uefi.h>
+#include <ProcessorBind.h>
+#include <Base.h>
+
+//
+// Global Id for Speaker Interface
+//
+#define EFI_SPEAKER_INTERFACE_PROTOCOL_GUID \
+ { \
+ 0x400b4476, 0x3081, 0x11d6, 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 \
+ }
+
+typedef struct _EFI_SPEAKER_IF_PROTOCOL EFI_SPEAKER_IF_PROTOCOL;
+
+//
+// Beep Code
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GENERATE_BEEP) (
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINTN NumberOfBeep,
+ IN UINTN BeepDuration,
+ IN UINTN TimeInterval
+ );
+
+//
+// Set Frequency
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPEAKER_SET_FREQUENCY) (
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINT16 Frequency
+ );
+
+//
+// Protocol definition
+//
+struct _EFI_SPEAKER_IF_PROTOCOL {
+ EFI_SPEAKER_SET_FREQUENCY SetSpeakerToneFrequency;
+ EFI_GENERATE_BEEP GenerateBeep;
+} ;
+
+extern EFI_GUID gEfiSpeakerInterfaceProtocolGuid;
+#endif
diff --git a/LegacySpeaker/ComponentName.c b/LegacySpeaker/ComponentName.c
new file mode 100644
index 0000000..0b21270
--- /dev/null
+++ b/LegacySpeaker/ComponentName.c
@@ -0,0 +1,134 @@
+/** @file
+ TODO: Brief Description of UEFI Driver LegacySpeaker
+
+ TODO: Detailed Description of UEFI Driver LegacySpeaker
+
+ TODO: Copyright for UEFI Driver LegacySpeaker
+
+ TODO: License for UEFI Driver LegacySpeaker
+
+**/
+
+#include "LegacySpeaker.h"
+
+///
+/// Component Name Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_COMPONENT_NAME_PROTOCOL gLegacySpeakerComponentName = {
+ (EFI_COMPONENT_NAME_GET_DRIVER_NAME) LegacySpeakerComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)LegacySpeakerComponentNameGetControllerName,
+ "eng"
+};
+
+///
+/// Component Name 2 Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_COMPONENT_NAME2_PROTOCOL gLegacySpeakerComponentName2 = {
+ LegacySpeakerComponentNameGetDriverName,
+ LegacySpeakerComponentNameGetControllerName,
+ "en"
+};
+
+///
+/// Table of driver names
+///
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_UNICODE_STRING_TABLE mLegacySpeakerDriverNameTable[] = {
+ { "eng;en", (CHAR16 *)L"LegacySpeaker" },
+ { NULL, NULL }
+};
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mLegacySpeakerDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This != &gLegacySpeakerComponentName2)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ return Status;
+}
diff --git a/LegacySpeaker/ComponentName.h b/LegacySpeaker/ComponentName.h
new file mode 100644
index 0000000..5f3920b
--- /dev/null
+++ b/LegacySpeaker/ComponentName.h
@@ -0,0 +1,90 @@
+/** @file
+ TODO: Brief Description of UEFI Driver LegacySpeaker
+
+ TODO: Detailed Description of UEFI Driver LegacySpeaker
+
+ TODO: Copyright for UEFI Driver LegacySpeaker
+
+ TODO: License for UEFI Driver LegacySpeaker
+
+**/
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
diff --git a/LegacySpeaker/LegacySpeaker.c b/LegacySpeaker/LegacySpeaker.c
new file mode 100644
index 0000000..2f7b1b9
--- /dev/null
+++ b/LegacySpeaker/LegacySpeaker.c
@@ -0,0 +1,238 @@
+/** @file
+ TODO: Brief Description of UEFI Driver LegacySpeaker
+
+ TODO: Detailed Description of UEFI Driver LegacySpeaker
+
+ TODO: Copyright for UEFI Driver LegacySpeaker
+
+ TODO: License for UEFI Driver LegacySpeaker
+
+**/
+
+#include "LegacySpeaker.h"
+#include <Library/IoLib.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Speaker
+//////////////////////////////////////////////////////////////////////////
+/**
+
+ This function will enable the speaker to generate beep
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+TurnOnSpeaker (
+ )
+{
+ UINT8 Data;
+ Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+ Data |= 0x03;
+ IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function will stop beep from speaker.
+
+ @retval Status
+
+**/
+EFI_STATUS
+TurnOffSpeaker (
+ )
+{
+ UINT8 Data;
+
+ Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+ Data &= 0xFC;
+ IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+ return EFI_SUCCESS;
+}
+
+/**
+ Generate beep sound based upon number of beeps and duration of the beep
+
+ @param NumberOfBeeps Number of beeps which user want to produce
+ @param BeepDuration Duration for speaker gate need to be enabled
+ @param TimeInterval Interval between each beep
+
+ @retval Does not return if the reset takes place.
+ EFI_INVALID_PARAMETER If ResetType is invalid.
+
+**/
+EFI_STATUS
+OutputBeep (
+ IN UINTN NumberOfBeep,
+ IN UINTN BeepDuration,
+ IN UINTN TimeInterval
+ )
+{
+ UINTN Num;
+
+ for (Num=0; Num < NumberOfBeep; Num++) {
+ TurnOnSpeaker ();
+ //
+ // wait some time,at least 120us
+ //
+ gBS->Stall (BeepDuration);
+ TurnOffSpeaker();
+ gBS->Stall (TimeInterval);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function will program the speaker tone frequency. The value should be with 64k
+ boundary since it takes only 16 bit value which gets programmed in two step IO opearattion
+
+ @param Frequency A value which should be 16 bit only.
+
+ @retval EFI_SUCESS
+
+**/
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency (
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINT16 Frequency
+ )
+{
+ UINT8 Data;
+
+ Data = 0xB6;
+ IoWrite8(EFI_TIMER_CONTROL_PORT, Data);
+
+ Data = (UINT8)(Frequency & 0x00FF);
+ IoWrite8(EFI_TIMER_2_PORT, Data);
+ Data = (UINT8)((Frequency & 0xFF00) >> 8);
+ IoWrite8(EFI_TIMER_2_PORT, Data);
+ return EFI_SUCCESS;
+}
+
+/**
+ This function will generate the beep for specified duration.
+
+ @param NumberOfBeeps Number of beeps which user want to produce
+ @param BeepDuration Duration for speaker gate need to be enabled
+ @param TimeInterval Interval between each beep
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINTN NumberOfBeeps,
+ IN UINTN BeepDuration,
+ IN UINTN TimeInterval
+ )
+{
+
+ if ((NumberOfBeeps == 1) && (BeepDuration == 0) && (TimeInterval == 0)) {
+ TurnOnSpeaker ();
+ return EFI_SUCCESS;
+ }
+
+ if ((NumberOfBeeps == 0) && (BeepDuration == 0) && (TimeInterval == 0)) {
+ TurnOffSpeaker ();
+ return EFI_SUCCESS;
+ }
+
+ if (BeepDuration == 0) {
+ BeepDuration = EFI_DEFAULT_SHORT_BEEP_DURATION;
+ }
+
+ if (TimeInterval == 0) {
+ TimeInterval = EFI_DEFAULT_BEEP_TIME_INTERVAL;
+ }
+
+ OutputBeep (NumberOfBeeps, BeepDuration, TimeInterval);
+ return EFI_SUCCESS;
+}
+
+GUID gEfiSpeakerInterfaceProtocolGuid = EFI_SPEAKER_INTERFACE_PROTOCOL_GUID;
+EFI_SPEAKER_IF_PROTOCOL gEfiSpeakerInterfaceProtocol = {
+ ProgramToneFrequency,
+ GenerateBeepTone
+};
+
+//////////////////////////////////////////////////////////////////////////
+// Driver
+//////////////////////////////////////////////////////////////////////////
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ //
+ // Uninstall Driver Supported EFI Version Protocol onto ImageHandle
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ ImageHandle,
+ &gEfiSpeakerInterfaceProtocolGuid, &gEfiSpeakerInterfaceProtocol,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ // Clean up
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+LegacySpeakerDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Install Speaker protocol onto ImageHandle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiSpeakerInterfaceProtocolGuid, &gEfiSpeakerInterfaceProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+// gEfiSpeakerInterfaceProtocol.SetSpeakerToneFrequency(&gEfiSpeakerInterfaceProtocol, 0x500);
+// gEfiSpeakerInterfaceProtocol.GenerateBeep(&gEfiSpeakerInterfaceProtocol, 2, 200000, 200000);
+
+ return Status;
+}
+
diff --git a/LegacySpeaker/LegacySpeaker.h b/LegacySpeaker/LegacySpeaker.h
new file mode 100644
index 0000000..6d90b13
--- /dev/null
+++ b/LegacySpeaker/LegacySpeaker.h
@@ -0,0 +1,101 @@
+/** @file
+ TODO: Brief Description of UEFI Driver LegacySpeaker
+
+ TODO: Detailed Description of UEFI Driver LegacySpeaker
+
+ TODO: Copyright for UEFI Driver LegacySpeaker
+
+ TODO: License for UEFI Driver LegacySpeaker
+
+**/
+
+#ifndef __EFI_LEGACY_SPEAKER_H__
+#define __EFI_LEGACY_SPEAKER_H__
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+
+//
+// UEFI Driver Model Protocols
+//
+#include <Protocol/ComponentName2.h>
+#include <Protocol/ComponentName.h>
+
+//
+// Consumed Protocols
+//
+
+//
+// Produced Protocols
+//
+#include <Protocol/Speaker.h>
+
+
+//
+// Protocol instances
+//
+extern EFI_COMPONENT_NAME2_PROTOCOL gLegacySpeakerComponentName2;
+extern EFI_COMPONENT_NAME_PROTOCOL gLegacySpeakerComponentName;
+extern EFI_SPEAKER_IF_PROTOCOL gEfiSpeakerInterfaceProtocol;
+
+//
+// Include files with function prototypes
+//
+#include "ComponentName.h"
+
+//
+// Speaker Related Port Information
+//
+#define EFI_TIMER_COUNTER_PORT 0x40
+#define EFI_TIMER_CONTROL_PORT 0x43
+#define EFI_TIMER_2_PORT 0x42
+#define EFI_SPEAKER_CONTROL_PORT 0x61
+
+#define EFI_SPEAKER_OFF_MASK 0xFC
+
+#define EFI_DEFAULT_BEEP_FREQUENCY 0x500
+
+//
+// Default Intervals/Beep Duration
+//
+#define EFI_DEFAULT_LONG_BEEP_DURATION 0x70000
+#define EFI_DEFAULT_SHORT_BEEP_DURATION 0x50000
+#define EFI_DEFAULT_BEEP_TIME_INTERVAL 0x20000
+
+
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency(
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINT16 Frequency
+ );
+
+
+EFI_STATUS
+EFIAPI
+GenerateBeepTone(
+ IN EFI_SPEAKER_IF_PROTOCOL * This,
+ IN UINTN NumberOfBeeps,
+ IN UINTN BeepDuration,
+ IN UINTN TimeInterval
+ );
+
+EFI_STATUS
+TurnOnSpeaker(
+ );
+
+EFI_STATUS
+TurnOffSpeaker(
+ );
+
+#endif
diff --git a/LegacySpeaker/LegacySpeaker.inf b/LegacySpeaker/LegacySpeaker.inf
new file mode 100644
index 0000000..50dfc7f
--- /dev/null
+++ b/LegacySpeaker/LegacySpeaker.inf
@@ -0,0 +1,46 @@
+## @file
+# TODO: Brief Description of UEFI Driver LegacySpeaker
+#
+# TODO: Detailed Description of UEFI Driver LegacySpeaker
+#
+# TODO: Copyright for UEFI Driver LegacySpeaker
+#
+# TODO: License for UEFI Driver LegacySpeaker
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LegacySpeaker
+ FILE_GUID = f556f20f-1838-11e6-94c2-6067203c4d58
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = LegacySpeakerDriverEntryPoint
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[Sources]
+ LegacySpeaker.h
+ LegacySpeaker.c
+ ComponentName.c
+ ComponentName.h
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ BaseLib
+ UefiLib
+ DevicePathLib
+ DebugLib
+ IoLib
+
+[Protocols]
+ gEfiComponentName2ProtocolGuid
+ gEfiComponentNameProtocolGuid
+
+[Guids]
+
diff --git a/Library/CommonLib/CommonLib.inf b/Library/CommonLib/CommonLib.inf
new file mode 100644
index 0000000..2c379b8
--- /dev/null
+++ b/Library/CommonLib/CommonLib.inf
@@ -0,0 +1,65 @@
+## @file
+# EFI common library (helpers)
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = CommonLib
+ MODULE_UNI_FILE = CommonLib.uni
+ FILE_GUID = F779769D-58F4-4A49-A7D7-59473BBD3CCE
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CommonLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ EfiMem.c
+ EfiBio.c
+ EfiVar.c
+ EfiFile.c
+ EfiConsole.c
+ EfiAttrPrint.c
+ EfiBeep.c
+ EfiExec.c
+ EfiUsb.c
+ EfiTouch.c
+
+[Sources.IA32]
+ IA32/EfiCpuHalt.asm
+
+[Sources.X64]
+ X64/EfiCpuHalt.asm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+ ShellPkg/ShellPkg.dec
+
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+ UefiUsbLib
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiUsbIoProtocolGuid
+ gEfiAbsolutePointerProtocolGuid
+ gEfiGraphicsOutputProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
diff --git a/Library/CommonLib/EfiAttrPrint.c b/Library/CommonLib/EfiAttrPrint.c
new file mode 100644
index 0000000..adcd606
--- /dev/null
+++ b/Library/CommonLib/EfiAttrPrint.c
@@ -0,0 +1,477 @@
+/** @file
+EFI console print with attribute (based on shell print)
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/EFiShell.h>
+#include <Protocol/EfiShellParameters.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Custom print based on shell print (copied here to avoid runtime limitation)
+//////////////////////////////////////////////////////////////////////////
+
+#define ATTRPRINT_BUFSIZE 4096
+
+BOOLEAN gShellReady = FALSE;
+EFI_SHELL_PARAMETERS_PROTOCOL* mEfiShellParametersProtocol = NULL;
+EFI_SHELL_PROTOCOL* mEfiShellProtocol = NULL;
+
+VOID
+SetShellAPI(
+ IN VOID* shellProtocol,
+ IN VOID* shellParametersProtocol) {
+ mEfiShellParametersProtocol = (EFI_SHELL_PARAMETERS_PROTOCOL*)shellParametersProtocol;
+ mEfiShellProtocol = (EFI_SHELL_PROTOCOL*)shellProtocol;
+}
+
+/**
+ Safely append with automatic string resizing given length of Destination and
+ desired length of copy from Source.
+
+ append the first D characters of Source to the end of Destination, where D is
+ the lesser of Count and the StrLen() of Source. If appending those D characters
+ will fit within Destination (whose Size is given as CurrentSize) and
+ still leave room for a NULL terminator, then those characters are appended,
+ starting at the original terminating NULL of Destination, and a new terminating
+ NULL is appended.
+
+ If appending D characters onto Destination will result in a overflow of the size
+ given in CurrentSize the string will be grown such that the copy can be performed
+ and CurrentSize will be updated to the new size.
+
+ If Source is NULL, there is nothing to append, just return the current buffer in
+ Destination.
+
+ if Destination is NULL, then ASSERT()
+ if Destination's current length (including NULL terminator) is already more then
+ CurrentSize, then ASSERT()
+
+ @param[in, out] Destination The String to append onto
+ @param[in, out] CurrentSize on call the number of bytes in Destination. On
+ return possibly the new size (still in bytes). if NULL
+ then allocate whatever is needed.
+ @param[in] Source The String to append from
+ @param[in] Count Maximum number of characters to append. if 0 then
+ all are appended.
+
+ @return Destination return the resultant string.
+**/
+CHAR16*
+EFIAPI
+StrnCatGrow2 (
+ IN OUT CHAR16 **Destination,
+ IN OUT UINTN *CurrentSize,
+ IN CONST CHAR16 *Source,
+ IN UINTN Count
+ )
+{
+ UINTN DestinationStartSize;
+ UINTN NewSize;
+
+ //
+ // ASSERTs
+ //
+ ASSERT(Destination != NULL);
+
+ //
+ // If there's nothing to do then just return Destination
+ //
+ if (Source == NULL) {
+ return (*Destination);
+ }
+
+ //
+ // allow for un-initialized pointers, based on size being 0
+ //
+ if (CurrentSize != NULL && *CurrentSize == 0) {
+ *Destination = NULL;
+ }
+
+ //
+ // allow for NULL pointers address as Destination
+ //
+ if (*Destination != NULL) {
+ ASSERT(CurrentSize != 0);
+ DestinationStartSize = StrSize(*Destination);
+ ASSERT(DestinationStartSize <= *CurrentSize);
+ } else {
+ DestinationStartSize = 0;
+// ASSERT(*CurrentSize == 0);
+ }
+
+ //
+ // Append all of Source?
+ //
+ if (Count == 0) {
+ Count = StrLen(Source);
+ }
+
+ //
+ // Test and grow if required
+ //
+ if (CurrentSize != NULL) {
+ NewSize = *CurrentSize;
+ if (NewSize < DestinationStartSize + (Count * sizeof(CHAR16))) {
+ while (NewSize < (DestinationStartSize + (Count*sizeof(CHAR16)))) {
+ NewSize += 2 * Count * sizeof(CHAR16);
+ }
+ *Destination = MEM_REALLOC(*CurrentSize, NewSize, *Destination);
+ *CurrentSize = NewSize;
+ }
+ } else {
+ NewSize = (Count+1)*sizeof(CHAR16);
+ *Destination = MEM_ALLOC(NewSize);
+ }
+
+ //
+ // Now use standard StrnCat on a big enough buffer
+ //
+ if (*Destination == NULL) {
+ return (NULL);
+ }
+
+ StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);
+ return *Destination;
+}
+
+
+/**
+ This is a find and replace function. Upon successful return the NewString is a copy of
+ SourceString with each instance of FindTarget replaced with ReplaceWith.
+
+ If SourceString and NewString overlap the behavior is undefined.
+
+ If the string would grow bigger than NewSize it will halt and return error.
+
+ @param[in] SourceString The string with source buffer.
+ @param[in, out] NewString The string with resultant buffer.
+ @param[in] NewSize The size in bytes of NewString.
+ @param[in] FindTarget The string to look for.
+ @param[in] ReplaceWith The string to replace FindTarget with.
+ @param[in] SkipPreCarrot If TRUE will skip a FindTarget that has a '^'
+ immediately before it.
+ @param[in] ParameterReplacing If TRUE will add "" around items with spaces.
+
+ @retval EFI_INVALID_PARAMETER SourceString was NULL.
+ @retval EFI_INVALID_PARAMETER NewString was NULL.
+ @retval EFI_INVALID_PARAMETER FindTarget was NULL.
+ @retval EFI_INVALID_PARAMETER ReplaceWith was NULL.
+ @retval EFI_INVALID_PARAMETER FindTarget had length < 1.
+ @retval EFI_INVALID_PARAMETER SourceString had length < 1.
+ @retval EFI_BUFFER_TOO_SMALL NewSize was less than the minimum size to hold
+ the new string (truncation occurred).
+ @retval EFI_SUCCESS The string was successfully copied with replacement.
+**/
+EFI_STATUS
+EFIAPI
+StrCopySearchAndReplace(
+ IN CHAR16 CONST *SourceString,
+ IN OUT CHAR16 *NewString,
+ IN UINTN NewSize,
+ IN CONST CHAR16 *FindTarget,
+ IN CONST CHAR16 *ReplaceWith,
+ IN CONST BOOLEAN SkipPreCarrot,
+ IN CONST BOOLEAN ParameterReplacing
+ )
+{
+ UINTN Size;
+ CHAR16 *Replace;
+
+ if ( (SourceString == NULL)
+ || (NewString == NULL)
+ || (FindTarget == NULL)
+ || (ReplaceWith == NULL)
+ || (StrLen(FindTarget) < 1)
+ || (StrLen(SourceString) < 1)
+ ){
+ return (EFI_INVALID_PARAMETER);
+ }
+ Replace = NULL;
+ if (StrStr(ReplaceWith, L" ") == NULL || !ParameterReplacing) {
+ Replace = StrnCatGrow2(&Replace, NULL, ReplaceWith, 0);
+ } else {
+ Replace = MEM_ALLOC(StrSize(ReplaceWith) + 2*sizeof(CHAR16));
+ if (Replace != NULL) {
+ UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith);
+ }
+ }
+ if (Replace == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ NewString = ZeroMem(NewString, NewSize);
+ while (*SourceString != CHAR_NULL) {
+ //
+ // if we find the FindTarget and either Skip == FALSE or Skip and we
+ // dont have a carrot do a replace...
+ //
+ if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0
+ && ((SkipPreCarrot && *(SourceString-1) != L'^') || !SkipPreCarrot)
+ ){
+ SourceString += StrLen(FindTarget);
+ Size = StrSize(NewString);
+ if ((Size + (StrLen(Replace)*sizeof(CHAR16))) > NewSize) {
+ MEM_FREE(Replace);
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ StrCatS(NewString, NewSize/sizeof(CHAR16), Replace);
+ } else {
+ Size = StrSize(NewString);
+ if (Size + sizeof(CHAR16) > NewSize) {
+ MEM_FREE(Replace);
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ StrnCatS(NewString, NewSize/sizeof(CHAR16), SourceString, 1);
+ SourceString++;
+ }
+ }
+ MEM_FREE(Replace);
+ return (EFI_SUCCESS);
+}
+
+/**
+ Internal worker function to output a string.
+
+ This function will output a string to the correct StdOut.
+
+ @param[in] String The string to print out.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval !EFI_SUCCESS The operation failed.
+**/
+EFI_STATUS
+EFIAPI
+AttrPrintTo (
+ IN CONST CHAR16 *String
+ )
+{
+ UINTN Size;
+ Size = StrSize(String) - sizeof(CHAR16);
+ if (Size == 0) {
+ return (EFI_SUCCESS);
+ }
+ if (mEfiShellParametersProtocol != NULL) {
+ return (mEfiShellProtocol->WriteFile(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));
+ }
+ return gST->ConOut->OutputString(gST->ConOut, (CHAR16*)String);
+}
+
+/**
+ Print at a specific location on the screen.
+
+ This function will move the cursor to a given screen location and print the specified string
+
+ If -1 is specified for either the Row or Col the current screen location for BOTH
+ will be used.
+
+ if either Row or Col is out of range for the current console, then ASSERT
+ if Format is NULL, then ASSERT
+
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports
+ the following additional flags:
+ %N - Set output attribute to normal
+ %H - Set output attribute to highlight
+ %E - Set output attribute to error
+ %B - Set output attribute to blue color
+ %V - Set output attribute to green color
+
+ Note: The background color is controlled by the shell command cls.
+
+ @param[in] Col the column to print at
+ @param[in] Row the row to print at
+ @param[in] Format the format string
+ @param[in] Marker the marker for the variable argument list
+
+ @return EFI_SUCCESS The operation was successful.
+ @return EFI_DEVICE_ERROR The console device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+InternalAttrPrintWorker(
+ IN INT32 Col OPTIONAL,
+ IN INT32 Row OPTIONAL,
+ IN CONST CHAR16 *Format,
+ IN VA_LIST Marker
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ResumeLocation;
+ CHAR16 *FormatWalker;
+ UINTN OriginalAttribute;
+ CHAR16 *mPostReplaceFormat;
+ CHAR16 *mPostReplaceFormat2;
+
+ mPostReplaceFormat = (CHAR16*)MEM_ALLOC (ATTRPRINT_BUFSIZE);
+ mPostReplaceFormat2 = (CHAR16*)MEM_ALLOC (ATTRPRINT_BUFSIZE);
+
+ if (mPostReplaceFormat == NULL || mPostReplaceFormat2 == NULL) {
+ MEM_FREE(mPostReplaceFormat);
+ MEM_FREE(mPostReplaceFormat2);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ Status = EFI_SUCCESS;
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+
+ //
+ // Back and forth each time fixing up 1 of our flags...
+ //
+ Status = StrCopySearchAndReplace(Format, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%N", L"%%N", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat, mPostReplaceFormat2, ATTRPRINT_BUFSIZE, L"%E", L"%%E", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%H", L"%%H", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat, mPostReplaceFormat2, ATTRPRINT_BUFSIZE, L"%B", L"%%B", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%V", L"%%V", FALSE, FALSE);
+
+ //
+ // Use the last buffer from replacing to print from...
+ //
+ UnicodeVSPrint (mPostReplaceFormat2, ATTRPRINT_BUFSIZE, mPostReplaceFormat, Marker);
+
+ if (Col != -1 && Row != -1) {
+ Status = gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
+ }
+
+ FormatWalker = mPostReplaceFormat2;
+ while (*FormatWalker != CHAR_NULL) {
+ //
+ // Find the next attribute change request
+ //
+ ResumeLocation = StrStr(FormatWalker, L"%");
+ if (ResumeLocation != NULL) {
+ *ResumeLocation = CHAR_NULL;
+ }
+ //
+ // print the current FormatWalker string
+ //
+ if (StrLen(FormatWalker)>0) {
+ Status = AttrPrintTo(FormatWalker);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ //
+ // update the attribute
+ //
+ if (ResumeLocation != NULL) {
+ if (*(ResumeLocation-1) == L'^') {
+ //
+ // Move cursor back 1 position to overwrite the ^
+ //
+ gST->ConOut->SetCursorPosition(gST->ConOut, gST->ConOut->Mode->CursorColumn - 1, gST->ConOut->Mode->CursorRow);
+
+ //
+ // Print a simple '%' symbol
+ //
+ Status = AttrPrintTo(L"%");
+ ResumeLocation = ResumeLocation - 1;
+ } else {
+ switch (*(ResumeLocation+1)) {
+ case (L'N'):
+ gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);
+ break;
+ case (L'E'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'H'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'B'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'V'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ default:
+ //
+ // Print a simple '%' symbol
+ //
+ Status = AttrPrintTo(L"%");
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ ResumeLocation = ResumeLocation - 1;
+ break;
+ }
+ }
+ } else {
+ //
+ // reset to normal now...
+ //
+ break;
+ }
+
+ //
+ // update FormatWalker to Resume + 2 (skip the % and the indicator)
+ //
+ FormatWalker = ResumeLocation + 2;
+ }
+
+ gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);
+
+ MEM_FREE(mPostReplaceFormat);
+ MEM_FREE(mPostReplaceFormat2);
+ return (Status);
+}
+
+/**
+ Print at a specific location on the screen.
+
+ This function will move the cursor to a given screen location and print the specified string.
+
+ If -1 is specified for either the Row or Col the current screen location for BOTH
+ will be used.
+
+ If either Row or Col is out of range for the current console, then ASSERT.
+ If Format is NULL, then ASSERT.
+
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports
+ the following additional flags:
+ %N - Set output attribute to normal
+ %H - Set output attribute to highlight
+ %E - Set output attribute to error
+ %B - Set output attribute to blue color
+ %V - Set output attribute to green color
+
+ Note: The background color is controlled by the shell command cls.
+
+ @param[in] Col the column to print at
+ @param[in] Row the row to print at
+ @param[in] Format the format string
+ @param[in] ... The variable argument list.
+
+ @return EFI_SUCCESS The printing was successful.
+ @return EFI_DEVICE_ERROR The console device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+AttrPrintEx(
+ IN INT32 Col OPTIONAL,
+ IN INT32 Row OPTIONAL,
+ IN CONST CHAR16 *Format,
+ ...
+ )
+{
+ VA_LIST Marker;
+ EFI_STATUS RetVal;
+ if (Format == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+ VA_START (Marker, Format);
+ RetVal = InternalAttrPrintWorker(Col, Row, Format, Marker);
+ VA_END(Marker);
+ return(RetVal);
+}
diff --git a/Library/CommonLib/EfiBeep.c b/Library/CommonLib/EfiBeep.c
new file mode 100644
index 0000000..2522078
--- /dev/null
+++ b/Library/CommonLib/EfiBeep.c
@@ -0,0 +1,69 @@
+/** @file
+EFI speaker beep helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Speaker.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Beep
+//////////////////////////////////////////////////////////////////////////
+EFI_HANDLE* gSpeakerHandles = NULL;
+UINTN gSpeakerCount = 0;
+EFI_SPEAKER_IF_PROTOCOL* gSpeaker = NULL;
+EFI_GUID gSpeakerGuid = EFI_SPEAKER_INTERFACE_PROTOCOL_GUID;
+
+// Beep defaults
+int gBeepEnabled = 1;
+BOOLEAN gBeepControlEnabled = 1;
+int gBeepDevice = -1;
+int gBeepNumberDefault = 1;
+int gBeepDurationDefault = 100;
+int gBeepIntervalDefault = 0;
+int gBeepToneDefault = 0x500;
+
+EFI_STATUS
+InitSpeaker() {
+ EFI_STATUS res;
+ // Init Console control if supported
+ res = EfiGetHandles(ByProtocol, &gSpeakerGuid, 0, &gSpeakerHandles, &gSpeakerCount);
+ if (gSpeakerCount > 0) {
+ return SpeakerSelect(gSpeakerCount - 1);
+ }
+ return res;
+}
+
+EFI_STATUS
+SpeakerSelect(
+ IN UINTN index) {
+ if (index < gSpeakerCount) {
+ return gBS->HandleProtocol(gSpeakerHandles[index], &gSpeakerGuid, (VOID**)&gSpeaker);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+SpeakerBeep(
+ IN UINT16 Tone,
+ IN UINTN NumberOfBeeps,
+ IN UINTN Duration,
+ IN UINTN Interval
+ )
+{
+ if (gSpeaker != NULL) {
+ gSpeaker->SetSpeakerToneFrequency(gSpeaker, Tone);
+ return gSpeaker->GenerateBeep(gSpeaker, NumberOfBeeps, Duration, Interval);
+ }
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Library/CommonLib/EfiBio.c b/Library/CommonLib/EfiBio.c
new file mode 100644
index 0000000..9577c08
--- /dev/null
+++ b/Library/CommonLib/EfiBio.c
@@ -0,0 +1,232 @@
+/** @file
+EFI block I/O helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/LoadedImage.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Print handle info
+//////////////////////////////////////////////////////////////////////////
+
+VOID
+EfiPrintDevicePath(
+ IN EFI_HANDLE handle)
+{
+ CHAR16 *StrPath;
+ EFI_DEVICE_PATH *DevicePath;
+ OUT_PRINT(L"(%0X): ", handle);
+ DevicePath = DevicePathFromHandle(handle);
+ if (DevicePath == NULL) {
+ ERR_PRINT(L"No path found");
+ return;
+ }
+ StrPath = ConvertDevicePathToText(DevicePath, FALSE, FALSE);
+ OUT_PRINT(StrPath);
+ MEM_FREE(StrPath);
+}
+
+VOID
+EfiPrintProtocols(
+ IN EFI_HANDLE handle)
+{
+ EFI_GUID **guids;
+ UINTN count;
+ EFI_STATUS status;
+ status = gBS->ProtocolsPerHandle(handle, &guids, &count);
+ if (!EFI_ERROR(status)) {
+ UINTN i;
+ for (i = 0; i < count; ++i) {
+ OUT_PRINT(L"%d: %g\n", i, guids[i]);
+ }
+ FreePool(guids);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Handles
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiGetHandles(
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol, OPTIONAL
+ IN VOID *SearchKey, OPTIONAL
+ OUT EFI_HANDLE **Buffer,
+ OUT UINTN *Count
+ )
+{
+ EFI_STATUS res = EFI_BUFFER_TOO_SMALL;
+ UINTN BufferSize;
+ if(*Buffer != NULL) MEM_FREE(*Buffer);
+ *Count = 0;
+ *Buffer = (EFI_HANDLE*) MEM_ALLOC(sizeof(EFI_HANDLE));
+ if (*Buffer) {
+ BufferSize = sizeof(EFI_HANDLE);
+ res = gBS->LocateHandle(SearchType, Protocol, SearchKey, &BufferSize, *Buffer);
+ if (res == RETURN_BUFFER_TOO_SMALL) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)MEM_ALLOC(BufferSize);
+ if (!Buffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ res = gBS->LocateHandle(SearchType, Protocol, SearchKey, &BufferSize, *Buffer);
+ if(res != EFI_SUCCESS) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)NULL;
+ return res;
+ }
+ } else if (EFI_ERROR(res)) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)NULL;
+ return res;
+ }
+ *Count = (UINTN)(BufferSize / sizeof(EFI_HANDLE));
+ }
+ return res;
+}
+
+EFI_STATUS
+EfiGetStartDevice(
+ OUT EFI_HANDLE* handle)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ *handle = LoadedImage->DeviceHandle;
+ return Status;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Block I/O
+//////////////////////////////////////////////////////////////////////////
+
+EFI_BLOCK_IO_PROTOCOL*
+EfiGetBlockIO(
+ IN EFI_HANDLE handle
+ )
+{
+ EFI_STATUS res;
+ EFI_BLOCK_IO_PROTOCOL* blockIOProtocol = NULL;
+ res = gBS->HandleProtocol(handle, &gEfiBlockIoProtocolGuid, (VOID**)&blockIOProtocol);
+ if (res == RETURN_SUCCESS &&
+ blockIOProtocol != NULL &&
+ blockIOProtocol->Media->MediaPresent) {
+ return blockIOProtocol;
+ }
+ return NULL;
+}
+
+
+EFI_HANDLE* gBIOHandles;
+UINTN gBIOCount;
+
+EFI_STATUS
+InitBio() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiBlockIoProtocolGuid, 0, &gBIOHandles, &gBIOCount);
+ return res;
+}
+
+BOOLEAN
+EfiIsPartition(
+ IN EFI_HANDLE h
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ node = DevicePathFromHandle(h);
+ if (node == NULL) return FALSE;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ return TRUE;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return FALSE;
+}
+
+EFI_STATUS
+EfiGetPartDetails(
+ IN EFI_HANDLE h,
+ OUT HARDDRIVE_DEVICE_PATH* dpVolme,
+ OUT EFI_HANDLE* hDisk)
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ EFI_DEVICE_PATH_PROTOCOL* dpVolume;
+ EFI_DEVICE_PATH_PROTOCOL* dpDisk;
+ EFI_STATUS res;
+ dpVolume = DevicePathFromHandle(h);
+ dpDisk = DuplicateDevicePath(dpVolume);
+ node = (EFI_DEVICE_PATH_PROTOCOL *)dpDisk;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ CopyMem(dpVolme, node, sizeof(HARDDRIVE_DEVICE_PATH));
+ SetDevicePathEndNode(node);
+ res = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &dpDisk, hDisk);
+ return res;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EfiGetPartGUID(
+ IN EFI_HANDLE h,
+ OUT EFI_GUID* guid)
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ EFI_DEVICE_PATH_PROTOCOL* dpVolume;
+ if (guid == NULL) return EFI_INVALID_PARAMETER;
+ dpVolume = DevicePathFromHandle(h);
+ node = (EFI_DEVICE_PATH_PROTOCOL *)dpVolume;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ HARDDRIVE_DEVICE_PATH* hdpNode = (HARDDRIVE_DEVICE_PATH*)node;
+ CopyMem(guid, hdpNode->Signature, sizeof(*guid));
+ return EFI_SUCCESS;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EfiFindPartByGUID(
+ IN EFI_GUID* guid,
+ OUT EFI_HANDLE* h
+ )
+{
+ EFI_STATUS res;
+ EFI_GUID guidI;
+ UINTN i;
+ if (guid == NULL || h == NULL) return EFI_INVALID_PARAMETER;
+ for (i = 0; i < gBIOCount; ++i) {
+ res = EfiGetPartGUID(gBIOHandles[i], &guidI);
+ if (!EFI_ERROR(res)) {
+ if (CompareMem(&guidI, guid, sizeof(guidI)) == 0) {
+ *h = gBIOHandles[i];
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
diff --git a/Library/CommonLib/EfiConsole.c b/Library/CommonLib/EfiConsole.c
new file mode 100644
index 0000000..8a87ec8
--- /dev/null
+++ b/Library/CommonLib/EfiConsole.c
@@ -0,0 +1,347 @@
+/** @file
+EFI console helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/Speaker.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Print
+//////////////////////////////////////////////////////////////////////////
+
+VOID
+FlushInputDelay(
+ IN UINTN delay
+ )
+{
+ EFI_INPUT_KEY key;
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex = 0;
+
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, delay);
+ while (EventIndex == 0) {
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+ }
+ gBS->CloseEvent(InputEvents[1]);
+}
+
+VOID
+FlushInput() {
+ FlushInputDelay(1000000);
+}
+
+EFI_INPUT_KEY
+KeyWait(
+ CHAR16* Prompt,
+ UINTN mDelay,
+ UINT16 scanCode,
+ UINT16 unicodeChar)
+{
+ EFI_INPUT_KEY key;
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex;
+
+ FlushInput();
+ key.ScanCode = scanCode;
+ key.UnicodeChar = unicodeChar;
+
+ InputEvents[0] = gST->ConIn->WaitForKey;
+
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, 10000000);
+ while (mDelay > 0) {
+ OUT_PRINT(Prompt, mDelay);
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ break;
+ }
+ else {
+ mDelay--;
+ }
+ }
+ OUT_PRINT(Prompt, mDelay);
+ gBS->CloseEvent(InputEvents[1]);
+ return key;
+}
+
+EFI_INPUT_KEY
+GetKey(void)
+{
+ EFI_INPUT_KEY key;
+ UINTN EventIndex;
+
+ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &EventIndex);
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ return key;
+}
+
+VOID
+ConsoleShowTip(
+ IN CHAR16* tip,
+ IN UINTN delay)
+{
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex = 0;
+ UINTN i = 0;
+ EFI_INPUT_KEY key;
+ OUT_PRINT(L"%s", tip);
+
+ // delay
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, delay);
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+
+ // remove tip
+ for (i = 0; i < StrLen(tip); ++i) {
+ OUT_PRINT(L"\b \b", tip);
+ }
+}
+
+
+VOID
+GetLine (
+ UINTN *length,
+ CHAR16 *line,
+ CHAR8 *asciiLine,
+ UINTN line_max,
+ UINT8 show)
+{
+ EFI_INPUT_KEY key;
+ UINT32 count = 0;
+
+ do {
+ key = GetKey();
+
+ if ((count >= line_max &&
+ key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED ||
+ key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ } else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ OUT_PRINT(L"\b \b");
+ if (line != NULL) line[--count] = '\0';
+ if (asciiLine != NULL) asciiLine[--count] = '\0';
+ continue;
+ }
+
+ // check size of line
+ if (count < line_max - 1) {
+ if (show) {
+ OUT_PRINT(L"%c", key.UnicodeChar);
+ }
+ else {
+ OUT_PRINT(L"*");
+ }
+ // save char
+ if (line != NULL) line[count++] = key.UnicodeChar;
+ if (asciiLine != NULL) asciiLine[count++] = (CHAR8)key.UnicodeChar;
+ }
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ OUT_PRINT(L"\n");
+ if (length != NULL) *length = count;
+ // Set end of line
+ if (line != NULL) line[count] = '\0';
+ if (asciiLine != NULL) asciiLine[count] = '\0';
+}
+
+int
+AskAsciiString(
+ CHAR8* prompt,
+ CHAR8* str,
+ UINTN max_len,
+ UINT8 visible)
+{
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, NULL, str, max_len, visible);
+ return (UINT32)len;
+}
+
+int
+AskInt(
+ CHAR8* prompt,
+ UINT8 visible)
+{
+ CHAR16 buf[32];
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, visible);
+ return (UINT32)StrDecimalToUintn(buf);
+}
+
+UINT8
+AskConfirm(
+ CHAR8* prompt,
+ UINT8 visible)
+{
+ CHAR16 buf[2];
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, visible);
+ return (buf[0] == 'y') || (buf[0] == 'Y') ? 1 : 0;
+}
+
+UINT64
+AskUINT64(
+ IN char* prompt,
+ IN UINT64 def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[%lld] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : (UINT64)StrDecimalToUint64(buf);
+}
+
+UINT64
+AskHexUINT64(
+ IN char* prompt,
+ IN UINT64 def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[0x%llx] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : (UINT64)StrHexToUint64(buf);
+}
+
+UINTN
+AskUINTN(
+ IN char* prompt,
+ IN UINTN def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[%d] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : StrDecimalToUintn(buf);
+}
+
+EFI_STATUS
+ConsoleGetOutput(
+ IN EFI_HANDLE handle,
+ OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL** io
+ ) {
+ return gBS->HandleProtocol(handle, &gEfiSimpleTextOutProtocolGuid, (VOID**)io);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Ascii converters
+//////////////////////////////////////////////////////////////////////////
+BOOLEAN
+AsciiHexToDigit(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ )
+{
+ CHAR8 ch;
+ ch = str[0];
+ if (ch >= '0' && ch <= '9') {
+ *b = ch - '0';
+ return TRUE;
+ }
+ else {
+ ch = ch & ~0x20;
+ if (ch >= 'A' && ch <= 'F') {
+ *b = ch - 'A' + 10;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOLEAN
+AsciiHexToByte(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ )
+{
+ UINT8 low = 0;
+ UINT8 high = 0;
+ BOOLEAN res;
+ res = AsciiHexToDigit(&high, str);
+ res = res && AsciiHexToDigit(&low, str + 1);
+ *b = low | high << 4;
+ return res;
+}
+
+BOOLEAN
+AsciiStrToGuid(
+ OUT EFI_GUID *guid,
+ IN CHAR8 *str
+ )
+{
+ UINT8 b[16];
+ BOOLEAN res = TRUE;
+ int i;
+ CHAR8* pos = str;
+ if (guid == NULL || str == NULL) return FALSE;
+ for (i = 0; i < 16; ++i) {
+ if (*pos == '-') pos++;
+ res = res && AsciiHexToByte(&b[i], pos);
+ pos += 2;
+ if (!res) return FALSE;
+ }
+ guid->Data1 = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
+ guid->Data2 = b[4] << 8 | b[5];
+ guid->Data3 = b[6] << 8 | b[7];
+ CopyMem(&guid->Data4, &b[8], 8);
+ return res;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Console control
+//////////////////////////////////////////////////////////////////////////
+
+EFI_HANDLE* gConsoleControlHandles = NULL;
+UINTN gConsoleControlCount = 0;
+
+EFI_STATUS
+InitConsoleControl() {
+ EFI_STATUS res;
+ // Init Console control if supported
+ EFI_GUID gConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+ EFI_CONSOLE_CONTROL_PROTOCOL* ConsoleControl;
+ res = EfiGetHandles(ByProtocol, &gConsoleControlProtocolGuid, 0, &gConsoleControlHandles, &gConsoleControlCount);
+ if (gConsoleControlCount > 0) {
+ res = gBS->HandleProtocol(gConsoleControlHandles[0], &gConsoleControlProtocolGuid, (VOID**)&ConsoleControl);
+ if (!EFI_ERROR(res)) {
+ // Unlock graphics
+ ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenGraphics);
+ }
+ }
+ return res;
+}
diff --git a/Library/CommonLib/EfiExec.c b/Library/CommonLib/EfiExec.c
new file mode 100644
index 0000000..ff0aa95
--- /dev/null
+++ b/Library/CommonLib/EfiExec.c
@@ -0,0 +1,88 @@
+/** @file
+EFI execute helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+EFI_STATUS
+EfiExec(
+ IN EFI_HANDLE deviceHandle,
+ IN CHAR16* path
+ )
+{
+ EFI_STATUS res;
+ EFI_DEVICE_PATH* DevicePath;
+ EFI_HANDLE ImageHandle;
+ UINTN ExitDataSize;
+ CHAR16 *ExitData;
+ if (deviceHandle == NULL) {
+ deviceHandle = gFileRootHandle;
+ }
+ if (!path || !deviceHandle) return EFI_INVALID_PARAMETER;
+ DevicePath = FileDevicePath(deviceHandle, path);
+
+ res = gBS->LoadImage(FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = gBS->StartImage(ImageHandle, &ExitDataSize, &ExitData);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return res;
+}
+
+/**
+This function will connect all current system handles recursively. The
+connection will finish until every handle's child handle created if it have.
+
+@retval EFI_SUCCESS All handles and it's child handle have been
+connected
+@retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+ConnectAllEfi(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+
+ Status = gBS->LocateHandleBuffer(
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->ConnectController(HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/Library/CommonLib/EfiFile.c b/Library/CommonLib/EfiFile.c
new file mode 100644
index 0000000..b1e2076
--- /dev/null
+++ b/Library/CommonLib/EfiFile.c
@@ -0,0 +1,350 @@
+/** @file
+EFI file system helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Library/BaseMemoryLib.h>
+
+//////////////////////////////////////////////////////////////////////////
+// EFI file
+//////////////////////////////////////////////////////////////////////////
+
+EFI_FILE* gFileRoot = NULL;
+EFI_HANDLE gFileRootHandle = NULL;
+
+EFI_HANDLE* gFSHandles = NULL;
+UINTN gFSCount = 0;
+
+EFI_STATUS
+InitFS() {
+ EFI_STATUS res;
+ EfiGetHandles(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, 0, &gFSHandles, &gFSCount);
+ res = EfiGetStartDevice(&gFileRootHandle);
+ if (!EFI_ERROR(res)) {
+ res = FileOpenRoot(gFileRootHandle, &gFileRoot);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileOpenRoot(
+ IN EFI_HANDLE rootHandle,
+ OUT EFI_FILE** rootFile)
+{
+ EFI_STATUS res = 0;
+ EFI_FILE_IO_INTERFACE* fSysProtocol = NULL;
+ res = gBS->HandleProtocol(rootHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&fSysProtocol);
+ if (res == RETURN_SUCCESS && fSysProtocol != NULL) {
+ res = fSysProtocol->OpenVolume(fSysProtocol, rootFile);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileOpen(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT EFI_FILE** file,
+ IN UINT64 mode,
+ IN UINT64 attributes
+ )
+{
+ EFI_STATUS res;
+
+ if (!name || !file) { return EFI_INVALID_PARAMETER; }
+ if (!root) root = gFileRoot;
+ if (!root) { return EFI_INVALID_PARAMETER; }
+ if (mode == 0) {
+ mode = EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE;
+ }
+ res = root->Open(root, file, name, mode , attributes);
+ return res;
+}
+
+EFI_STATUS
+FileClose(
+ IN EFI_FILE* f)
+{
+ if (!f) { return EFI_INVALID_PARAMETER; }
+ return f->Close(f);
+}
+
+EFI_STATUS
+FileDelete(
+ IN EFI_FILE* root,
+ IN CHAR16* name
+ )
+{
+ EFI_FILE* f;
+ EFI_STATUS res;
+ if (!name) { return EFI_INVALID_PARAMETER; }
+ res = FileOpen(root, name, &f, 0, 0);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = f->Delete(f);
+// f->Close(f);
+ return res;
+}
+
+EFI_STATUS
+FileRead(
+ IN EFI_FILE* f,
+ OUT VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position)
+{
+ EFI_STATUS res;
+
+ if (!f || !data || !bytes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (position != NULL) {
+ res = f->SetPosition(f, *position);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ }
+ res = f->Read(f, bytes, data);
+ if (position != NULL) {
+ f->GetPosition(f, position);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileWrite(
+ IN EFI_FILE* f,
+ IN VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position)
+{
+ EFI_STATUS res;
+
+ if (!f || !data || !bytes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (position != NULL) {
+ res = f->SetPosition(f, *position);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ }
+ res = f->Write(f, bytes, data);
+ if (position != NULL) {
+ f->GetPosition(f, position);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileGetInfo(
+ IN EFI_FILE* f,
+ OUT EFI_FILE_INFO** info,
+ OUT UINTN* size
+ )
+{
+ EFI_STATUS res;
+ UINTN sz = 0;
+ if (!f || !info) { return EFI_INVALID_PARAMETER; }
+ res = f->GetInfo(f, &gEfiFileInfoGuid, &sz, NULL);
+ if (res == RETURN_BUFFER_TOO_SMALL) {
+ *info = (EFI_FILE_INFO*)MEM_ALLOC(sz);
+ if (!(*info)) {
+ return res;
+ }
+ res = f->GetInfo(f, &gEfiFileInfoGuid, &sz, *info);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(*info);
+ *info = NULL;
+ sz = 0;
+ }
+ }
+ if (size) {
+ *size = sz;
+ }
+ return res;
+}
+
+EFI_STATUS
+FileGetSize(
+ IN EFI_FILE* f,
+ OUT UINTN* size
+ )
+{
+ EFI_STATUS res;
+ EFI_FILE_INFO* info = NULL;
+ if (!f || !size) { return EFI_INVALID_PARAMETER; }
+ res = FileGetInfo(f, &info, NULL);
+ if (!EFI_ERROR(res)) {
+ *size = (UINTN)info->FileSize;
+ MEM_FREE(info);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileLoad(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT VOID** data,
+ OUT UINTN* size
+ )
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ UINTN sz;
+ if (!data) {
+ return EFI_INVALID_PARAMETER;
+ }
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetSize(file, &sz);
+ if (EFI_ERROR(res)) {
+ FileClose(file);
+ return res;
+ }
+ *data = MEM_ALLOC(sz);
+ if (*data == NULL) {
+ FileClose(file);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ res = FileRead(file, *data, &sz, NULL);
+ if (EFI_ERROR(res)) {
+ FileClose(file);
+ MEM_FREE(*data);
+ return res;
+ }
+ FileClose(file);
+ if (size != NULL) {
+ *size = sz;
+ }
+ return res;
+}
+
+EFI_STATUS
+FileSave(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ IN VOID* data,
+ IN UINTN size
+ )
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ UINTN sz = size;
+ if (!data || !name) { return EFI_INVALID_PARAMETER; }
+ FileDelete(root, name);
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileWrite(file, data, &sz, NULL);
+ FileClose(file);
+ return res;
+}
+
+EFI_STATUS
+FileExist(
+ IN EFI_FILE* root,
+ IN CHAR16* name)
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ FileClose(file);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileRename(
+ IN EFI_FILE* root,
+ IN CHAR16* src,
+ IN CHAR16* dst)
+{
+ EFI_STATUS res;
+ EFI_FILE* file;
+ EFI_FILE_INFO* info = NULL;
+ UINTN sz;
+ EFI_FILE_INFO* dstinfo = NULL;
+ UINTN dstinfosz;
+
+ res = FileOpen(root, src, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetInfo(file, &info, &sz);
+ if (EFI_ERROR(res)) return res;
+ dstinfosz = SIZE_OF_EFI_FILE_INFO + StrSize(dst);
+ dstinfo = (EFI_FILE_INFO*)MEM_ALLOC(dstinfosz);
+ if (dstinfo != NULL) {
+ CopyMem(dstinfo, info, SIZE_OF_EFI_FILE_INFO);
+ dstinfo->FileName[0] = 0;
+ StrCat(dstinfo->FileName, dst);
+ res = file->SetInfo(file, &gEfiFileInfoGuid, dstinfosz, dstinfo);
+ } else {
+ res = EFI_BUFFER_TOO_SMALL;
+ }
+
+ MEM_FREE(info);
+ MEM_FREE(dstinfo);
+ FileClose(file);
+ return res;
+}
+
+EFI_STATUS
+FileCopy(
+ IN EFI_FILE* srcroot,
+ IN CHAR16* src,
+ IN EFI_FILE* dstroot,
+ IN CHAR16* dst,
+ IN UINTN bufSz
+ )
+{
+ EFI_STATUS res;
+ EFI_FILE* srcfile = NULL;
+ EFI_FILE* dstfile = NULL;
+ UINTN remains;
+ CHAR8* data = NULL;
+ UINTN datasz = bufSz;
+
+ res = FileOpen(srcroot, src, &srcfile, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetSize(srcfile, &remains);
+ if (EFI_ERROR(res)) return res;
+
+ data = (CHAR8*)MEM_ALLOC(bufSz);
+ if (data == NULL) {
+ res = EFI_BUFFER_TOO_SMALL;
+ goto copyerr;
+ }
+
+ res = FileOpen(dstroot, dst, &dstfile, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) goto copyerr;
+
+ do {
+ datasz = remains > bufSz ? bufSz : remains;
+ res =FileRead(srcfile, data, &datasz, NULL);
+ if (EFI_ERROR(res)) goto copyerr;
+ res = FileWrite(dstfile, data, &datasz, NULL);
+ if (EFI_ERROR(res)) goto copyerr;
+ remains -= datasz;
+ } while (remains > 0);
+
+copyerr:
+ MEM_FREE(data);
+ FileClose(srcfile);
+ FileClose(dstfile);
+ return res;
+}
diff --git a/Library/CommonLib/EfiMem.c b/Library/CommonLib/EfiMem.c
new file mode 100644
index 0000000..d9386c0
--- /dev/null
+++ b/Library/CommonLib/EfiMem.c
@@ -0,0 +1,74 @@
+/** @file
+EFI memory helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "Library/CommonLib.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// Memory procedures wrappers
+//////////////////////////////////////////////////////////////////////////
+
+VOID*
+MemAlloc(
+ IN UINTN size
+ ) {
+ return AllocateZeroPool(size);
+}
+
+VOID*
+MemRealloc(
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ ) {
+ return ReallocatePool(OldSize, NewSize, OldBuffer);
+}
+
+VOID
+MemFree(
+ IN VOID* ptr
+ ) {
+ if(ptr != NULL) FreePool(ptr);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Memory mapped IO
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+PrepareMemory(
+ IN UINTN address,
+ IN UINTN len,
+ OUT VOID** mem)
+{
+ EFI_STATUS status;
+ EFI_PHYSICAL_ADDRESS ptr;
+ VOID* buf;
+ UINTN pages;
+ pages = ((len & ~0x0FFF) + 0x1000) >> 12;
+ ptr = address & ~0x0FFF;
+// OUT_PRINT(L"mem try %0x, %0x\n", pages, (UINTN)ptr);
+ status = gBS->AllocatePages(AllocateAddress, EfiMemoryMappedIO, pages, &ptr);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+ buf = (void*)(UINTN)ptr;
+ SetMem(buf, pages << 12, 0);
+ *mem = buf;
+ return status;
+}
diff --git a/Library/CommonLib/EfiTouch.c b/Library/CommonLib/EfiTouch.c
new file mode 100644
index 0000000..9009f82
--- /dev/null
+++ b/Library/CommonLib/EfiTouch.c
@@ -0,0 +1,47 @@
+/** @file
+EFI touch/absolute pointer helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/AbsolutePointer.h>
+
+EFI_HANDLE* gTouchHandles = NULL;
+UINTN gTouchCount = 0;
+int gTouchSimulate = 0;
+UINT32 gTouchSimulateStep = 1;
+
+EFI_ABSOLUTE_POINTER_PROTOCOL* gTouchPointer = NULL;
+
+EFI_STATUS
+InitTouch() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiAbsolutePointerProtocolGuid, 0, &gTouchHandles, &gTouchCount);
+ if (gTouchCount > 0) {
+ TouchGetIO(gTouchHandles[gTouchCount - 1], &gTouchPointer);
+ }
+ return res;
+}
+
+
+EFI_STATUS
+TouchGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_ABSOLUTE_POINTER_PROTOCOL** io
+ ) {
+ if (!io) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gBS->HandleProtocol(Handle, &gEfiAbsolutePointerProtocolGuid, (VOID**)io);
+}
+
diff --git a/Library/CommonLib/EfiUsb.c b/Library/CommonLib/EfiUsb.c
new file mode 100644
index 0000000..b5bdac5
--- /dev/null
+++ b/Library/CommonLib/EfiUsb.c
@@ -0,0 +1,88 @@
+/** @file
+EFI USB helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/UsbIo.h>
+
+EFI_HANDLE* gUSBHandles = NULL;
+UINTN gUSBCount = 0;
+
+EFI_STATUS
+InitUsb() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiUsbIoProtocolGuid, 0, &gUSBHandles, &gUSBCount);
+ return res;
+}
+
+EFI_STATUS
+UsbGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo
+ ) {
+ if (!UsbIo) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gBS->HandleProtocol(Handle, &gEfiUsbIoProtocolGuid, (VOID**)UsbIo);
+}
+
+EFI_STATUS
+UsbGetIOwithDescriptor(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo,
+ OUT EFI_USB_DEVICE_DESCRIPTOR* UsbDescriptor
+ ) {
+ EFI_STATUS res;
+ if (!UsbIo || !UsbDescriptor) {
+ return EFI_INVALID_PARAMETER;
+ }
+ res = UsbGetIO(Handle, UsbIo);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return (*UsbIo)->UsbGetDeviceDescriptor(*UsbIo, UsbDescriptor);
+}
+
+EFI_STATUS
+UsbGetId(
+ IN EFI_HANDLE Handle,
+ OUT CHAR8** id
+ )
+{
+ EFI_STATUS res;
+ EFI_USB_IO_PROTOCOL *usbIO = NULL;
+ EFI_USB_DEVICE_DESCRIPTOR usbDescriptor;
+ CHAR16* serial = NULL;
+ CHAR8* buff;
+ UINTN len;
+ res = UsbGetIOwithDescriptor(Handle, &usbIO, &usbDescriptor);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+// Print(L" %02x ", (UINTN)usbDescriptor.StrSerialNumber);
+ res = usbIO->UsbGetStringDescriptor(usbIO, 0x409, usbDescriptor.StrSerialNumber, &serial);
+ if (!EFI_ERROR(res)) {
+ len = 11 + StrLen(serial);
+ buff = (CHAR8*)MEM_ALLOC(len);
+ AsciiSPrint(buff, len, "%04x_%04x_%s", usbDescriptor.IdVendor, usbDescriptor.IdProduct, serial);
+ } else {
+// Print(L" %04x %r ", res, res);
+ len = 10;
+ buff = (CHAR8*)MEM_ALLOC(len);
+ AsciiSPrint(buff, len, "%04x_%04x", usbDescriptor.IdVendor, usbDescriptor.IdProduct);
+ }
+ *id = buff;
+ return EFI_SUCCESS;
+}
diff --git a/Library/CommonLib/EfiVar.c b/Library/CommonLib/EfiVar.c
new file mode 100644
index 0000000..2a6e59e
--- /dev/null
+++ b/Library/CommonLib/EfiVar.c
@@ -0,0 +1,228 @@
+/** @file
+EFI firmware variable helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+
+#include <Uefi.h>
+#include <Guid/GlobalVariable.h>
+#include <Protocol/DevicePath.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Efi variables
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiGetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ OUT VOID** varValue,
+ OUT UINTN* varSize,
+ OUT UINT32* varAttr
+ ) {
+ EFI_STATUS Status;
+ CHAR8 *varData = NULL;
+ if (varSize == NULL) return EFI_INVALID_PARAMETER;
+ *varSize = 0;
+ if (varGuid == NULL) varGuid = &gEfiDcsVariableGuid;
+ Status = gST->RuntimeServices->GetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varData);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ varData = MEM_ALLOC(*varSize);
+ if (varData == NULL) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ Status = gST->RuntimeServices->GetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varData);
+ *varValue = varData;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+EfiSetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ IN VOID* varValue,
+ IN UINTN varSize,
+ IN UINT32 varAttr
+ ) {
+ EFI_STATUS Status;
+ if (varGuid == NULL) varGuid = &gEfiDcsVariableGuid;
+ Status = gST->RuntimeServices->SetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varValue);
+ return Status;
+}
+
+EFI_STATUS
+BootOrderInsert(
+ IN CHAR16 *OrderVarName,
+ IN UINTN index,
+ UINT16 value)
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT16* varBootOrderNew;
+ UINT16* varBootOrder;
+ UINTN varBootOrderSize;
+ UINT32 varBootOrderAttr;
+ UINTN BootOrderCount;
+ UINTN i;
+ UINTN j;
+ res = EfiGetVar(OrderVarName, &gEfiGlobalVariableGuid, &varBootOrder, &varBootOrderSize, &varBootOrderAttr);
+ if (EFI_ERROR(res)) return res;
+ BootOrderCount = varBootOrderSize / sizeof(UINT16);
+ varBootOrderNew = MEM_ALLOC((BootOrderCount + 1) * sizeof(UINT16));
+ if (BootOrderCount < index) index = BootOrderCount - 1;
+ for (j = 0, i = 0; i < BootOrderCount; ++i) {
+ if (j == index) {
+ varBootOrderNew[j] = value;
+ j++;
+ }
+ if (varBootOrder[i] == value) {
+ continue;
+ }
+ varBootOrderNew[j] = varBootOrder[i];
+ ++j;
+ }
+ BootOrderCount = j;
+
+ res = EfiSetVar(OrderVarName, &gEfiGlobalVariableGuid,
+ varBootOrderNew, BootOrderCount * sizeof(UINT16),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ MEM_FREE(varBootOrderNew);
+ MEM_FREE(varBootOrder);
+ return res;
+}
+
+EFI_STATUS
+BootOrderRemove(
+ IN CHAR16 *OrderVarName,
+ UINT16 value)
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT16* varBootOrderNew;
+ UINT16* varBootOrder;
+ UINTN varBootOrderSize;
+ UINT32 varBootOrderAttr;
+ UINTN BootOrderCount;
+ UINTN i;
+ UINTN j;
+
+ res = EfiGetVar(OrderVarName, &gEfiGlobalVariableGuid, &varBootOrder, &varBootOrderSize, &varBootOrderAttr);
+ if (EFI_ERROR(res)) return res;
+ BootOrderCount = varBootOrderSize / sizeof(UINT16);
+ varBootOrderNew = MEM_ALLOC((BootOrderCount + 1) * sizeof(UINT16));
+ for (j = 0, i = 0; i < BootOrderCount; ++i) {
+ if (varBootOrder[i] == value) {
+ continue;
+ }
+ varBootOrderNew[j] = varBootOrder[i];
+ ++j;
+ }
+ BootOrderCount = j;
+
+ res = EfiSetVar(OrderVarName, &gEfiGlobalVariableGuid,
+ varBootOrderNew, BootOrderCount * sizeof(UINT16),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+
+ MEM_FREE(varBootOrderNew);
+ MEM_FREE(varBootOrder);
+ return res;
+}
+
+EFI_STATUS
+BootMenuItemRemove(
+ IN CHAR16 *VarName
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ res = EfiSetVar(
+ VarName, &gEfiGlobalVariableGuid,
+ NULL, 0,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ return res;
+}
+
+EFI_STATUS
+BootMenuItemCreate(
+ IN CHAR16 *VarName,
+ IN CHAR16 *Desc,
+ IN EFI_HANDLE volumeHandle,
+ IN CHAR16 *Path,
+ IN BOOLEAN Reduced
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT8* varBoot;
+ UINT8* TempByteBuffer;
+ UINTN DescSize;
+ UINTN FilePathSize;
+ EFI_DEVICE_PATH_PROTOCOL* DevPath;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL* FileNode;
+ EFI_DEVICE_PATH_PROTOCOL* FilePath;
+
+ // Prepare
+ DevicePath = DevicePathFromHandle(volumeHandle);
+ if (Reduced) {
+ DevPath = DevicePath;
+ while (!IsDevicePathEnd(DevPath)) {
+ if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
+ (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
+
+ //
+ // If we find it use it instead
+ //
+ DevicePath = DevPath;
+ break;
+ }
+ DevPath = NextDevicePathNode(DevPath);
+ }
+ }
+ //
+ // append the file
+ //
+ FileNode = FileDevicePath(NULL, Path);
+ FilePath = AppendDevicePath(DevicePath, FileNode);
+ FreePool(FileNode);
+ //
+ // Add the option
+ //
+ DescSize = StrSize(Desc);
+ FilePathSize = GetDevicePathSize(FilePath);
+
+ varBoot = MEM_ALLOC(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);
+ if (varBoot != NULL) {
+ TempByteBuffer = varBoot;
+ *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
+ TempByteBuffer += sizeof(UINT32);
+
+ *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
+ TempByteBuffer += sizeof(UINT16);
+
+ CopyMem(TempByteBuffer, Desc, DescSize);
+ TempByteBuffer += DescSize;
+ CopyMem(TempByteBuffer, FilePath, FilePathSize);
+
+ res = EfiSetVar(VarName, &gEfiGlobalVariableGuid,
+ varBoot, sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ }
+ else {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ MEM_FREE(varBoot);
+ return res;
+}
diff --git a/Library/CommonLib/IA32/EfiCpuHalt.asm b/Library/CommonLib/IA32/EfiCpuHalt.asm
new file mode 100644
index 0000000..3c5bb0d
--- /dev/null
+++ b/Library/CommonLib/IA32/EfiCpuHalt.asm
@@ -0,0 +1,19 @@
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; CpuHalt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiCpuHalt PROC
+ cli
+l: hlt
+ jmp l
+ ret
+EfiCpuHalt ENDP
+
+ END
diff --git a/Library/CommonLib/X64/EfiCpuHalt.asm b/Library/CommonLib/X64/EfiCpuHalt.asm
new file mode 100644
index 0000000..7893234
--- /dev/null
+++ b/Library/CommonLib/X64/EfiCpuHalt.asm
@@ -0,0 +1,17 @@
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; CpuHalt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiCpuHalt PROC
+ cli
+l: hlt
+ jmp l
+ ret
+EfiCpuHalt ENDP
+
+ END
diff --git a/Library/DcsCfgLib/DcsCfgLib.inf b/Library/DcsCfgLib/DcsCfgLib.inf
new file mode 100644
index 0000000..8607cb4
--- /dev/null
+++ b/Library/DcsCfgLib/DcsCfgLib.inf
@@ -0,0 +1,80 @@
+## @file
+# Library for DCS configuration
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsCfgLib
+ MODULE_UNI_FILE = DcsCfgLib.uni
+ FILE_GUID = 3E61F9E0-0844-44F2-A177-A72FE81D6F07
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DcsCfgLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+GptEdit.c
+DcsRandom.c
+
+[Sources.X64]
+
+[Sources.IA32]
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ RngLib
+
+[Protocols]
+
+
+[BuildOptions.IA32]
+DEBUG_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /FAcs /D_UEFI
+RELEASE_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /FAcs /D_UEFI
+NOOPT_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /Od /FAcs /D_UEFI
+
+DEBUG_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /FAcs /D_UEFI
+RELEASE_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /FAcs /D_UEFI
+NOOPT_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /Od /FAcs /D_UEFI
+
+RELEASE_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+DEBUG_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+NOOPT_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+
+RELEASE_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+DEBUG_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+NOOPT_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+
+[BuildOptions.X64]
+DEBUG_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /D_UEFI
+RELEASE_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /D_UEFI
+NOOPT_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od /D_UEFI
+
+DEBUG_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /D_UEFI
+RELEASE_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /D_UEFI
+NOOPT_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od /D_UEFI
+
+RELEASE_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+DEBUG_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+NOOPT_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+
+RELEASE_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+DEBUG_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+NOOPT_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
diff --git a/Library/DcsCfgLib/DcsRandom.c b/Library/DcsCfgLib/DcsRandom.c
new file mode 100644
index 0000000..a269a46
--- /dev/null
+++ b/Library/DcsCfgLib/DcsRandom.c
@@ -0,0 +1,460 @@
+/** @file
+Random number generators for DCS
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+
+!NOTE: Very simple! Need to select several sources of random like user input or other.
+**/
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/CommonLib.h>
+#include <Library/RngLib.h>
+#include <Library/DcsCfgLib.h>
+
+#include <common/Pkcs5.h>
+#include <crypto/sha2.h>
+
+DCS_RND* gRnd = NULL;
+
+//////////////////////////////////////////////////////////////////////////
+// Random data from file
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+RndFilePrepare(
+ IN DCS_RND* rnd
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ if (rnd != NULL && rnd->Type == RndTypeFile && rnd->State.File.Data != NULL) {
+ rnd->State.File.Pos = 0;
+ res = EFI_SUCCESS;
+ }
+ return res;
+}
+
+EFI_STATUS
+RndFileGetBytes(
+ IN DCS_RND *rnd,
+ OUT UINT8 *buf,
+ IN UINTN len)
+{
+ UINTN i;
+ if (rnd != NULL && rnd->Type == RndTypeFile && rnd->State.File.Data != NULL) {
+ for (i = 0; i < len; i++, rnd->State.File.Pos++) {
+ if (rnd->State.File.Pos >= rnd->State.File.Size) {
+ rnd->State.File.Pos = 0;
+ }
+ buf[i] = rnd->State.File.Data[rnd->State.File.Pos];
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RndFileInit(
+ IN DCS_RND* rnd,
+ IN VOID* Context
+ )
+{
+ EFI_STATUS res = EFI_NOT_FOUND;
+ ZeroMem(rnd, sizeof(DCS_RND));
+ rnd->Type = RndTypeFile;
+ rnd->GetBytes = RndFileGetBytes;
+ rnd->Prepare = RndFilePrepare;
+ if (Context != NULL) {
+ res = FileLoad(NULL, (CHAR16*)Context, &rnd->State.File.Data, &rnd->State.File.Size);
+ if (!EFI_ERROR(res)) {
+ return rnd->Prepare(rnd);
+ }
+ }
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Random data from CPU RDRAND
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+RndRDRandPrepare(
+ IN DCS_RND* rnd
+ )
+{
+ UINT64 rndTmp;
+ if (rnd != NULL && rnd->Type == RndTypeRDRand) {
+ if (GetRandomNumber64((UINT64*)&rndTmp)) {
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndRDRandGetBytes(
+ IN DCS_RND *rnd,
+ OUT UINT8 *buf,
+ IN UINTN len)
+{
+ UINT8 tmpRnd[8];
+ UINTN i = 0;
+ UINTN j = 0;
+ if (rnd != NULL && rnd->Type == RndTypeRDRand) {
+ for (i = 0; i < len; ++i, ++j) {
+ j &= 7;
+ if (j == 0) {
+ if (!GetRandomNumber64((UINT64*)tmpRnd)) return EFI_NOT_READY;
+ }
+ buf[i] = tmpRnd[j];
+ }
+ } else {
+ return EFI_NOT_READY;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RndRDRandInit(
+ IN DCS_RND* rnd,
+ IN VOID* Context
+ )
+{
+ ZeroMem(rnd, sizeof(DCS_RND));
+ rnd->Type = RndTypeRDRand;
+ rnd->GetBytes = RndRDRandGetBytes;
+ rnd->Prepare = RndRDRandPrepare;
+ return rnd->Prepare(rnd);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// DRBG HMAC (SHA512) (NIST SP 800-90A) (simplified)
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+HmacSha512(
+ IN UINT8 *k, /* secret key */
+ OUT UINT8 *out, /* output buffer */
+ ...
+ )
+{
+ sha512_ctx ctx;
+ char inner[SHA512_DIGEST_SIZE], outer[SHA512_DIGEST_SIZE];
+ char key[SHA512_DIGEST_SIZE];
+ char buf[SHA512_BLOCK_SIZE];
+ int32 i;
+ int32 lk = SHA512_DIGEST_SIZE; /* length of the key in bytes */
+ VA_LIST args;
+ UINT8* data;
+ UINTN len;
+
+ /**** Inner Digest ****/
+ sha512_begin(&ctx);
+
+ /* Pad the key for inner digest */
+ for (i = 0; i < lk; ++i)
+ buf[i] = (char)(k[i] ^ 0x36);
+ for (i = lk; i < SHA512_BLOCK_SIZE; ++i)
+ buf[i] = 0x36;
+
+ sha512_hash((unsigned char *)buf, SHA512_BLOCK_SIZE, &ctx);
+
+ VA_START(args, out);
+ while ((data = VA_ARG(args, UINT8 *)) != NULL) {
+ len = VA_ARG(args, UINTN);
+ sha512_hash(data, (UINT32)len, &ctx);
+ }
+ VA_END(args);
+
+ sha512_end((unsigned char *)inner, &ctx);
+
+ /**** Outer Digest ****/
+
+ sha512_begin(&ctx);
+
+ for (i = 0; i < lk; ++i)
+ buf[i] = (char)(k[i] ^ 0x5C);
+ for (i = lk; i < SHA512_BLOCK_SIZE; ++i)
+ buf[i] = 0x5C;
+
+ sha512_hash((unsigned char *)buf, SHA512_BLOCK_SIZE, &ctx);
+ sha512_hash((unsigned char *)inner, SHA512_DIGEST_SIZE, &ctx);
+
+ sha512_end((unsigned char *)out, &ctx);
+
+ /* Prevent possible leaks. */
+ burn(&ctx, sizeof(ctx));
+ burn(outer, sizeof(outer));
+ burn(inner, sizeof(inner));
+ burn(buf, sizeof(buf));
+ burn(key, sizeof(key));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RndDtrmHmacSha512Update(
+ RND_DTRM_HMAC_SHA512_STATE *state,
+ UINT8 *seed,
+ UINTN seedLen,
+ BOOLEAN reseed
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ int i = 0;
+
+ if (!reseed)
+ {
+ /* 10.1.2.3 */
+ memset(state->V, 1, SHA512_DIGEST_SIZE);
+ memset(state->C, 0, SHA512_DIGEST_SIZE);
+ }
+
+ /* we execute two rounds of V/K massaging */
+ for (i = 2; 0 < i; i--)
+ {
+ /* first round uses 0x0, second 0x1 */
+ unsigned char prefix = 0;
+ if (1 == i)
+ prefix = 1;
+ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
+
+ res = HmacSha512(state->C, state->C,
+ state->V, SHA512_DIGEST_SIZE,
+ &prefix, 1,
+ seed, seedLen,
+ NULL
+ );
+ if (EFI_ERROR(res))
+ return res;
+
+ /* 10.1.2.2 step 2 and 5 -- HMAC for V */
+ res = HmacSha512(state->C, state->V,
+ state->V, SHA512_DIGEST_SIZE,
+ NULL);
+
+ if (EFI_ERROR(res))
+ return res;
+
+ /* 10.1.2.2 step 3 */
+ if (!seed || 0 == seedLen)
+ return res;
+ }
+ return EFI_SUCCESS;
+}
+
+/* generate function of HMAC DRBG as defined in 10.1.2.5 */
+EFI_STATUS
+RndDtrmHmacSha512Generate(
+ RND_DTRM_HMAC_SHA512_STATE *state,
+ OUT UINT8 *buf,
+ IN UINTN buflen,
+ IN UINT8 *seed,
+ IN UINTN seedLen
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN len = 0;
+
+ /* 10.1.2.5 step 2 */
+ if (seed && 0 < seedLen)
+ {
+ res = RndDtrmHmacSha512Update(state, seed, seedLen, 1);
+ if (EFI_ERROR(res))
+ return res;
+ }
+
+ while (len < buflen)
+ {
+ UINTN outlen = 0;
+ /* 10.1.2.5 step 4.1 */
+ res = HmacSha512(state->C, state->V,
+ state->V, SHA512_DIGEST_SIZE,
+ NULL
+ );
+ if (EFI_ERROR(res))
+ return res;
+ outlen = (SHA512_DIGEST_SIZE < (buflen - len)) ?
+ SHA512_DIGEST_SIZE : (buflen - len);
+
+ /* 10.1.2.5 step 4.2 */
+ memcpy(buf + len, state->V, outlen);
+ len += outlen;
+ }
+
+ /* 10.1.2.5 step 6 */
+ res = RndDtrmHmacSha512Update(state, seed, seedLen, 1);
+ return res;
+}
+
+EFI_STATUS
+RndDtrmHmacSha512Prepare(
+ IN DCS_RND* rnd
+ )
+{
+ if (rnd != NULL && rnd->Type == RndTypeDtrmHmacSha512) {
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndDtrmHmacSha512GetBytes(
+ IN DCS_RND* rnd,
+ UINT8 *buf,
+ UINTN len
+ )
+{
+ EFI_TIME seed;
+ EFI_STATUS res = EFI_NOT_READY;
+ RND_DTRM_HMAC_SHA512_STATE *state = &rnd->State.HMacSha512;
+ if (state->ReseedCtr < (1LL << 48)) {
+ gST->RuntimeServices->GetTime(&seed, NULL);
+ res = RndDtrmHmacSha512Generate(state, buf, len, (UINT8*)&seed, sizeof(seed));
+ state->ReseedCtr++;
+ }
+ return res;
+}
+
+EFI_STATUS
+RndDtrmHmacSha512Init(
+ IN DCS_RND* rnd,
+ IN VOID* Context
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ ZeroMem(rnd, sizeof(DCS_RND));
+ rnd->Type = RndTypeDtrmHmacSha512;
+ rnd->GetBytes = RndDtrmHmacSha512GetBytes;
+ rnd->Prepare = RndDtrmHmacSha512Prepare;
+
+ if (Context != NULL) {
+ CHAR16* type = (CHAR16*)Context;
+ if (*type == '_') {
+ UINT8* data;
+ UINTN size;
+ type++;
+ res = FileLoad(NULL, (CHAR16*)type, &data, &size);
+ if (EFI_ERROR(res)) {
+ rnd->Type = RndTypeNone;
+ }
+ res = RndDtrmHmacSha512Update(&rnd->State.HMacSha512, data, size, 0);
+ if (EFI_ERROR(res)) {
+ rnd->Type = RndTypeNone;
+ }
+ }
+ }
+ return rnd->Prepare(rnd);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Random API
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+RndInit(
+ IN UINTN rndType,
+ IN VOID* Context,
+ OUT DCS_RND **rnd)
+{
+ if (rnd != NULL) {
+ DCS_RND *rndTemp;
+ rndTemp = (DCS_RND*)MEM_ALLOC(sizeof(DCS_RND));
+ if (rndTemp != NULL) {
+ EFI_STATUS res = EFI_NOT_FOUND;
+ rndTemp->Type = (UINT32)rndType;
+ switch (rndType) {
+ case RndTypeFile:
+ res = RndFileInit(rndTemp, Context);
+ break;
+ case RndTypeRDRand:
+ res = RndRDRandInit(rndTemp, Context);
+ break;
+ case RndTypeDtrmHmacSha512:
+ res = RndDtrmHmacSha512Init(rndTemp, Context);
+ break;
+ }
+ if (EFI_ERROR(res)) {
+ MEM_FREE(rndTemp);
+ return res;
+ }
+ *rnd = rndTemp;
+ return res;
+ }
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndGetBytes(
+ UINT8 *buf,
+ UINTN len)
+{
+ if (gRnd != NULL) {
+ return gRnd->GetBytes(gRnd, buf, len);
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndPreapare()
+{
+ if (gRnd != NULL) {
+ return gRnd->Prepare(gRnd);
+ }
+ return EFI_NOT_READY;
+}
+
+UINT64 gRndHeaderSign = RND_HEADER_SIGN;
+
+EFI_STATUS
+RndSave(
+ IN DCS_RND *rnd,
+ OUT DCS_RND_SAVED **rndSaved
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ DCS_RND_SAVED *RndSaved;
+ UINT32 crc;
+ if (rnd != NULL && rndSaved != NULL && rnd->Type != RndTypeFile) {
+ RndSaved = MEM_ALLOC(sizeof(DCS_RND_SAVED));
+ if (RndSaved != NULL) {
+ RndSaved->Size = sizeof(DCS_RND_SAVED);
+ CopyMem(&RndSaved->State, &rnd->State, sizeof(DCS_RND_STATE));
+ RndSaved->Type = rnd->Type;
+ RndSaved->Sign = gRndHeaderSign;
+ gST->RuntimeServices->GetTime(&RndSaved->SavedAt, NULL);
+ res = gBS->CalculateCrc32(RndSaved, sizeof(DCS_RND_SAVED), &crc);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(RndSaved);
+ return res;
+ }
+ RndSaved->CRC = crc;
+ *rndSaved = RndSaved;
+ }
+ }
+ return res;
+}
+
+EFI_STATUS
+RndLoad(
+ IN DCS_RND_SAVED *rndSaved,
+ OUT DCS_RND **rndOut
+ ) {
+ EFI_STATUS res = EFI_SUCCESS;
+ UINT32 crc;
+ UINT32 crcSaved;
+
+ crcSaved = rndSaved->CRC;
+ rndSaved->CRC = 0;
+ res = gBS->CalculateCrc32(rndSaved, sizeof(DCS_RND_SAVED), &crc);
+ if (EFI_ERROR(res) || crc != crcSaved || rndSaved->Sign != gRndHeaderSign) {
+ return EFI_CRC_ERROR;
+ }
+ res = RndInit(rndSaved->Type, NULL, rndOut);
+ if (!EFI_ERROR(res)) {
+ CopyMem(&((*rndOut)->State), &rndSaved->State, sizeof(DCS_RND_STATE));
+ }
+ return res;
+}
diff --git a/Library/DcsCfgLib/GptEdit.c b/Library/DcsCfgLib/GptEdit.c
new file mode 100644
index 0000000..702ce5d
--- /dev/null
+++ b/Library/DcsCfgLib/GptEdit.c
@@ -0,0 +1,935 @@
+/** @file
+GPT actions
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Uefi/UefiGpt.h>
+#include <Guid/Gpt.h>
+
+#include <Library/CommonLib.h>
+#include <Library/DcsCfgLib.h>
+
+#include <common/Tcdefs.h>
+#include <BootCommon.h>
+
+EFI_GUID gEfiPartTypeMsReservedPartGuid = EFI_PART_TYPE_MS_RESERVED_PART_GUID;
+EFI_GUID gEfiPartTypeBasicDataPartGuid = EFI_PART_TYPE_BASIC_DATA_PART_GUID;
+EFI_GUID gEfiPartTypeMsRecoveryPartGuid = EFI_PART_TYPE_MS_RECOVERY_PART_GUID;
+
+UINT64 gDcsDiskEntryListHeaderID = DCS_DISK_ENTRY_LIST_HEADER_SIGN;
+UINT64 gDcsDiskEntryPwdCacheID = DCS_DEP_PWD_CACHE_SIGN;
+
+DCS_DISK_ENTRY_LIST *DeList = NULL;
+
+UINT8 *CryptoHeader = NULL;
+
+EFI_PARTITION_TABLE_HEADER *GptMainHdr = NULL;
+EFI_PARTITION_ENTRY *GptMainEntrys = NULL;
+EFI_PARTITION_TABLE_HEADER *GptAltHdr = NULL;
+EFI_PARTITION_ENTRY *GptAltEntrys = NULL;
+
+UINT32 DiskIdMbr = 0;
+EFI_GUID DiskIdGpt = EFI_PART_TYPE_UNUSED_GUID;
+DCS_DISK_ENTRY_DISKID DeDiskId;
+
+DCS_DEP_EXEC *DeExecParams = NULL;
+
+DCS_DEP_PWD_CACHE *DePwdCache = NULL;
+
+DCS_RND_SAVED *DeRndSaved;
+
+EFI_BLOCK_IO_PROTOCOL* BlockIo = NULL;
+CONST CHAR16* DcsDiskEntrysFileName = L"DcsDiskEntrys";
+
+EFI_PARTITION_ENTRY DcsHidePart;
+
+UINTN BootPartIdx;
+UINTN MirrorPartIdx;
+
+//////////////////////////////////////////////////////////////////////////
+// Partitions
+//////////////////////////////////////////////////////////////////////////
+
+
+/**
+Checks the CRC32 value in the table header.
+
+@param MaxSize Max Size limit
+@param Size The size of the table
+@param Hdr Table to check
+
+@return TRUE CRC Valid
+@return FALSE CRC Invalid
+
+**/
+BOOLEAN
+GptHeaderCheckCrcAltSize(
+ IN UINTN MaxSize,
+ IN UINTN Size,
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+{
+ UINT32 Crc;
+ UINT32 OrgCrc;
+ EFI_STATUS Status;
+
+ Crc = 0;
+
+ if (Size == 0) {
+ //
+ // If header size is 0 CRC will pass so return FALSE here
+ //
+ return FALSE;
+ }
+
+ if ((MaxSize != 0) && (Size > MaxSize)) {
+ return FALSE;
+ }
+ //
+ // clear old crc from header
+ //
+ OrgCrc = Hdr->CRC32;
+ Hdr->CRC32 = 0;
+
+ Status = gBS->CalculateCrc32((UINT8 *)Hdr, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+ //
+ // set results
+ //
+ Hdr->CRC32 = OrgCrc;
+
+ return (BOOLEAN)(OrgCrc == Crc);
+}
+
+/**
+Checks the CRC32 value in the table header.
+
+@param MaxSize Max Size limit
+@param Hdr Table to check
+
+@return TRUE CRC Valid
+@return FALSE CRC Invalid
+
+**/
+BOOLEAN
+GptHeaderCheckCrc(
+ IN UINTN MaxSize,
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+{
+ return GptHeaderCheckCrcAltSize(MaxSize, Hdr->HeaderSize, Hdr);
+}
+
+EFI_STATUS
+GptCheckEntryArray(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINTN Size;
+
+ Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
+ Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return EFI_CRC_ERROR;
+ }
+ Status = (PartHeader->PartitionEntryArrayCRC32 == Crc) ? EFI_SUCCESS : EFI_CRC_ERROR;
+ return Status;
+}
+
+EFI_STATUS
+GptUpdateCRC(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINTN Size;
+
+ Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
+ Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ PartHeader->PartitionEntryArrayCRC32 = Crc;
+ PartHeader->Header.CRC32 = 0;
+
+ Status = gBS->CalculateCrc32((UINT8 *)PartHeader, PartHeader->Header.HeaderSize, &Crc);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ PartHeader->Header.CRC32 = Crc;
+ return Status;
+}
+
+/**
+Read GPT
+Check if the CRC field in the Partition table header is valid
+for Partition entry array.
+
+@param[in] DiskIo Disk Io Protocol.
+@param[in] PartHeader Partition table header structure
+
+@retval EFI_SUCCESS the CRC is valid
+**/
+EFI_STATUS
+GptReadEntryArray(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ OUT EFI_PARTITION_ENTRY **Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Ptr;
+
+ //
+ // Read the EFI Partition Entries
+ //
+ Ptr = MEM_ALLOC(PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
+ if (Ptr == NULL) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Status = BlockIo->ReadBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ PartHeader->PartitionEntryLBA,
+ PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
+ Ptr
+ );
+ if (EFI_ERROR(Status)) {
+ MEM_FREE(Ptr);
+ return Status;
+ }
+
+ *Entrys = (EFI_PARTITION_ENTRY*)Ptr;
+ return GptCheckEntryArray(PartHeader, *Entrys);
+}
+
+EFI_STATUS
+GptReadHeader(
+ IN EFI_LBA HeaderLba,
+ OUT EFI_PARTITION_TABLE_HEADER **PartHeader
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINT32 BlockSize;
+ EFI_PARTITION_TABLE_HEADER *PartHdr;
+ UINT32 MediaId;
+
+ BlockSize = BlockIo->Media->BlockSize;
+ MediaId = BlockIo->Media->MediaId;
+ PartHdr = MEM_ALLOC(BlockSize);
+
+ res = BlockIo->ReadBlocks(BlockIo, MediaId, HeaderLba, BlockSize, PartHdr);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(PartHdr);
+ return res;
+ }
+
+ // Check header
+ if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
+ !GptHeaderCheckCrc(BlockSize, &PartHdr->Header) ||
+ PartHdr->MyLBA != HeaderLba ||
+ (PartHdr->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
+ ) {
+ MEM_FREE(PartHdr);
+ return EFI_CRC_ERROR;
+ }
+ *PartHeader = PartHdr;
+ return EFI_SUCCESS;
+}
+
+VOID
+GptPrint(
+ IN EFI_PARTITION_TABLE_HEADER *PartHdr,
+ IN EFI_PARTITION_ENTRY *Entrys
+ )
+{
+ EFI_PARTITION_ENTRY *Entry;
+ UINTN index;
+ if (PartHdr == NULL) {
+ ERR_PRINT(L"No GPT is loaded\n");
+ return;
+ }
+ Entry = Entrys;
+ for (index = 0; index < PartHdr->NumberOfPartitionEntries; ++index, ++Entry) {
+ if (CompareGuid(&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ continue;
+ }
+ OUT_PRINT(L"%H%02d%N I:%g T:%g [%lld, %lld] %s\n",
+ index,
+ &Entry->UniquePartitionGUID,
+ &Entry->PartitionTypeGUID,
+ Entry->StartingLBA,
+ Entry->EndingLBA,
+ &Entry->PartitionName
+ );
+ }
+}
+
+EFI_STATUS
+GptLoadFromDisk(
+ IN UINTN diskIdx
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN i;
+ InitBio();
+
+ BlockIo = EfiGetBlockIO(gBIOHandles[diskIdx]);
+ if (BlockIo == NULL) {
+ ERR_PRINT(L"Can't open device\n");
+ return EFI_NOT_FOUND;
+ }
+
+ res = GptReadHeader(1, &GptMainHdr);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Can't read main GPT header: %r\n", res);
+ goto error;
+ }
+
+ res = GptReadHeader(GptMainHdr->AlternateLBA, &GptAltHdr);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Can't read alt GPT header: %r\n", res);
+ goto error;
+ }
+
+ res = GptReadEntryArray(GptMainHdr, &GptMainEntrys);
+ // Read GPT
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Main GPT error: %r\n", res);
+ goto error;
+ }
+
+ res = GptReadEntryArray(GptAltHdr, &GptAltEntrys);
+ // Read GPT
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Alt GPT error: %r\n", res);
+ goto error;
+ }
+
+ CryptoHeader = MEM_ALLOC(512);
+ if (CryptoHeader == NULL) {
+ ERR_PRINT(L"Can't alloc CryptoHeader\n");
+ res = EFI_BUFFER_TOO_SMALL;
+ goto error;
+ }
+
+ // Load disk IDs
+ res = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0, 512, CryptoHeader);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Can't MBR \n");
+ goto error;
+ }
+
+ SetMem(&DeDiskId, sizeof(DeDiskId), 0);
+ DeDiskId.Type = DE_DISKID;
+ CopyMem(&DeDiskId.MbrID, &CryptoHeader[0x1b8], sizeof(DiskIdMbr));
+ CopyMem(&DeDiskId.GptID, &GptMainHdr->DiskGUID, sizeof(DiskIdGpt));
+
+ // Load crypto header
+ res = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 62, 512, CryptoHeader);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Can't read CryptoHeader\n");
+ goto error;
+ }
+
+ for (i = 0; i < GptMainHdr->NumberOfPartitionEntries; ++i) {
+ EFI_PARTITION_ENTRY *part;
+ part = &GptMainEntrys[i];
+ if (CompareMem(&gEfiPartTypeSystemPartGuid, &part->PartitionTypeGUID, sizeof(EFI_GUID)) == 0) {
+ CHAR16* defExec = L"\\EFI\\Microsoft\\Boot\\Bootmgfw.efi";
+ DeExecParams = MEM_ALLOC(sizeof(*DeExecParams));
+ ZeroMem(DeExecParams, sizeof(*DeExecParams));
+ CopyMem(&DeExecParams->ExecPartGuid, &part->UniquePartitionGUID, sizeof(EFI_GUID));
+ CopyMem(&DeExecParams->ExecCmd, defExec, (StrLen(defExec) + 1 ) * 2);
+ break;
+ }
+ }
+ return res;
+
+error:
+ MEM_FREE(GptMainHdr);
+ MEM_FREE(GptMainEntrys);
+ MEM_FREE(GptAltHdr);
+ MEM_FREE(GptAltEntrys);
+ MEM_FREE(CryptoHeader);
+ return res;
+}
+
+VOID
+DeListPrint() {
+ OUT_PRINT(L"Diskid %08x, %g\n", DeDiskId.MbrID, &DeDiskId.GptID);
+ if (DeExecParams != NULL) {
+ OUT_PRINT(L"Exec %g, %s\n", &DeExecParams->ExecPartGuid, &DeExecParams->ExecCmd);
+ }
+ if (DePwdCache != NULL) {
+ OUT_PRINT(L"PwdCache %d\n", DePwdCache->Count);
+ }
+ if (DeRndSaved != NULL) {
+ OUT_PRINT(L"Rnd %d\n", DeRndSaved->Type);
+ }
+ GptPrint(GptMainHdr, GptMainEntrys);
+}
+
+#define DeList_UPDATE_BEGIN(Data, DEType, Index, Len) \
+ if (Data != NULL) { \
+ DeData[Index] = Data; \
+ DeList->DE[Index].Type = DEType; \
+ DeList->DE[Index].Offset = Offset; \
+ DeList->DE[Index].Length = Len; \
+ Offset += ((Len + 511) >> 9) << 9;
+
+#define DeList_UPDATE_END \
+ }
+
+VOID
+DeListSaveToFile() {
+ EFI_STATUS res = EFI_SUCCESS;
+ UINT32 Offset;
+ VOID* DeData[DE_IDX_TOTAL];
+ UINT8* pad512buf = NULL;
+
+ ZeroMem(DeData, sizeof(DeData));
+
+ res = EFI_BUFFER_TOO_SMALL;
+ DeList = MEM_ALLOC(sizeof(*DeList));
+ if (DeList == NULL) {
+ ERR_PRINT(L"Can't alloc DeList\n");
+ goto error;
+ }
+
+ pad512buf = MEM_ALLOC(512);
+ if (pad512buf == NULL) {
+ ERR_PRINT(L"No memory\n");
+ goto error;
+ }
+
+ DeList->Signature = DCS_DISK_ENTRY_LIST_HEADER_SIGN;
+ DeList->HeaderSize = sizeof(*DeList);
+ DeList->Count = DE_IDX_TOTAL;
+ Offset = 0;
+
+ DeList_UPDATE_BEGIN(CryptoHeader, DE_Sectors, DE_IDX_CRYPTOHEADER, 512)
+ DeList->DE[DE_IDX_CRYPTOHEADER].Sectors.Start = 62 * 512;
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(DeList, DE_List, DE_IDX_LIST, 512)
+ DeList_UPDATE_END
+
+ CopyMem(&DeList->DE[DE_IDX_DISKID], &DeDiskId, sizeof(DeDiskId));
+
+ DeList_UPDATE_BEGIN(GptMainHdr, DE_Sectors, DE_IDX_MAINGPTHDR, 512)
+ DeList->DE[DE_IDX_MAINGPTHDR].Sectors.Start = GptMainHdr->MyLBA * 512;
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(GptMainEntrys, DE_Sectors, DE_IDX_MAINGPTENTRYS, GptMainHdr->NumberOfPartitionEntries * GptMainHdr->SizeOfPartitionEntry)
+ DeList->DE[DE_IDX_MAINGPTENTRYS].Sectors.Start = GptMainHdr->PartitionEntryLBA * 512;
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(GptAltHdr, DE_Sectors, DE_IDX_ALTGPTHDR, 512)
+ DeList->DE[DE_IDX_ALTGPTHDR].Sectors.Start = GptAltHdr->MyLBA * 512;
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(GptAltEntrys, DE_Sectors, DE_IDX_ALTGPTENTRYS, GptAltHdr->NumberOfPartitionEntries * GptAltHdr->SizeOfPartitionEntry)
+ DeList->DE[DE_IDX_ALTGPTENTRYS].Sectors.Start = GptAltHdr->PartitionEntryLBA * 512;
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(DeExecParams, DE_ExecParams, DE_IDX_EXEC, sizeof(*DeExecParams))
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(DePwdCache, DE_PwdCache, DE_IDX_PWDCACHE, sizeof(*DePwdCache))
+ DeList_UPDATE_END
+
+ DeList_UPDATE_BEGIN(DeRndSaved, DE_Rnd, DE_IDX_RND, sizeof(*DeRndSaved))
+ DeList_UPDATE_END
+
+ DeList->DataSize = Offset;
+ res = gBS->CalculateCrc32(DeList, 512, &DeList->CRC32);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"CRC: %r\n", res);
+ goto error;
+ }
+ {
+ EFI_FILE* file;
+ UINTN i;
+
+ FileDelete(NULL, (CHAR16*)DcsDiskEntrysFileName);
+ res = FileOpen(NULL, (CHAR16*)DcsDiskEntrysFileName, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE, 0);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"File: %r\n", res);
+ goto error;
+ }
+ for (i = 0; i < DeList->Count; ++i) {
+ if (DeData[i] != 0 && DeList->DE[i].Type != DE_DISKID) {
+ UINTN len;
+ UINTN pad;
+ len = (UINTN)DeList->DE[i].Length;
+ pad = (((len + 511) >> 9) << 9) - len;
+ res = FileWrite(file, DeData[i], &len, NULL);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ goto error;
+ }
+ if (pad > 0) {
+ res = FileWrite(file, pad512buf, &pad, NULL);
+ }
+ }
+ }
+ FileClose(file);
+ }
+
+error:
+ MEM_FREE(DeList);
+ MEM_FREE(pad512buf);
+}
+
+EFI_STATUS
+DeListZero() {
+ if (DePwdCache != NULL) {
+ DePwdCache = AskConfirm("Remove passwords cache?", 1) ? NULL : DePwdCache;
+ }
+ if (DeExecParams != NULL) {
+ DeExecParams = AskConfirm("Remove exec?", 1) ? NULL : DeExecParams;
+ }
+ if (DeRndSaved != NULL) {
+ DeRndSaved = AskConfirm("Remove rnd?", 1) ? NULL : DeRndSaved;
+ }
+ if (GptMainHdr != NULL) {
+ if (AskConfirm("Remove GPT?", 1)) {
+ GptMainHdr = NULL;
+ GptMainEntrys = NULL;
+ GptAltHdr = NULL;
+ GptAltEntrys = NULL;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeListParseSaved(
+ IN UINT8 *DeBuffer
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ CryptoHeader = DeBuffer;
+ DeList = (DCS_DISK_ENTRY_LIST*)(DeBuffer + 512);
+ CopyMem(&DeDiskId, &DeList->DE[DE_IDX_DISKID], sizeof(DeDiskId));
+
+ if (DeList->DE[DE_IDX_EXEC].Type == DE_ExecParams) {
+ DeExecParams = (DCS_DEP_EXEC *)(DeBuffer + DeList->DE[DE_IDX_EXEC].Offset);
+ }
+
+ if (DeList->DE[DE_IDX_RND].Type == DE_Rnd) {
+ DeRndSaved = (DCS_RND_SAVED *)(DeBuffer + DeList->DE[DE_IDX_RND].Offset);
+ if ((UINTN)DeList->DE[DE_IDX_RND].Length != sizeof(*DeRndSaved)) {
+ return EFI_CRC_ERROR;
+ }
+ }
+
+ if (DeList->DE[DE_IDX_PWDCACHE].Type == DE_PwdCache) {
+ UINT32 crc = 0;
+ UINT32 crcSaved = 0;
+ DePwdCache = (DCS_DEP_PWD_CACHE*)(DeBuffer + DeList->DE[DE_IDX_PWDCACHE].Offset);
+ if (DePwdCache->Sign != gDcsDiskEntryPwdCacheID) {
+ return EFI_CRC_ERROR;
+ }
+ crcSaved = DePwdCache->CRC;
+ DePwdCache->CRC = 0;
+ res = gBS->CalculateCrc32(DePwdCache, sizeof(*DePwdCache), &crc);
+ if (crc != crcSaved) {
+ ERR_PRINT(L"Pwd cache crc\n");
+ return EFI_CRC_ERROR;
+ }
+ DePwdCache->CRC = crcSaved;
+ }
+
+ if (DeList->DE[DE_IDX_MAINGPTHDR].Type == DE_Sectors) {
+ GptMainHdr = (EFI_PARTITION_TABLE_HEADER*)(DeBuffer + DeList->DE[DE_IDX_MAINGPTHDR].Sectors.Offset);
+ if ((GptMainHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
+ !GptHeaderCheckCrc(512, &GptMainHdr->Header) ||
+ (DeList->DE[DE_IDX_MAINGPTHDR].Sectors.Start >> 9) != GptMainHdr->MyLBA ||
+ (GptMainHdr->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))) {
+ res = EFI_CRC_ERROR;
+ ERR_PRINT(L"Main GPT header: %r\n", res);
+ return res;
+ }
+ }
+
+ if (DeList->DE[DE_IDX_MAINGPTENTRYS].Type == DE_Sectors) {
+ GptMainEntrys = (EFI_PARTITION_ENTRY*)(DeBuffer + DeList->DE[DE_IDX_MAINGPTENTRYS].Sectors.Offset);
+ res = GptCheckEntryArray(GptMainHdr, GptMainEntrys);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Main GPT: %r\n", res);
+ return res;
+ }
+ }
+
+ if (DeList->DE[DE_IDX_ALTGPTHDR].Type == DE_Sectors) {
+ GptAltHdr = (EFI_PARTITION_TABLE_HEADER*)(DeBuffer + DeList->DE[DE_IDX_ALTGPTHDR].Sectors.Offset);
+ if ((GptAltHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
+ !GptHeaderCheckCrc(512, &GptAltHdr->Header) ||
+ (DeList->DE[DE_IDX_ALTGPTHDR].Sectors.Start >> 9) != GptAltHdr->MyLBA ||
+ (GptAltHdr->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))) {
+ res = EFI_CRC_ERROR;
+ ERR_PRINT(L"Alt GPT header: %r\n", res);
+ return res;
+ }
+ }
+
+ if (DeList->DE[DE_IDX_ALTGPTENTRYS].Type == DE_Sectors) {
+ GptAltEntrys = (EFI_PARTITION_ENTRY*)(DeBuffer + DeList->DE[DE_IDX_ALTGPTENTRYS].Sectors.Offset);
+ res = GptCheckEntryArray(GptAltHdr, GptAltEntrys);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Alt GPT: %r\n", res);
+ return res;
+ }
+ }
+
+ if (GptMainEntrys != NULL && GptAltEntrys != NULL && GptMainHdr != NULL) {
+ if (CompareMem(GptMainEntrys, GptAltEntrys, GptMainHdr->NumberOfPartitionEntries * GptMainHdr->SizeOfPartitionEntry) != 0) {
+ ERR_PRINT(L"Alt GPT != Main GPT\n", );
+ return EFI_CRC_ERROR;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeListLoadFromFile()
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN len;
+ UINT8 *DeBuffer;
+
+ InitFS();
+ res = FileLoad(NULL, (CHAR16*)DcsDiskEntrysFileName, &DeBuffer, &len);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Load: %r\n", res);
+ return res;
+ }
+ return DeListParseSaved(DeBuffer);
+}
+
+EFI_STATUS
+DeListApplySectorsToDisk(
+ IN UINTN diskIdx
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN i;
+ UINT8 *Mbr;
+
+ InitBio();
+ InitFS();
+ BlockIo = EfiGetBlockIO(gBIOHandles[diskIdx]);
+ if (BlockIo == NULL) {
+ ERR_PRINT(L"Can't open device\n");
+ return EFI_NOT_FOUND;
+ }
+
+ // Compare MBR disk ID
+ Mbr = MEM_ALLOC(512);
+ if (Mbr == NULL) {
+ ERR_PRINT(L"Can't load MBR\n");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ res = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0, 512, Mbr);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Read MBR: %r\n", res);
+ MEM_FREE(Mbr);
+ return res;
+ }
+
+ if (CompareMem(Mbr + 0x1b8, &DeDiskId.MbrID, sizeof(UINT32)) != 0) {
+ ERR_PRINT(L"Disk MBR ID %08x != %08x \n", *((UINT32*)(Mbr + 0x1b8)), DeDiskId.MbrID);
+ MEM_FREE(Mbr);
+ return res;
+ }
+ MEM_FREE(Mbr);
+
+ // Save sectors
+ for (i = 0; i < DeList->Count; ++i) {
+ if (DeList->DE[i].Type == DE_Sectors) {
+ OUT_PRINT(L"%d Write: %lld, %lld\n", i, DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Length);
+ res = BlockIo->WriteBlocks(BlockIo, BlockIo->Media->MediaId,
+ DeList->DE[i].Sectors.Start >> 9,
+ (UINTN)DeList->DE[i].Sectors.Length,
+ CryptoHeader + DeList->DE[i].Sectors.Offset);
+ }
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Write: %r\n", res);
+ return res;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GptSyncMainAlt() {
+ EFI_STATUS res = EFI_SUCCESS;
+ // Duplicate parts array
+ CopyMem(GptAltEntrys, GptMainEntrys, GptMainHdr->NumberOfPartitionEntries * GptMainHdr->SizeOfPartitionEntry);
+
+ res = GptUpdateCRC(GptMainHdr, GptMainEntrys);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Main CRC: %r\n", res);
+ return res;
+ }
+ GptUpdateCRC(GptAltHdr, GptAltEntrys);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Alt CRC: %r\n", res);
+ return res;
+ }
+ return res;
+}
+
+VOID
+GptSqueze() {
+ UINTN i = 0;
+ UINTN emptyIdx = 0;
+ UINTN count;
+ count = GptMainHdr->NumberOfPartitionEntries;
+ while (i < count) {
+ if (CompareGuid(&GptMainEntrys[i].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ SetMem(&GptMainEntrys[i], sizeof(*GptMainEntrys), 0);
+ ++i;
+ continue;
+ }
+ else {
+ if (emptyIdx != i) {
+ CopyMem(&GptMainEntrys[emptyIdx], &GptMainEntrys[i], sizeof(*GptMainEntrys) * (count - i));
+ SetMem(&GptMainEntrys[i], sizeof(*GptMainEntrys), 0);
+ }
+ ++emptyIdx;
+ i = emptyIdx;
+ }
+ }
+}
+
+VOID
+GptSort() {
+ UINTN i = 0;
+ UINTN j = 0;
+ UINTN n = 0;
+ UINTN count;
+ EFI_PARTITION_ENTRY tmp;
+ BOOLEAN swapped = TRUE;
+ count = GptMainHdr->NumberOfPartitionEntries;
+
+ while (n < count) {
+ if (CompareGuid(&GptMainEntrys[n].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ break;
+ }
+ ++n;
+ }
+
+ while (swapped) {
+ swapped = FALSE;
+ j++;
+ for (i = 0; i < n - j; ++i) {
+ if (GptMainEntrys[i].StartingLBA > GptMainEntrys[i + 1].StartingLBA) {
+ CopyMem(&tmp, &GptMainEntrys[i], sizeof(tmp));
+ CopyMem(&GptMainEntrys[i], &GptMainEntrys[i + 1], sizeof(tmp));
+ CopyMem(&GptMainEntrys[i + 1], &tmp, sizeof(tmp));
+ swapped = TRUE;
+ }
+ }
+ }
+}
+
+// Checks if two regions overlap (borders are parts of regions)
+BOOLEAN
+IsRegionOverlap(UINT64 start1, UINT64 end1, UINT64 start2, UINT64 end2) {
+ return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
+}
+
+VOID
+GptHideParts() {
+ UINTN count;
+ UINTN n;
+ BOOLEAN set = FALSE;
+ count = GptMainHdr->NumberOfPartitionEntries;
+
+ for (n = 0; n < count; ++n) {
+ if (CompareGuid(&GptMainEntrys[n].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ continue;
+ }
+ if (IsRegionOverlap(
+ GptMainEntrys[n].StartingLBA, GptMainEntrys[n].EndingLBA,
+ DcsHidePart.StartingLBA, DcsHidePart.EndingLBA)) {
+ if (set) {
+ SetMem(&GptMainEntrys[n], sizeof(*GptMainEntrys), 0);
+ }
+ else {
+ set = TRUE;
+ CopyMem(&GptMainEntrys[n], &DcsHidePart, sizeof(*GptMainEntrys));
+ }
+ }
+ }
+ GptSqueze();
+ GptSort();
+ GptSyncMainAlt();
+}
+
+BOOLEAN
+GptAskGUID(
+ IN char* prompt,
+ IN OUT EFI_GUID* guid)
+{
+ CHAR8 buf[128];
+ UINTN len = 0;
+ EFI_GUID result;
+ BOOLEAN ok = TRUE;
+ OUT_PRINT(L"[%g] %a", guid, prompt);
+
+ // (msr, data, oem, efi, del or guid)
+ GetLine(&len, NULL, buf, sizeof(buf), 1);
+ if (AsciiStrCmp(buf, "msr") == 0) {
+ CopyMem(guid, &gEfiPartTypeMsReservedPartGuid, sizeof(EFI_GUID));
+ }
+ else if (AsciiStrCmp(buf, "data") == 0) {
+ CopyMem(guid, &gEfiPartTypeBasicDataPartGuid, sizeof(EFI_GUID));
+ }
+ else if (AsciiStrCmp(buf, "wre") == 0) {
+ CopyMem(guid, &gEfiPartTypeMsRecoveryPartGuid, sizeof(EFI_GUID));
+ }
+ else if (AsciiStrCmp(buf, "efi") == 0) {
+ CopyMem(guid, &gEfiPartTypeSystemPartGuid, sizeof(EFI_GUID));
+ }
+ else if (AsciiStrCmp(buf, "del") == 0) {
+ CopyMem(guid, &gEfiPartTypeUnusedGuid, sizeof(EFI_GUID));
+ }
+ else if (len == 0) {
+ ok = TRUE;
+ }
+ else {
+ ok = AsciiStrToGuid(&result, buf);
+ if (ok) {
+ CopyMem(guid, &result, sizeof(result));
+ }
+ }
+ return ok;
+}
+
+EFI_STATUS
+DeListExecEdit()
+{
+ UINTN len;
+ UINTN i;
+ CHAR16 execCmd[FIELD_SIZEOF(DCS_DEP_EXEC, ExecCmd)];
+ if (DeExecParams == NULL) {
+ DeExecParams = MEM_ALLOC(sizeof(*DeExecParams));
+ }
+ OUT_PRINT(L"Exec %g, %s\n", &DeExecParams->ExecPartGuid, &DeExecParams->ExecCmd);
+ if (GptMainHdr != NULL) {
+ for (i = 0; i < GptMainHdr->NumberOfPartitionEntries; ++i) {
+ EFI_PARTITION_ENTRY *part;
+ part = &GptMainEntrys[i];
+ if (CompareMem(&gEfiPartTypeSystemPartGuid, &part->PartitionTypeGUID, sizeof(EFI_GUID)) == 0) {
+ if (CompareMem(&DeExecParams->ExecPartGuid, &part->UniquePartitionGUID, sizeof(EFI_GUID)) != 0) {
+ OUT_PRINT(L"EFI partition missmatched, updated");
+ CopyMem(&DeExecParams->ExecPartGuid, &part->UniquePartitionGUID, sizeof(EFI_GUID));
+ }
+ break;
+ }
+ }
+ }
+ while (!GptAskGUID("\n\r:",(EFI_GUID*) &DeExecParams->ExecPartGuid));
+ OUT_PRINT(L"[%s]\n\r:", &DeExecParams->ExecCmd);
+ GetLine(&len, execCmd, NULL, sizeof(execCmd) / 2 - 1, 1);
+ if (len != 0) {
+ CopyMem(&DeExecParams->ExecCmd, execCmd, sizeof(execCmd));
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeListPwdCacheEdit()
+{
+ UINTN count;
+ UINTN len;
+ UINTN i;
+ UINT32 crc = 0;
+ Password pwd;
+ UINTN pim;
+ EFI_STATUS res;
+ if (DePwdCache == NULL) {
+ DePwdCache = MEM_ALLOC(sizeof(*DePwdCache));
+ DePwdCache->Sign = DCS_DEP_PWD_CACHE_SIGN;
+ }
+ OUT_PRINT(L"PwdCache\n");
+ do {
+ count = (uint32)AskUINTN("Count[0-4]:", DePwdCache->Count);
+ } while (count > 4);
+ DePwdCache->Count = (uint32)count;
+ for (i = 0; i < 4; ++i) {
+ ZeroMem(&pwd, sizeof(pwd));
+ pim = 0;
+ if (i < DePwdCache->Count) {
+ OUT_PRINT(L"%H%d%N [%a] [%d]\n:", i, DePwdCache->Pwd[i].Text, DePwdCache->Pim[i]);
+ GetLine(&len, NULL, pwd.Text, MAX_PASSWORD, 1);
+ if (len != 0) {
+ pwd.Length = (uint32)len;
+ pim = (uint32)AskUINTN("Pim:", DePwdCache->Pim[i]);
+ }
+ }
+ DePwdCache->Pim[i] = (uint32)pim;
+ CopyMem(&DePwdCache->Pwd[i], &pwd, sizeof(pwd));
+ }
+ ZeroMem(&DePwdCache->pad, sizeof(DePwdCache->pad));
+ DePwdCache->CRC = 0;
+ res =gBS->CalculateCrc32(DePwdCache, 512, &crc);
+ DePwdCache->CRC = crc;
+ return res;
+}
+
+EFI_STATUS
+DeListRndSave()
+{
+ EFI_STATUS res;
+ if (gRnd == NULL) {
+ DeRndSaved = NULL;
+ return EFI_SUCCESS;
+ }
+ res = RndSave(gRnd,&DeRndSaved);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Random: %r\n", res);
+ return res;
+ }
+ OUT_PRINT(L"Rnd selected:%d\n", DeRndSaved->Type);
+ return res;
+}
+
+EFI_STATUS
+DeListRndLoad()
+{
+ EFI_STATUS res = EFI_NOT_FOUND;
+ if (DeRndSaved != NULL) {
+ res = RndLoad(DeRndSaved,&gRnd);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"Random: %r\n", res);
+ return res;
+ }
+ OUT_PRINT(L"Rnd selected:%d\n", gRnd->Type);
+ }
+ return res;
+}
diff --git a/Library/GraphLib/EfiGraph.c b/Library/GraphLib/EfiGraph.c
new file mode 100644
index 0000000..b8e8e2e
--- /dev/null
+++ b/Library/GraphLib/EfiGraph.c
@@ -0,0 +1,670 @@
+/** @file
+Graph library
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/GraphicsOutput.h>
+
+EFI_HANDLE* gGraphHandles = NULL;
+UINTN gGraphCount = 0;
+
+EFI_GRAPHICS_OUTPUT_PROTOCOL* gGraphOut = NULL;
+
+EFI_STATUS
+InitGraph() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiGraphicsOutputProtocolGuid, 0, &gGraphHandles, &gGraphCount);
+ if (gGraphCount > 0) {
+ GraphGetIO(gGraphHandles[gGraphCount - 1], &gGraphOut);
+ }
+ return res;
+}
+
+EFI_STATUS
+GraphGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_GRAPHICS_OUTPUT_PROTOCOL** io
+ ) {
+ if (!io) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gBS->HandleProtocol(Handle, &gEfiGraphicsOutputProtocolGuid, (VOID**)io);
+}
+
+EFI_STATUS
+GraphGetModeInfo(
+ IN UINTN mode,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **info,
+ OUT UINTN* szInfo
+ ) {
+ if (!info || !gGraphOut || mode > gGraphOut->Mode->MaxMode) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gGraphOut->QueryMode(gGraphOut, (UINT32)mode, szInfo, info);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Screen
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+ScreenGetSize(
+ OUT UINTN *Height,
+ OUT UINTN *Width
+ )
+{
+ if (gGraphOut == NULL) return EFI_INVALID_PARAMETER;
+ *Height = gGraphOut->Mode->Info->VerticalResolution;
+ *Width = gGraphOut->Mode->Info->HorizontalResolution;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS ScreenFillRect(
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *color,
+ IN UINTN x,
+ IN UINTN y,
+ IN UINTN width,
+ IN UINTN height
+ )
+{
+ if (gGraphOut == NULL) return EFI_INVALID_PARAMETER;
+
+ return gGraphOut->Blt(gGraphOut, color, EfiBltVideoFill, 0, 0, x, y, width, height, width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+}
+
+EFI_STATUS ScreenDrawBlt(
+ IN BLT_HEADER *blt,
+ IN UINTN x,
+ IN UINTN y
+ )
+{
+ return gGraphOut->Blt(gGraphOut, blt->Pixels, EfiBltBufferToVideo, 0, 0, x, y, blt->Width, blt->Height, blt->Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+}
+
+EFI_STATUS ScreenUpdateDirty(
+ IN BLT_HEADER *bltScreen
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ if (bltScreen->Dirty.top != bltScreen->Dirty.bottom || bltScreen->Dirty.left != bltScreen->Dirty.right) {
+ res = gGraphOut->Blt(gGraphOut, bltScreen->Pixels, EfiBltBufferToVideo,
+ bltScreen->Dirty.top, bltScreen->Dirty.left, // Source x,y
+ bltScreen->Dirty.top, bltScreen->Dirty.left, // Dest x,y
+ bltScreen->Dirty.right - bltScreen->Dirty.left + 1, bltScreen->Dirty.bottom - bltScreen->Dirty.top + 1, // width , height
+ bltScreen->Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ SetMem(&bltScreen->Dirty, sizeof(bltScreen->Dirty), 0);
+ }
+ return res;
+}
+
+EFI_STATUS
+ScreenSaveBlt(
+ OUT BLT_HEADER **bltScreen
+ )
+{
+ UINTN height;
+ UINTN width;
+ EFI_STATUS res;
+ BLT_HEADER* blt;
+ if (!bltScreen) return EFI_INVALID_PARAMETER;
+ res = ScreenGetSize(&height, &width);
+ if (EFI_ERROR(res)) return res;
+ blt = (BLT_HEADER*)MEM_ALLOC(sizeof(BLT_HEADER) + height * width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ blt->Height = (UINT32)height;
+ blt->Width = (UINT32)width;
+ *bltScreen = blt;
+ return gGraphOut->Blt(gGraphOut, blt->Pixels, EfiBltVideoToBltBuffer, 0, 0, 0, 0, blt->Width, blt->Height, blt->Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Colors
+//////////////////////////////////////////////////////////////////////////
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorBlack = { 0,0,0,0 };
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorWhite = { 255,255,255,0 };
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorBlue = { 255,0,0,0 };
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorGreen = { 0,255,0,0 };
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorRed = { 0,0,255,0 };
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL gColorGray = { 128,128,128,0 };
+DRAW_CONTEXT gDrawContext = { { 255, 255, 255, 0 }, DrawOpSet, 0xFFFFFFFF, 128, { 128,128,128, 0}, NULL };
+INT32 gBrush3[5*2] = { -1,0, 1,0, 0,1, 0,-1, 0,0 };
+
+//////////////////////////////////////////////////////////////////////////
+// Blt
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+BltDrawBlt(
+ IN OUT BLT_HEADER* canvas,
+ IN BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ UINTN row, col;
+ DRAW_CONTEXT ctx;
+ ctx.Op = DrawOpSet;
+ ctx.Brush = NULL;
+ for (row = 0; row < blt->Height; ++row) {
+ for (col = 0; col < blt->Width; ++col) {
+ ctx.Color = blt->Pixels[col + row * blt->Width];
+ BltPoint(canvas, &ctx, x + col, y + row);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RectMarkDirty(
+ IN OUT PRECT rect,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ if (!rect) return EFI_INVALID_PARAMETER;
+ if (rect->top > y) rect->top = (UINT32)y;
+ if (rect->bottom < y) rect->bottom = (UINT32)y;
+ if (rect->left > x) rect->left = (UINT32)x;
+ if (rect->right < x) rect->right = (UINT32)x;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BltPointSingle(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ UINTN pos;
+ if (!blt || x >= blt->Width || y >= blt->Height) return EFI_INVALID_PARAMETER;
+ RectMarkDirty(&blt->Dirty, x, y);
+ pos = x + y * blt->Width;
+ if (!draw) draw = &gDrawContext;
+ switch (draw->Op)
+ {
+ case DrawOpClear:
+ *(UINT32*)&blt->Pixels[pos] &= ~(*(UINT32*)&draw->Color);
+ break;
+ case DrawOpXor:
+ *(UINT32*)&blt->Pixels[pos] ^= *(UINT32*)&draw->Color;
+ break;
+ case DrawOpOr:
+ *(UINT32*)&blt->Pixels[pos] |= *(UINT32*)&draw->Color;
+ break;
+ case DrawOpSet:
+ blt->Pixels[pos] = draw->Color;
+ break;
+ case DrawOpAlpha:
+ {
+ UINT8 val;
+ val = blt->Pixels[pos].Red;
+ blt->Pixels[pos].Red = (UINT8)(val + (((draw->AlphaColor.Red - val) * draw->Alpha) >> 8));
+
+ val = blt->Pixels[pos].Green;
+ blt->Pixels[pos].Green = (UINT8)(val + (((draw->AlphaColor.Green - val) * draw->Alpha) >> 8));
+
+ val = blt->Pixels[pos].Blue;
+ blt->Pixels[pos].Blue = (UINT8)(val + (((draw->AlphaColor.Blue - val) * draw->Alpha) >> 8));
+
+ break;
+ }
+ default:
+ break;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BltPoint(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ if (draw->Brush == NULL) return BltPointSingle(blt, draw, x, y);
+ else
+ {
+ INT32* offset = draw->Brush;
+ do {
+ BltPointSingle(blt, draw, x + offset[0], y + +offset[1]);
+ offset += 2;
+ } while (!(offset[0] == 0 && offset[1] == 0));
+ return BltPointSingle(blt, draw, x, y);
+ }
+}
+
+VOID
+BltBox(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1)
+{
+ BltLine(blt, draw, x0, y0, x1, y0);
+ BltLine(blt, draw, x0, y0, x0, y1);
+ BltLine(blt, draw, x0, y1, x1, y1);
+ BltLine(blt, draw, x1, y0, x1, y1);
+}
+
+VOID
+BltFill(
+ IN BLT_HEADER* blt,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL fill,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1)
+{
+ INT32 x;
+ INT32 y;
+ DRAW_CONTEXT ctx;
+ ctx.Op = DrawOpSet;
+ ctx.Brush = NULL;
+ ctx.Color = fill;
+ for (y = y0; y < y1; ++y) {
+ for (x = x0; x < x1; ++x) {
+ BltPoint(blt, &ctx, x, y);
+ }
+ }
+}
+
+VOID
+BltLine(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x0,
+ IN INT32 y0,
+ IN INT32 x1,
+ IN INT32 y1)
+{
+ int dx = ABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
+ int dy = -ABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
+ UINT32 mask, dmask, cmask;
+ int err = dx + dy, e2; /* error value e_xy */
+ mask = draw ? draw->DashLine : gDrawContext.DashLine;
+ dmask = mask;
+ cmask = 32;
+ for (;;) { /* loop */
+ // Dash
+ if ((dmask & 1) == 1) {
+ BltPoint(blt, draw, x0, y0);
+ }
+ dmask >>= 1;
+ cmask--;
+ if (cmask == 0) {
+ dmask = mask;
+ cmask = 32;
+ }
+ // next point
+ e2 = 2 * err;
+ if (e2 >= dy) { /* e_xy+e_x > 0 */
+ if (x0 == x1) break;
+ err += dy; x0 += sx;
+ }
+ if (e2 <= dx) { /* e_xy+e_y < 0 */
+ if (y0 == y1) break;
+ err += dx; y0 += sy;
+ }
+ }
+}
+
+
+
+VOID
+BltCircle(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 xm,
+ IN INT32 ym,
+ IN INT32 r,
+ IN BOOLEAN fill)
+{
+ int sx = 1;
+ int x = -r, y = 0, err = 2 - 2 * r; /* bottom left to top right */
+ UINT32 mask, dmask, cmask;
+ mask = draw ? draw->DashLine : gDrawContext.DashLine;
+ dmask = mask;
+ cmask = 32;
+ do {
+ if (fill) {
+ if (sx != x) {
+ int i;
+ for (i = ym - y; i <= ym + y; i++) {
+ BltPoint(blt, draw, xm + x, i);
+ if( x != 0 ) BltPoint(blt, draw, xm - x, i);
+ }
+ sx = x;
+ }
+ } else {
+ if ((dmask & 1) == 1) {
+ BltPoint(blt, draw, xm - x, ym + y); /* I. Quadrant +x +y */
+ BltPoint(blt, draw, xm - y, ym - x); /* II. Quadrant -x +y */
+ BltPoint(blt, draw, xm + x, ym - y); /* III. Quadrant -x -y */
+ BltPoint(blt, draw, xm + y, ym + x); /* IV. Quadrant +x -y */
+ }
+ dmask >>= 1;
+ cmask--;
+ }
+ if (cmask == 0) {
+ dmask = mask;
+ cmask = 32;
+ }
+ r = err;
+ if (r <= y) err += ++y * 2 + 1; /* e_xy+e_y < 0 */
+ if (r >= x || err > y) /* e_xy+e_x > 0 or no 2nd y-step */
+ err += ++x * 2 + 1; /* -> x-step now */
+ } while (x <= 0);
+}
+
+extern __int8 gSimplex_ascii_32_126[95][112];
+VOID
+BltText(
+ IN BLT_HEADER* blt,
+ IN PDRAW_CONTEXT draw,
+ IN INT32 x,
+ IN INT32 y,
+ IN INT32 scale, // 0..256 reduce 256... enlarge
+ IN CONST CHAR8 *text)
+{
+ INT32 posX = x;
+ INT32 posY = y;
+ const char *c;
+ for (c = text; *c; ++c)
+ {
+ INT8 ch = *c;
+ if (ch >= 32 && ch <= 126) {
+ INT8 *it = gSimplex_ascii_32_126[ch - 32];
+ INT32 nvtcs = *it++;
+ INT32 spacing = *it++;
+ INT32 fromX = -1;
+ INT32 fromY = -1;
+ INTN i;
+ for (i = 0; i < nvtcs; ++i) {
+ INT32 toX = *it++;
+ INT32 toY = *it++;
+ if ((fromX != -1 || fromY != -1) && (toX != -1 || toY != -1)) {
+ BltLine(
+ blt, draw,
+ posX + ((fromX * scale) >> 8), posY + (((25 - fromY) * scale) >> 8),
+ posX + ((toX * scale) >> 8), posY + (((25 - toY) * scale) >> 8));
+ }
+ fromX = toX;
+ fromY = toY;
+ }
+ posX += (spacing * scale) >> 8;
+ }
+ // Next line
+ if (ch == '\n') {
+ posX = x;
+ posY += 30 * scale >> 8;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Bmp
+//////////////////////////////////////////////////////////////////////////
+
+#pragma pack(1)
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} BMP_COLOR_MAP;
+
+typedef struct {
+ CHAR8 CharB;
+ CHAR8 CharM;
+ UINT32 Size;
+ UINT16 Reserved[2];
+ UINT32 ImageOffset;
+ UINT32 HeaderSize;
+ UINT32 PixelWidth;
+ UINT32 PixelHeight;
+ UINT16 Planes; // Must be 1
+ UINT16 BitPerPixel; // 1, 4, 8, or 24
+ UINT32 CompressionType;
+ UINT32 ImageSize; // Compressed image size in bytes
+ UINT32 XPixelsPerMeter;
+ UINT32 YPixelsPerMeter;
+ UINT32 NumberOfColors;
+ UINT32 ImportantColors;
+} BMP_IMAGE_HEADER;
+#pragma pack()
+
+EFI_STATUS BmpGetSize(
+ IN const unsigned char* BmpImage,
+ IN UINTN BmpImageSize,
+ OUT UINTN *Height,
+ OUT UINTN *Width
+ )
+{
+ BMP_IMAGE_HEADER *BmpHeader;
+
+ if (sizeof(BMP_IMAGE_HEADER) > BmpImageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BmpHeader = (BMP_IMAGE_HEADER *)BmpImage;
+
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Only support BITMAPINFOHEADER format.
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+ //
+ if (BmpHeader->HeaderSize != sizeof(BMP_IMAGE_HEADER) - ((UINTN)&(((BMP_IMAGE_HEADER *)0)->HeaderSize))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *Height = BmpHeader->PixelHeight;
+ *Width = BmpHeader->PixelWidth;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BmpToBlt(
+ IN CONST VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ OUT BLT_HEADER **blt
+ )
+{
+ UINT8 *Image;
+ UINT8 *ImageHeader;
+ BMP_IMAGE_HEADER *BmpHeader;
+ BMP_COLOR_MAP *BmpColorMap;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt_;
+ UINT64 BltBufferSize;
+ UINTN Index;
+ UINTN Height;
+ UINTN Width;
+ UINTN ImageIndex;
+ UINTN DataSizePerLine;
+ UINT32 ColorMapNum;
+
+ if (sizeof(BMP_IMAGE_HEADER) > BmpImageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BmpHeader = (BMP_IMAGE_HEADER *)BmpImage;
+
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Doesn't support compress.
+ //
+ if (BmpHeader->CompressionType != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Only support BITMAPINFOHEADER format.
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+ //
+ if (BmpHeader->HeaderSize != sizeof(BMP_IMAGE_HEADER) - ((UINTN)&(((BMP_IMAGE_HEADER *)0)->HeaderSize))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // The data size in each line must be 4 byte alignment.
+ //
+ DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+ BltBufferSize = MultU64x32(DataSizePerLine, BmpHeader->PixelHeight);
+ if (BltBufferSize > (UINT32)~0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BmpHeader->Size != BmpImageSize) ||
+ (BmpHeader->Size < BmpHeader->ImageOffset) ||
+ (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate Color Map offset in the image.
+ //
+ Image = (UINT8 *)BmpImage;
+ BmpColorMap = (BMP_COLOR_MAP *)(Image + sizeof(BMP_IMAGE_HEADER));
+ if (BmpHeader->ImageOffset < sizeof(BMP_IMAGE_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmpHeader->ImageOffset > sizeof(BMP_IMAGE_HEADER)) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ ColorMapNum = 2;
+ break;
+ case 4:
+ ColorMapNum = 16;
+ break;
+ case 8:
+ ColorMapNum = 256;
+ break;
+ default:
+ ColorMapNum = 0;
+ break;
+ }
+ if (BmpHeader->ImageOffset - sizeof(BMP_IMAGE_HEADER) != sizeof(BMP_COLOR_MAP) * ColorMapNum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Calculate graphics image data address in the image
+ //
+ Image = ((UINT8 *)BmpImage) + BmpHeader->ImageOffset;
+ ImageHeader = Image;
+
+ BltBufferSize = MultU64x32((UINT64)BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+ //
+ // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BltBufferSize > DivU64x32((UINTN)~0, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+ BltBufferSize = MultU64x32(BltBufferSize, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ *blt = MEM_ALLOC((UINTN)BltBufferSize + sizeof(**blt));
+
+ (*blt)->Width = BmpHeader->PixelWidth;
+ (*blt)->Height = BmpHeader->PixelHeight;
+
+ //
+ // Convert image from BMP to Blt buffer format
+ //
+ BltBuffer = (*blt)->Pixels;
+ for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+ Blt_ = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+ for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt_++) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ //
+ // Convert 1bit BMP to 24-bit color
+ //
+ for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+ Blt_->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+ Blt_->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+ Blt_->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+ Blt_++;
+ Width++;
+ }
+
+ Blt_--;
+ Width--;
+ break;
+
+ case 4:
+ //
+ // Convert BMP Palette to 24-bit color
+ //
+ Index = (*Image) >> 4;
+ Blt_->Red = BmpColorMap[Index].Red;
+ Blt_->Green = BmpColorMap[Index].Green;
+ Blt_->Blue = BmpColorMap[Index].Blue;
+ if (Width < (BmpHeader->PixelWidth - 1)) {
+ Blt_++;
+ Width++;
+ Index = (*Image) & 0x0f;
+ Blt_->Red = BmpColorMap[Index].Red;
+ Blt_->Green = BmpColorMap[Index].Green;
+ Blt_->Blue = BmpColorMap[Index].Blue;
+ }
+ break;
+
+ case 8:
+ //
+ // Convert BMP Palette to 24-bit color
+ //
+ Blt_->Red = BmpColorMap[*Image].Red;
+ Blt_->Green = BmpColorMap[*Image].Green;
+ Blt_->Blue = BmpColorMap[*Image].Blue;
+ break;
+
+ case 24:
+ Blt_->Blue = *Image++;
+ Blt_->Green = *Image++;
+ Blt_->Red = *Image;
+ break;
+
+ default:
+ MEM_FREE(*blt);
+ *blt = NULL;
+ return EFI_UNSUPPORTED;
+ break;
+ };
+
+ }
+
+ ImageIndex = (UINTN)(Image - ImageHeader);
+ if ((ImageIndex % 4) != 0) {
+ //
+ // Bmp Image starts each row on a 32-bit boundary!
+ //
+ Image = Image + (4 - (ImageIndex % 4));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Library/GraphLib/GraphLib.inf b/Library/GraphLib/GraphLib.inf
new file mode 100644
index 0000000..8201c82
--- /dev/null
+++ b/Library/GraphLib/GraphLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Graph library
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = GraphLib
+ MODULE_UNI_FILE = GraphLib.uni
+ FILE_GUID = 9BD93C5C-7EF7-4B07-A53D-1E84A9F00F2C
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = GraphLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+
+[Sources.common]
+ EfiGraph.c
+ font.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid
diff --git a/Library/GraphLib/font.c b/Library/GraphLib/font.c
new file mode 100644
index 0000000..c3ba9b2
--- /dev/null
+++ b/Library/GraphLib/font.c
@@ -0,0 +1,586 @@
+/** @file
+Vector font definition based on Hershey Vector Font
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+__int8 gSimplex_ascii_32_126[95][112] = {
+ 0,16, /* Ascii 32 */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,10, /* Ascii 33 */
+ 5,21, 5, 7,-1,-1, 5, 2, 4, 1, 5, 0, 6, 1, 5, 2,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,16, /* Ascii 34 */
+ 4,21, 4,14,-1,-1,12,21,12,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,21, /* Ascii 35 */
+ 11,25, 4,-7,-1,-1,17,25,10,-7,-1,-1, 4,12,18,12,-1,-1, 3, 6,17, 6,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 26,20, /* Ascii 36 */
+ 8,25, 8,-4,-1,-1,12,25,12,-4,-1,-1,17,18,15,20,12,21, 8,21, 5,20, 3,
+ 18, 3,16, 4,14, 5,13, 7,12,13,10,15, 9,16, 8,17, 6,17, 3,15, 1,12, 0,
+ 8, 0, 5, 1, 3, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 31,24, /* Ascii 37 */
+ 21,21, 3, 0,-1,-1, 8,21,10,19,10,17, 9,15, 7,14, 5,14, 3,16, 3,18, 4,
+ 20, 6,21, 8,21,10,20,13,19,16,19,19,20,21,21,-1,-1,17, 7,15, 6,14, 4,
+ 14, 2,16, 0,18, 0,20, 1,21, 3,21, 5,19, 7,17, 7,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 34,26, /* Ascii 38 */
+ 23,12,23,13,22,14,21,14,20,13,19,11,17, 6,15, 3,13, 1,11, 0, 7, 0, 5,
+ 1, 4, 2, 3, 4, 3, 6, 4, 8, 5, 9,12,13,13,14,14,16,14,18,13,20,11,21,
+ 9,20, 8,18, 8,16, 9,13,11,10,16, 3,18, 1,20, 0,22, 0,23, 1,23, 2,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 7,10, /* Ascii 39 */
+ 5,19, 4,20, 5,21, 6,20, 6,18, 5,16, 4,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,14, /* Ascii 40 */
+ 11,25, 9,23, 7,20, 5,16, 4,11, 4, 7, 5, 2, 7,-2, 9,-5,11,-7,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,14, /* Ascii 41 */
+ 3,25, 5,23, 7,20, 9,16,10,11,10, 7, 9, 2, 7,-2, 5,-5, 3,-7,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,16, /* Ascii 42 */
+ 8,21, 8, 9,-1,-1, 3,18,13,12,-1,-1,13,18, 3,12,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,26, /* Ascii 43 */
+ 13,18,13, 0,-1,-1, 4, 9,22, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,10, /* Ascii 44 */
+ 6, 1, 5, 0, 4, 1, 5, 2, 6, 1, 6,-1, 5,-3, 4,-4,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2,26, /* Ascii 45 */
+ 4, 9,22, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,10, /* Ascii 46 */
+ 5, 2, 4, 1, 5, 0, 6, 1, 5, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2,22, /* Ascii 47 */
+ 20,25, 2,-7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,20, /* Ascii 48 */
+ 9,21, 6,20, 4,17, 3,12, 3, 9, 4, 4, 6, 1, 9, 0,11, 0,14, 1,16, 4,17,
+ 9,17,12,16,17,14,20,11,21, 9,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 4,20, /* Ascii 49 */
+ 6,17, 8,18,11,21,11, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 14,20, /* Ascii 50 */
+ 4,16, 4,17, 5,19, 6,20, 8,21,12,21,14,20,15,19,16,17,16,15,15,13,13,
+ 10, 3, 0,17, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 15,20, /* Ascii 51 */
+ 5,21,16,21,10,13,13,13,15,12,16,11,17, 8,17, 6,16, 3,14, 1,11, 0, 8,
+ 0, 5, 1, 4, 2, 3, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 6,20, /* Ascii 52 */
+ 13,21, 3, 7,18, 7,-1,-1,13,21,13, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,20, /* Ascii 53 */
+ 15,21, 5,21, 4,12, 5,13, 8,14,11,14,14,13,16,11,17, 8,17, 6,16, 3,14,
+ 1,11, 0, 8, 0, 5, 1, 4, 2, 3, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 23,20, /* Ascii 54 */
+ 16,18,15,20,12,21,10,21, 7,20, 5,17, 4,12, 4, 7, 5, 3, 7, 1,10, 0,11,
+ 0,14, 1,16, 3,17, 6,17, 7,16,10,14,12,11,13,10,13, 7,12, 5,10, 4, 7,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,20, /* Ascii 55 */
+ 17,21, 7, 0,-1,-1, 3,21,17,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 29,20, /* Ascii 56 */
+ 8,21, 5,20, 4,18, 4,16, 5,14, 7,13,11,12,14,11,16, 9,17, 7,17, 4,16,
+ 2,15, 1,12, 0, 8, 0, 5, 1, 4, 2, 3, 4, 3, 7, 4, 9, 6,11, 9,12,13,13,
+ 15,14,16,16,16,18,15,20,12,21, 8,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 23,20, /* Ascii 57 */
+ 16,14,15,11,13, 9,10, 8, 9, 8, 6, 9, 4,11, 3,14, 3,15, 4,18, 6,20, 9,
+ 21,10,21,13,20,15,18,16,14,16, 9,15, 4,13, 1,10, 0, 8, 0, 5, 1, 4, 3,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,10, /* Ascii 58 */
+ 5,14, 4,13, 5,12, 6,13, 5,14,-1,-1, 5, 2, 4, 1, 5, 0, 6, 1, 5, 2,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 14,10, /* Ascii 59 */
+ 5,14, 4,13, 5,12, 6,13, 5,14,-1,-1, 6, 1, 5, 0, 4, 1, 5, 2, 6, 1, 6,
+ -1, 5,-3, 4,-4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 3,24, /* Ascii 60 */
+ 20,18, 4, 9,20, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,26, /* Ascii 61 */
+ 4,12,22,12,-1,-1, 4, 6,22, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 3,24, /* Ascii 62 */
+ 4,18,20, 9, 4, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 20,18, /* Ascii 63 */
+ 3,16, 3,17, 4,19, 5,20, 7,21,11,21,13,20,14,19,15,17,15,15,14,13,13,
+ 12, 9,10, 9, 7,-1,-1, 9, 2, 8, 1, 9, 0,10, 1, 9, 2,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 55,27, /* Ascii 64 */
+ 18,13,17,15,15,16,12,16,10,15, 9,14, 8,11, 8, 8, 9, 6,11, 5,14, 5,16,
+ 6,17, 8,-1,-1,12,16,10,14, 9,11, 9, 8,10, 6,11, 5,-1,-1,18,16,17, 8,
+ 17, 6,19, 5,21, 5,23, 7,24,10,24,12,23,15,22,17,20,19,18,20,15,21,12,
+ 21, 9,20, 7,19, 5,17, 4,15, 3,12, 3, 9, 4, 6, 5, 4, 7, 2, 9, 1,12, 0,
+ 15, 0,18, 1,20, 2,21, 3,-1,-1,19,16,18, 8,18, 6,19, 5,
+ 8,18, /* Ascii 65 */
+ 9,21, 1, 0,-1,-1, 9,21,17, 0,-1,-1, 4, 7,14, 7,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 23,21, /* Ascii 66 */
+ 4,21, 4, 0,-1,-1, 4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,
+ 11,-1,-1, 4,11,13,11,16,10,17, 9,18, 7,18, 4,17, 2,16, 1,13, 0, 4, 0,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 18,21, /* Ascii 67 */
+ 18,16,17,18,15,20,13,21, 9,21, 7,20, 5,18, 4,16, 3,13, 3, 8, 4, 5, 5,
+ 3, 7, 1, 9, 0,13, 0,15, 1,17, 3,18, 5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 15,21, /* Ascii 68 */
+ 4,21, 4, 0,-1,-1, 4,21,11,21,14,20,16,18,17,16,18,13,18, 8,17, 5,16,
+ 3,14, 1,11, 0, 4, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,19, /* Ascii 69 */
+ 4,21, 4, 0,-1,-1, 4,21,17,21,-1,-1, 4,11,12,11,-1,-1, 4, 0,17, 0,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,18, /* Ascii 70 */
+ 4,21, 4, 0,-1,-1, 4,21,17,21,-1,-1, 4,11,12,11,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 22,21, /* Ascii 71 */
+ 18,16,17,18,15,20,13,21, 9,21, 7,20, 5,18, 4,16, 3,13, 3, 8, 4, 5, 5,
+ 3, 7, 1, 9, 0,13, 0,15, 1,17, 3,18, 5,18, 8,-1,-1,13, 8,18, 8,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,22, /* Ascii 72 */
+ 4,21, 4, 0,-1,-1,18,21,18, 0,-1,-1, 4,11,18,11,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2, 8, /* Ascii 73 */
+ 4,21, 4, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,16, /* Ascii 74 */
+ 12,21,12, 5,11, 2,10, 1, 8, 0, 6, 0, 4, 1, 3, 2, 2, 5, 2, 7,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,21, /* Ascii 75 */
+ 4,21, 4, 0,-1,-1,18,21, 4, 7,-1,-1, 9,12,18, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,17, /* Ascii 76 */
+ 4,21, 4, 0,-1,-1, 4, 0,16, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,24, /* Ascii 77 */
+ 4,21, 4, 0,-1,-1, 4,21,12, 0,-1,-1,20,21,12, 0,-1,-1,20,21,20, 0,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,22, /* Ascii 78 */
+ 4,21, 4, 0,-1,-1, 4,21,18, 0,-1,-1,18,21,18, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 21,22, /* Ascii 79 */
+ 9,21, 7,20, 5,18, 4,16, 3,13, 3, 8, 4, 5, 5, 3, 7, 1, 9, 0,13, 0,15,
+ 1,17, 3,18, 5,19, 8,19,13,18,16,17,18,15,20,13,21, 9,21,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 13,21, /* Ascii 80 */
+ 4,21, 4, 0,-1,-1, 4,21,13,21,16,20,17,19,18,17,18,14,17,12,16,11,13,
+ 10, 4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 24,22, /* Ascii 81 */
+ 9,21, 7,20, 5,18, 4,16, 3,13, 3, 8, 4, 5, 5, 3, 7, 1, 9, 0,13, 0,15,
+ 1,17, 3,18, 5,19, 8,19,13,18,16,17,18,15,20,13,21, 9,21,-1,-1,12, 4,
+ 18,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 16,21, /* Ascii 82 */
+ 4,21, 4, 0,-1,-1, 4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,
+ 11, 4,11,-1,-1,11,11,18, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 20,20, /* Ascii 83 */
+ 17,18,15,20,12,21, 8,21, 5,20, 3,18, 3,16, 4,14, 5,13, 7,12,13,10,15,
+ 9,16, 8,17, 6,17, 3,15, 1,12, 0, 8, 0, 5, 1, 3, 3,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,16, /* Ascii 84 */
+ 8,21, 8, 0,-1,-1, 1,21,15,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,22, /* Ascii 85 */
+ 4,21, 4, 6, 5, 3, 7, 1,10, 0,12, 0,15, 1,17, 3,18, 6,18,21,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,18, /* Ascii 86 */
+ 1,21, 9, 0,-1,-1,17,21, 9, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,24, /* Ascii 87 */
+ 2,21, 7, 0,-1,-1,12,21, 7, 0,-1,-1,12,21,17, 0,-1,-1,22,21,17, 0,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,20, /* Ascii 88 */
+ 3,21,17, 0,-1,-1,17,21, 3, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 6,18, /* Ascii 89 */
+ 1,21, 9,11, 9, 0,-1,-1,17,21, 9,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,20, /* Ascii 90 */
+ 17,21, 3, 0,-1,-1, 3,21,17,21,-1,-1, 3, 0,17, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,14, /* Ascii 91 */
+ 4,25, 4,-7,-1,-1, 5,25, 5,-7,-1,-1, 4,25,11,25,-1,-1, 4,-7,11,-7,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2,14, /* Ascii 92 */
+ 0,21,14,-3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,14, /* Ascii 93 */
+ 9,25, 9,-7,-1,-1,10,25,10,-7,-1,-1, 3,25,10,25,-1,-1, 3,-7,10,-7,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,16, /* Ascii 94 */
+ 6,15, 8,18,10,15,-1,-1, 3,12, 8,17,13,12,-1,-1, 8,17, 8, 0,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2,16, /* Ascii 95 */
+ 0,-2,16,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 7,10, /* Ascii 96 */
+ 6,21, 5,20, 4,18, 4,16, 5,15, 6,16, 5,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 97 */
+ 15,14,15, 0,-1,-1,15,11,13,13,11,14, 8,14, 6,13, 4,11, 3, 8, 3, 6, 4,
+ 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 98 */
+ 4,21, 4, 0,-1,-1, 4,11, 6,13, 8,14,11,14,13,13,15,11,16, 8,16, 6,15,
+ 3,13, 1,11, 0, 8, 0, 6, 1, 4, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 14,18, /* Ascii 99 */
+ 15,11,13,13,11,14, 8,14, 6,13, 4,11, 3, 8, 3, 6, 4, 3, 6, 1, 8, 0,11,
+ 0,13, 1,15, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 100 */
+ 15,21,15, 0,-1,-1,15,11,13,13,11,14, 8,14, 6,13, 4,11, 3, 8, 3, 6, 4,
+ 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,18, /* Ascii 101 */
+ 3, 8,15, 8,15,10,14,12,13,13,11,14, 8,14, 6,13, 4,11, 3, 8, 3, 6, 4,
+ 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,12, /* Ascii 102 */
+ 10,21, 8,21, 6,20, 5,17, 5, 0,-1,-1, 2,14, 9,14,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 22,19, /* Ascii 103 */
+ 15,14,15,-2,14,-5,13,-6,11,-7, 8,-7, 6,-6,-1,-1,15,11,13,13,11,14, 8,
+ 14, 6,13, 4,11, 3, 8, 3, 6, 4, 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,19, /* Ascii 104 */
+ 4,21, 4, 0,-1,-1, 4,10, 7,13, 9,14,12,14,14,13,15,10,15, 0,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8, 8, /* Ascii 105 */
+ 3,21, 4,20, 5,21, 4,22, 3,21,-1,-1, 4,14, 4, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,10, /* Ascii 106 */
+ 5,21, 6,20, 7,21, 6,22, 5,21,-1,-1, 6,14, 6,-3, 5,-6, 3,-7, 1,-7,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,17, /* Ascii 107 */
+ 4,21, 4, 0,-1,-1,14,14, 4, 4,-1,-1, 8, 8,15, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2, 8, /* Ascii 108 */
+ 4,21, 4, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 18,30, /* Ascii 109 */
+ 4,14, 4, 0,-1,-1, 4,10, 7,13, 9,14,12,14,14,13,15,10,15, 0,-1,-1,15,
+ 10,18,13,20,14,23,14,25,13,26,10,26, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,19, /* Ascii 110 */
+ 4,14, 4, 0,-1,-1, 4,10, 7,13, 9,14,12,14,14,13,15,10,15, 0,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 111 */
+ 8,14, 6,13, 4,11, 3, 8, 3, 6, 4, 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,16,
+ 6,16, 8,15,11,13,13,11,14, 8,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 112 */
+ 4,14, 4,-7,-1,-1, 4,11, 6,13, 8,14,11,14,13,13,15,11,16, 8,16, 6,15,
+ 3,13, 1,11, 0, 8, 0, 6, 1, 4, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,19, /* Ascii 113 */
+ 15,14,15,-7,-1,-1,15,11,13,13,11,14, 8,14, 6,13, 4,11, 3, 8, 3, 6, 4,
+ 3, 6, 1, 8, 0,11, 0,13, 1,15, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,13, /* Ascii 114 */
+ 4,14, 4, 0,-1,-1, 4, 8, 5,11, 7,13, 9,14,12,14,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 17,17, /* Ascii 115 */
+ 14,11,13,13,10,14, 7,14, 4,13, 3,11, 4, 9, 6, 8,11, 7,13, 6,14, 4,14,
+ 3,13, 1,10, 0, 7, 0, 4, 1, 3, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,12, /* Ascii 116 */
+ 5,21, 5, 4, 6, 1, 8, 0,10, 0,-1,-1, 2,14, 9,14,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 10,19, /* Ascii 117 */
+ 4,14, 4, 4, 5, 1, 7, 0,10, 0,12, 1,15, 4,-1,-1,15,14,15, 0,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,16, /* Ascii 118 */
+ 2,14, 8, 0,-1,-1,14,14, 8, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 11,22, /* Ascii 119 */
+ 3,14, 7, 0,-1,-1,11,14, 7, 0,-1,-1,11,14,15, 0,-1,-1,19,14,15, 0,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 5,17, /* Ascii 120 */
+ 3,14,14, 0,-1,-1,14,14, 3, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 9,16, /* Ascii 121 */
+ 2,14, 8, 0,-1,-1,14,14, 8, 0, 6,-4, 4,-6, 2,-7, 1,-7,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 8,17, /* Ascii 122 */
+ 14,14, 3, 0,-1,-1, 3,14,14,14,-1,-1, 3, 0,14, 0,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 39,14, /* Ascii 123 */
+ 9,25, 7,24, 6,23, 5,21, 5,19, 6,17, 7,16, 8,14, 8,12, 6,10,-1,-1, 7,
+ 24, 6,22, 6,20, 7,18, 8,17, 9,15, 9,13, 8,11, 4, 9, 8, 7, 9, 5, 9, 3,
+ 8, 1, 7, 0, 6,-2, 6,-4, 7,-6,-1,-1, 6, 8, 8, 6, 8, 4, 7, 2, 6, 1, 5,
+ -1, 5,-3, 6,-5, 7,-6, 9,-7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 2, 8, /* Ascii 124 */
+ 4,25, 4,-7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 39,14, /* Ascii 125 */
+ 5,25, 7,24, 8,23, 9,21, 9,19, 8,17, 7,16, 6,14, 6,12, 8,10,-1,-1, 7,
+ 24, 8,22, 8,20, 7,18, 6,17, 5,15, 5,13, 6,11,10, 9, 6, 7, 5, 5, 5, 3,
+ 6, 1, 7, 0, 8,-2, 8,-4, 7,-6,-1,-1, 8, 8, 6, 6, 6, 4, 7, 2, 8, 1, 9,
+ -1, 9,-3, 8,-5, 7,-6, 5,-7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 23,24, /* Ascii 126 */
+ 3, 6, 3, 8, 4,11, 6,12, 8,12,10,11,14, 8,16, 7,18, 7,20, 8,21,10,-1,
+ -1, 3, 8, 4,10, 6,11, 8,11,10,10,14, 7,16, 6,18, 6,20, 7,21,10,21,12,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+}; \ No newline at end of file
diff --git a/Library/PasswordLib/ConsolePassword.c b/Library/PasswordLib/ConsolePassword.c
new file mode 100644
index 0000000..c195b48
--- /dev/null
+++ b/Library/PasswordLib/ConsolePassword.c
@@ -0,0 +1,128 @@
+/** @file
+Ask password from console
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include "Library/CommonLib.h"
+#include "Library/PasswordLib.h"
+#include <Library/UefiBootServicesTableLib.h>
+
+VOID
+AskConsolePwdInt(
+ OUT UINT32 *length,
+ OUT CHAR8 *asciiLine,
+ OUT INT32 *retCode,
+ IN UINTN line_max,
+ IN UINT8 show
+ )
+{
+ EFI_INPUT_KEY key;
+ UINT32 count = 0;
+ UINTN i;
+
+ gST->ConOut->EnableCursor(gST->ConOut, TRUE);
+
+ do {
+ key = GetKey();
+ // Remove dirty chars 0.1s
+ FlushInputDelay(100000);
+
+ if (key.ScanCode == SCAN_ESC) {
+ *retCode = AskPwdRetCancel;
+ break;
+ }
+
+ if (key.ScanCode == SCAN_F2) {
+ *retCode = AskPwdRetChange;
+ break;
+ }
+
+ if (key.ScanCode == SCAN_F5) {
+ show = show ? 0 : 1;
+ if (show) {
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b");
+ }
+ OUT_PRINT(L"%a", asciiLine);
+ }
+ else {
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b");
+ }
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"*");
+ }
+ }
+ }
+
+ if (key.ScanCode == SCAN_F7) {
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ ConsoleShowTip(gPlatformLocked ? L" Platform locked!" : L" Platform unlocked!", 10000000);
+ }
+
+ if (key.ScanCode == SCAN_F8) {
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ ConsoleShowTip(gTPMLocked ? L" TPM locked!" : L" TPM unlocked!", 10000000);
+ }
+
+
+ if (key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ *retCode = AskPwdRetLogin;
+ break;
+ }
+
+ if ((count >= line_max &&
+ key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED ||
+ key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ }
+ else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ OUT_PRINT(L"\b \b");
+ if (asciiLine != NULL) asciiLine[--count] = '\0';
+ continue;
+ }
+
+ // check size of line
+ if (count < line_max - 1) {
+ if (show) {
+ OUT_PRINT(L"%c", key.UnicodeChar);
+ }
+ else {
+ OUT_PRINT(L"*");
+ }
+ // save char
+ if (asciiLine != NULL) {
+ asciiLine[count++] = (CHAR8)key.UnicodeChar;
+ asciiLine[count] = 0;
+ }
+ }
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ if (length != NULL) *length = count;
+ // Set end of line
+ if (asciiLine != NULL) {
+ asciiLine[count] = '\0';
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b \b");
+ }
+ OUT_PRINT(L"*");
+ }
+ OUT_PRINT(L"\n");
+}
diff --git a/Library/PasswordLib/PasswordLib.inf b/Library/PasswordLib/PasswordLib.inf
new file mode 100644
index 0000000..6b30c0c
--- /dev/null
+++ b/Library/PasswordLib/PasswordLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Password library
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = GraphLib
+ MODULE_UNI_FILE = GraphLib.uni
+ FILE_GUID = A73BC841-498A-41E5-87B1-A0CED9933756
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = GraphLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ PicturePassword.c
+ ConsolePassword.c
+ PlatformID.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid
+
+[Guids]
+ gEfiSmbiosTableGuid
diff --git a/Library/PasswordLib/PicturePassword.c b/Library/PasswordLib/PicturePassword.c
new file mode 100644
index 0000000..f917899
--- /dev/null
+++ b/Library/PasswordLib/PicturePassword.c
@@ -0,0 +1,629 @@
+/** @file
+Picture password
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/PasswordLib.h>
+
+CHAR16* gPasswordPictureFileName = NULL;
+
+CHAR8* gPasswordPictureChars = NULL;
+CHAR8* gPasswordPictureCharsDefault = "MN/[aQ-eyPr}GT: |V^UqiI_gbdA9YwZ%f8t6S@D\"7uXl\\30R#+zH*,W4J?=&BLFv]hx~E;$<.o'sp1`(>C)O{!5j2nmkcK";
+//CHAR8* gPicturePasswordCharsDefault = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+UINTN gPasswordPictureCharsLen = 95;
+
+UINT8 gPasswordVisible = 0;
+int gPasswordShowMark = 1;
+
+int gPlatformLocked = 0;
+int gTPMLocked = 0;
+int gSCLocked = 0;
+
+
+//////////////////////////////////////////////////////////////////////////
+// Picture password
+//////////////////////////////////////////////////////////////////////////
+CONST CHAR16* BmpName = L"Test.bmp";
+VOID* Bmp = NULL;
+UINTN BmpSize = 0;
+BLT_HEADER* bltPwd = NULL;
+UINTN posPictX, posPictY;
+BLT_HEADER* bltScrn = NULL;
+UINTN* cellSelected = NULL;
+UINTN picPwdIdx = 0;
+UINTN sHeight;
+UINTN sWidth;
+UINTN step;
+
+DRAW_CONTEXT ctxCursor;
+DRAW_CONTEXT ctxCell;
+DRAW_CONTEXT ctxMark;
+DRAW_CONTEXT ctxSet;
+
+VOID
+CellUpdate(
+ IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y,
+ IN BOOLEAN selected) {
+ if (selected && gPasswordShowMark) {
+ BltCircle(blt, &ctxMark, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 3), TRUE);
+ BltCircle(blt, &ctxCell, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 9), TRUE);
+ }
+ else {
+ CHAR8 ch[2] = { 0,0 };
+ BltCircle(blt, &ctxCell, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 3), FALSE);
+ if (gPasswordVisible) {
+ ch[0] = gPasswordPictureChars[(x + blt->Width / step * y) % gPasswordPictureCharsLen];
+ BltText(blt, &ctxCell, (INT32)(x * step + step / 2 - 12), (INT32)(y * step + step / 2 - 12), 256, ch);
+ }
+ }
+}
+
+BOOLEAN
+CellGetSelected(
+ IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y,
+ OUT UINTN* cellX,
+ OUT UINTN* cellY) {
+ RECT reg;
+ UINTN sen;
+ if (x > blt->Width || y > blt->Height) return FALSE;
+ *cellX = x / step;
+ *cellY = y / step;
+ sen = step / 5; // zone sensible
+ reg.left = (UINT32)(*cellX * step + step / 2 - sen);
+ reg.right = (UINT32)(*cellX * step + step / 2 + sen);
+ reg.top = (UINT32)(*cellY * step + step / 2 - sen);
+ reg.bottom = (UINT32)(*cellY * step + step / 2 + sen);
+ return (x > reg.left && x < reg.right && y > reg.top && y < reg.bottom);
+}
+
+VOID
+DrawCursor(IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ BltLine(blt, &ctxCursor, (INT32)(x - 10), (INT32)y, (INT32)(x + 10), (INT32)y);
+ BltLine(blt, &ctxCursor, (INT32)x, (INT32)(y - 10), (INT32)x, (INT32)(y + 10));
+}
+
+typedef struct _TOUCH_ZONE {
+ UINTN Zone;
+ CHAR8* Message;
+ UINTN RetCode;
+ INT32 TextScale;
+} TOUCH_ZONE, *PTOUCH_ZONE;
+
+enum TouchZoneIds {
+ tznLogin = 1,
+ tznBeep,
+ tznShow,
+ tznChange
+};
+
+CHAR8* msgLogin = "LOGIN";
+CHAR8* msgBeepOn = "Beep\non";
+CHAR8* msgBeepOff = "Beep\noff";
+CHAR8* msgChg = "Change\npwd";
+CHAR8* msgShowPwd = "Show\npwd";
+CHAR8* msgHidePwd = "Hide\npwd";
+CHAR8* msgNewPwd = "New\npwd";
+CHAR8* msgConfirmPwd = "Confirm\npwd";
+CHAR8* msgPlatformLocked = "PLT\nlkd";
+CHAR8* msgPlatformUnLocked = "PLT\nunlkd";
+CHAR8* msgTpmLocked = "TPM\nlkd";
+CHAR8* msgTpmUnLocked = "TPM\nunlkd";
+
+TOUCH_ZONE TZN_Login = { 0, NULL, tznLogin, 128 };
+TOUCH_ZONE TZN_Speaker = { 2, NULL, tznBeep, 64 };
+TOUCH_ZONE TZN_Show = { 3, NULL, tznShow, 64 };
+TOUCH_ZONE TZN_Change = { 5, NULL, tznChange, 32 };
+TOUCH_ZONE TZN_Platform = { 6, NULL, 0, 32 };
+TOUCH_ZONE TZN_Tpm = { 7, NULL, 0, 32 };
+
+VOID
+DrawTouchZone(
+ IN PTOUCH_ZONE zone
+ ) {
+ BltFill(bltScrn, gColorBlack, (INT32)(sWidth - step), (INT32)(2 + zone->Zone * step), (INT32)(INT32)(sWidth - 2), (INT32)(step + zone->Zone * step));
+ BltBox(bltScrn, &ctxCell, (INT32)(sWidth - step), (INT32)(2 + zone->Zone * step), (INT32)(INT32)(sWidth - 2), (INT32)(step + zone->Zone * step));
+ BltText(bltScrn, &ctxCell, (INT32)(sWidth - step * 3 / 4), (INT32)(step * 1 / 3 + zone->Zone * step), 128, zone->Message);
+}
+
+BOOLEAN
+IsTouchZone(
+ IN PTOUCH_ZONE zone,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ if (x > sWidth - step &&
+ (y > (zone->Zone * step)) &&
+ (y < (step + zone->Zone * step))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+VOID
+DrawPwdZone(
+ IN CHAR8* pwd,
+ IN UINT32 pwdMax)
+{
+ INT32 pwdGrphMaxLen = (INT32)(sWidth - 2 * step);
+ BltFill(bltScrn, gColorBlack, 0, 0, (INT32)(sWidth - 2 * step), (INT32)(posPictY));
+ if (gPasswordVisible) {
+ BltText(bltScrn, &ctxCell, 0, 0, 256, pwd);
+ }
+ else {
+ INT32 pwdGrphLen = (INT32)(pwdGrphMaxLen * picPwdIdx / pwdMax);
+ INT32 pwdGrphHeight = (INT32)(posPictY) / 2;
+ INT32 pwdGrphTop = (INT32)(posPictY) / 4;
+ BltFill(bltScrn, gColorGreen, 0, pwdGrphTop, pwdGrphLen, pwdGrphHeight + pwdGrphTop);
+ BltFill(bltScrn, gColorBlack, pwdGrphLen, pwdGrphTop, pwdGrphMaxLen, pwdGrphHeight + pwdGrphTop);
+ }
+}
+
+EFI_STATUS
+DrawPwdPicture()
+{
+ EFI_STATUS res;
+ UINTN idx;
+ UINTN cellX, cellY;
+
+ if (bltPwd != NULL) MEM_FREE(bltPwd);
+
+ res = BmpToBlt(Bmp, BmpSize, &bltPwd);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ cellY = 0;
+ do {
+ cellX = 0;
+ do {
+ CellUpdate(bltPwd, cellX, cellY, FALSE);
+ cellX++;
+ } while ((cellX + 1) * step <= (bltPwd->Width));
+ cellY++;
+ } while ((cellY + 1)* step <= (bltPwd->Height));
+
+ // Update selected
+ for (idx = 0; idx < picPwdIdx; ++idx) {
+ if (cellSelected[idx * 2] != MAX_INTN) {
+ CellUpdate(bltPwd, cellSelected[idx * 2], cellSelected[idx * 2 + 1], TRUE);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+VOID
+CreateDraws() {
+ // Set
+ ctxSet.Color = gColorGray;
+ ctxSet.DashLine = 0xFFFFFFFF;
+ ctxSet.Op = DrawOpSet;
+ ctxSet.Brush = NULL;
+
+ // Cursor
+ ctxCursor.Color = gColorWhite;
+ ctxCursor.DashLine = 0xFFFFFFFF;
+ ctxCursor.Op = DrawOpXor;
+ ctxCursor.Brush = NULL;
+
+ // Cell
+ ctxCell.Color = gColorGreen;
+ ctxCell.DashLine = 0xFFFFFFFF;
+ ctxCell.Op = DrawOpSet;
+ ctxCell.Brush = gBrush3;
+
+ // Shade (close to black)
+ ctxMark.AlphaColor = gColorWhite;
+ ctxMark.Alpha = 128;
+ ctxMark.Op = DrawOpAlpha;
+ ctxMark.Brush = NULL;
+}
+
+enum PictPwdAction {
+ PwdActNone = 0,
+ PwdActLogin,
+ PwdActCancel,
+ PwdActChange,
+ PwdActShow,
+ PwdActBeep,
+ PwdActNewChar,
+ PwdActUpdateZones,
+};
+
+VOID
+AskPictPwdInt(
+ IN UINTN pwdType,
+ IN UINTN pwdMax,
+ OUT CHAR8* pwd,
+ OUT UINT32* pwdLen,
+ OUT INT32* retCode
+ ) {
+ EFI_STATUS res;
+ UINTN cellX, cellY;
+ UINTN cellPrevX, cellPrevY;
+ UINTN curX, curY;
+ UINTN curPrevX, curPrevY;
+ EFI_INPUT_KEY key;
+ EFI_EVENT UpdateEvent;
+ EFI_EVENT BeepOffEvent;
+ EFI_EVENT InputEvents[3];
+ UINTN EventIndex = 0;
+ UINTN eventsCount = 2;
+ EFI_ABSOLUTE_POINTER_STATE aps = {0};
+ BOOLEAN showCursor = FALSE;
+ BOOLEAN beepOn = FALSE;
+ UINTN pwdAction = PwdActNone;
+ CHAR8 pwdNewChar = 0;
+
+ InitConsoleControl();
+ if (gBeepEnabled) {
+ InitSpeaker();
+ }
+
+ if (Bmp == NULL) {
+ if (gPasswordPictureFileName != NULL) {
+ res = FileLoad(NULL, (CHAR16*)gPasswordPictureFileName, &Bmp, &BmpSize);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"File load - %r\n", res);
+ return;
+ }
+ } else {
+ ERR_PRINT(L"Picture file name undefined\n");
+ return;
+ }
+ }
+ // Init draws
+ CreateDraws();
+
+ // Init screen
+ if (bltScrn != NULL) MEM_FREE(bltScrn);
+ ScreenSaveBlt(&bltScrn);
+ sWidth = bltScrn->Width;
+ sHeight = bltScrn->Height;
+ step = sWidth >> 4;
+
+ // Init picture password
+ picPwdIdx = 0;
+ res = DrawPwdPicture();
+ if (EFI_ERROR(res)) {
+ MEM_FREE(bltScrn);
+ ERR_PRINT(L"BmpToBlt - %r", res);
+ return;
+ }
+
+ // Touch zones
+ switch (pwdType) {
+ case AskPwdConfirm:
+ TZN_Login.Message = msgConfirmPwd;
+ break;
+ case AskPwdNew:
+ TZN_Login.Message = msgNewPwd;
+ break;
+ case AskPwdLogin:
+ default:
+ TZN_Login.Message = msgLogin;
+ }
+ DrawTouchZone(&TZN_Login);
+
+ if (pwdType == AskPwdLogin) {
+ TZN_Change.Message = msgChg;
+ DrawTouchZone(&TZN_Change);
+ }
+
+ if (gBeepControlEnabled) {
+ TZN_Speaker.Message = gBeepEnabled ? msgBeepOff : msgBeepOn;
+ DrawTouchZone(&TZN_Speaker);
+ }
+
+ TZN_Platform.Message = gPlatformLocked? msgPlatformLocked : msgPlatformUnLocked;
+ DrawTouchZone(&TZN_Platform);
+
+ TZN_Tpm.Message = gTPMLocked ? msgTpmLocked : msgTpmUnLocked;
+ DrawTouchZone(&TZN_Tpm);
+
+ TZN_Show.Message = gPasswordVisible ? msgHidePwd : msgShowPwd;
+ DrawTouchZone(&TZN_Show);
+ cellSelected = MEM_ALLOC(sizeof(UINTN) * 2 * (pwdMax + 1));
+
+ ScreenUpdateDirty(bltScrn);
+
+ // Prepare cursors
+ posPictX = (sWidth - bltPwd->Width) >> 1;
+ posPictY = (sHeight - bltPwd->Height) >> 1;
+ cellPrevX = MAX_INTN;
+ cellPrevY = MAX_INTN;
+ curX = sWidth / 2;
+ curY = posPictY / 2;
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+
+ // Prepare events
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &BeepOffEvent);
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &UpdateEvent);
+ gBS->SetTimer(UpdateEvent, TimerRelative, 500000); // 20 times per second to update
+ gBS->SetTimer(BeepOffEvent, TimerRelative, gBeepDurationDefault * 10);
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+
+ if (gTouchPointer != NULL) {
+ eventsCount = 3;
+ InputEvents[2] = gTouchPointer->WaitForInput;
+ while (gBS->CheckEvent(InputEvents[2]) == EFI_SUCCESS) {
+ gTouchPointer->GetState(gTouchPointer, &aps);
+ }
+ }
+ while (gBS->CheckEvent(InputEvents[0]) == EFI_SUCCESS) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+ do
+ {
+ curPrevX = curX;
+ curPrevY = curY;
+ res = gBS->WaitForEvent(eventsCount, InputEvents, &EventIndex);
+ // OUT_PRINT(L" \r%05d %05d", (UINT32)curX, (UINT32)curY, );
+ // recharge timeout event and stop beep
+ if (gBeepControlEnabled && gBeepEnabled && beepOn) {
+ if (gBS->CheckEvent(BeepOffEvent) == EFI_SUCCESS) {
+ beepOn = FALSE;
+ SpeakerBeep((UINT16)gBeepToneDefault, 0, 0, 0);
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+ }
+ }
+ else {
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+ }
+
+ // hide cursor
+ if (showCursor && EventIndex != 1) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = FALSE;
+ }
+
+ // Blink cursor
+ if (EventIndex == 1) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = !showCursor;
+ }
+
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ // OUT_PRINT(L" %04x, %04x\r", key.ScanCode, key.UnicodeChar);
+
+ // Remove dirty chars 0.1s
+ FlushInputDelay(100000);
+ switch (key.ScanCode)
+ {
+ case SCAN_HOME:
+ curX -= gTouchSimulateStep;
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_LEFT:
+ curX -= gTouchSimulateStep;
+ break;
+ case SCAN_END:
+ curX -= gTouchSimulateStep;
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_DOWN:
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_PAGE_DOWN:
+ curX += gTouchSimulateStep;
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_RIGHT:
+ curX += gTouchSimulateStep;
+ break;
+ case SCAN_PAGE_UP:
+ curX += gTouchSimulateStep;
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_UP:
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_F11:
+ if (gTouchSimulateStep > 1)
+ gTouchSimulateStep--;
+ break;
+ case SCAN_F12:
+ gTouchSimulateStep++;
+ break;
+ case SCAN_ESC:
+ pwdAction = PwdActCancel;
+ break;
+ case SCAN_F2:
+ if (pwdType == AskPwdLogin) {
+ pwdAction = PwdActChange;
+ }
+ break;
+ case SCAN_F4:
+ if (gBeepControlEnabled) {
+ pwdAction = PwdActBeep;
+ }
+ break;
+ case SCAN_F5:
+ pwdAction = PwdActShow;
+ break;
+ case SCAN_F7:
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ break;
+ case SCAN_F8:
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ break;
+ default:
+ ;
+ }
+
+ if (key.UnicodeChar != 0) {
+ if (key.UnicodeChar == 0x0d) {
+ pwdAction = PwdActLogin;
+ }
+ else {
+ pwdNewChar = (CHAR8)key.UnicodeChar;
+ pwdAction = PwdActNewChar;
+ cellSelected[picPwdIdx * 2] = MAX_INTN;
+ }
+ }
+
+ }
+
+ if (EventIndex == 2) {
+ res = gTouchPointer->GetState(gTouchPointer, &aps);
+ if (!EFI_ERROR(res)) {
+ curX = (UINTN)(aps.CurrentX * sWidth / (gTouchPointer->Mode->AbsoluteMaxX - gTouchPointer->Mode->AbsoluteMinX));
+ curY = (UINTN)(aps.CurrentY * sHeight / (gTouchPointer->Mode->AbsoluteMaxY - gTouchPointer->Mode->AbsoluteMinY));
+ }
+ }
+
+ if (curX > sWidth) curX = sWidth;
+ if (curY > sHeight) curY = sHeight;
+
+ // Cell check
+ if (CellGetSelected(bltPwd, curX - posPictX, curY - posPictY, &cellX, &cellY) && picPwdIdx < pwdMax) {
+ if (cellPrevX != cellX || cellPrevY != cellY) {
+ cellPrevX = cellX;
+ cellPrevY = cellY;
+ cellSelected[picPwdIdx * 2] = cellX;
+ cellSelected[picPwdIdx * 2 + 1] = cellY;
+ CellUpdate(bltPwd, cellX, cellY, TRUE);
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+ pwdAction = PwdActNewChar;
+ pwdNewChar = gPasswordPictureChars[(cellX + bltPwd->Width / step * cellY) % gPasswordPictureCharsLen];
+ }
+ else if (EventIndex == 2 && aps.ActiveButtons == 0) {
+ cellPrevX = MAX_INTN;
+ cellPrevY = MAX_INTN;
+ curX = posPictX + cellX * step;
+ curY = posPictY + cellY * step;
+ while (gBS->CheckEvent(InputEvents[2]) == EFI_SUCCESS) {
+ gTouchPointer->GetState(gTouchPointer, &aps);
+ }
+ }
+ }
+
+ if (pwdAction == PwdActNone) {
+ if (IsTouchZone(&TZN_Login, curX, curY)) {
+ pwdAction = PwdActLogin;
+ }
+
+ if (pwdType == AskPwdLogin && IsTouchZone(&TZN_Change, curX, curY)) {
+ pwdAction = PwdActChange;
+ }
+
+ if (curPrevX != curX || curPrevY != curY) {
+ if (gSpeakerCount > 0 && IsTouchZone(&TZN_Speaker, curX, curY)) {
+ pwdAction = PwdActBeep;
+ }
+ if (IsTouchZone(&TZN_Show, curX, curY)) {
+ pwdAction = PwdActShow;
+ }
+ if (IsTouchZone(&TZN_Tpm, curX, curY)) {
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ }
+ if (IsTouchZone(&TZN_Platform, curX, curY)) {
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ }
+ }
+ }
+
+ if (PwdActNewChar == pwdAction) {
+ BOOLEAN bUpdPwdZone = FALSE;
+ if (pwdNewChar == '\b' && picPwdIdx > 0) {
+ picPwdIdx--;
+ pwd[picPwdIdx] = 0;
+ bUpdPwdZone = TRUE;
+ } else if ((picPwdIdx < pwdMax - 1) && (pwdNewChar >= 32)) {
+ pwd[picPwdIdx++] = pwdNewChar;
+ pwd[picPwdIdx] = 0;
+ bUpdPwdZone = TRUE;
+ }
+ if(bUpdPwdZone) {
+ *pwdLen = (int)picPwdIdx;
+ DrawPwdZone(pwd, (INT32)pwdMax);
+ if (gBeepControlEnabled && gBeepEnabled) {
+ SpeakerBeep((UINT16)gBeepToneDefault, gBeepNumberDefault, 0, 0);
+ gBS->SetTimer(BeepOffEvent, TimerRelative, gBeepDurationDefault * 10);
+ gBS->SetTimer(InputEvents[1], TimerRelative, gBeepDurationDefault * 10);
+ beepOn = TRUE;
+ }
+ }
+ }
+ else if (PwdActBeep == pwdAction && gBeepControlEnabled) {
+ if (gBeepEnabled && beepOn) {
+ beepOn = FALSE;
+ SpeakerBeep((UINT16)gBeepToneDefault, 0, 0, 0);
+ }
+ gBeepEnabled = gBeepEnabled ? 0 : 1;
+ TZN_Speaker.Message = gBeepEnabled ? msgBeepOff : msgBeepOn;
+ DrawTouchZone(&TZN_Speaker);
+ }
+ else if (PwdActShow == pwdAction) {
+ gPasswordVisible = gPasswordVisible ? 0 : 1;
+ DrawPwdZone(pwd, (INT32)pwdMax);
+ DrawPwdPicture();
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+ TZN_Show.Message = gPasswordVisible ? msgHidePwd : msgShowPwd;
+ DrawTouchZone(&TZN_Show);
+ }
+ else if (PwdActLogin == pwdAction) {
+ *retCode = AskPwdRetLogin;
+ break;
+ }
+ else if (pwdType == AskPwdLogin && PwdActChange == pwdAction) {
+ *retCode = AskPwdRetChange;
+ break;
+ }
+ else if (PwdActCancel == pwdAction){
+ *retCode = AskPwdRetCancel;
+ break;
+ }
+ else if (PwdActUpdateZones == pwdAction) {
+ TZN_Platform.Message = gPlatformLocked ? msgPlatformLocked : msgPlatformUnLocked;
+ DrawTouchZone(&TZN_Platform);
+
+ TZN_Tpm.Message = gTPMLocked ? msgTpmLocked : msgTpmUnLocked;
+ DrawTouchZone(&TZN_Tpm);
+ }
+
+ if (curPrevX != curX || curPrevY != curY) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = TRUE;
+ }
+ // Time to update screen?
+ if (gBS->CheckEvent(UpdateEvent) == EFI_SUCCESS) {
+ ScreenUpdateDirty(bltScrn);
+ gBS->SetTimer(UpdateEvent, TimerRelative, 500000); // 20 times per second to update
+ }
+
+ pwdAction = PwdActNone;
+ } while (TRUE);
+ gBS->CloseEvent(InputEvents[1]);
+ gBS->CloseEvent(UpdateEvent);
+ gBS->CloseEvent(BeepOffEvent);
+ ScreenFillRect(&gColorBlack, 0, 0, sWidth, sHeight);
+ gBS->Stall(500000);
+}
diff --git a/Library/PasswordLib/PlatformID.c b/Library/PasswordLib/PlatformID.c
new file mode 100644
index 0000000..351503e
--- /dev/null
+++ b/Library/PasswordLib/PlatformID.c
@@ -0,0 +1,266 @@
+/** @file
+Platform Id based on SMBIOS structures
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Guid/SmBios.h>
+#include <IndustryStandard\SmBios.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "Library/CommonLib.h"
+
+SMBIOS_TABLE_ENTRY_POINT* gSmbTable = NULL;
+EFI_GUID* gSmbSystemUUID = NULL; // Universal unique ID
+CHAR8* gSmbSystemSerial = NULL; // System serial
+CHAR8* gSmbSystemSKU = NULL; // SKU number
+CHAR8* gSmbBaseBoardSerial = NULL; // Base board serial
+UINT64* gSmbProcessorID = NULL; // Processor ID
+
+UINTN gBioIndexAuth = 0;
+typedef struct _DCS_AUTH_DATA_MARK {
+ UINT32 HeaderCrc;
+ UINT32 PlatformCrc;
+ UINT32 AuthDataSize;
+ UINT32 Reserved;
+} DCS_AUTH_DATA_MARK;
+
+CHAR8* SMBIOSGetString(UINTN StringNumber, SMBIOS_STRUCTURE* smbtbl, CHAR8* lastAddr) {
+ CHAR8* String;
+ UINTN Index;
+ String = ((UINT8*)smbtbl) + smbtbl->Length;
+ for (Index = 1; Index <= StringNumber; Index++) {
+ if (StringNumber == Index) {
+ return String;
+ }
+ //
+ // Skip string
+ //
+ while (*String != 0) {
+ String++;
+ if (String > lastAddr) {
+ return NULL;
+ }
+ }
+ String++;
+// if (*String == 0) {
+// return NULL;
+// }
+ }
+ return NULL;
+}
+
+/**
+* Get SMBIOS serial data
+*/
+EFI_STATUS
+SMBIOSGetSerials()
+{
+ EFI_STATUS res;
+ SMBIOS_STRUCTURE_POINTER pSMBIOS;
+ CHAR8* pos = NULL;
+ CHAR8* endOfTable;
+
+ // Get SMBIOS tables pointer from System Configure table
+ res = EfiGetSystemConfigurationTable(&gEfiSmbiosTableGuid, (VOID**)&gSmbTable);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ pSMBIOS.Raw = (UINT8 *)(UINTN)(gSmbTable->TableAddress);
+ pos = pSMBIOS.Raw;
+ endOfTable = pSMBIOS.Raw + gSmbTable->TableLength;
+ do {
+ SMBIOS_STRUCTURE* smbtbl = (SMBIOS_STRUCTURE*)pos;
+ // System info
+ if (smbtbl->Type == 1) {
+ gSmbSystemUUID = (EFI_GUID*)&pos[8];
+ gSmbSystemSerial = SMBIOSGetString(4, smbtbl, endOfTable);
+ gSmbSystemSKU = SMBIOSGetString(5, smbtbl, endOfTable);
+ }
+ // Base board
+ if (smbtbl->Type == 2) {
+ gSmbBaseBoardSerial = SMBIOSGetString(4, smbtbl, endOfTable);
+ }
+ // Processor
+ if (smbtbl->Type == 4) {
+ gSmbProcessorID = (UINT64*)&pos[8];
+ }
+ pos += smbtbl->Length;
+ while (((pos[0] != 0) || (pos[1] != 0)) && (pos < endOfTable)) pos++;
+ pos += 2;
+ } while (pos < endOfTable);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PlatformGetID(
+ IN EFI_HANDLE handle,
+ OUT CHAR8 **id,
+ OUT UINTN *idlength
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN idLen = 0;
+ CHAR8* idBuf = NULL;
+ CHAR8* handleSerial = NULL;
+
+ UsbGetId(handle, &handleSerial);
+ if (gSmbSystemUUID == NULL) SMBIOSGetSerials();
+ idLen += (gSmbSystemUUID == NULL) ? 0 : sizeof(*gSmbSystemUUID);
+ idLen += (gSmbSystemSerial == NULL) ? 0 : AsciiStrLen((char*)gSmbSystemSerial) + 1;
+ idLen += (gSmbSystemSKU == NULL) ? 0 : AsciiStrLen((char*)gSmbSystemSKU) + 1;
+ idLen += (gSmbBaseBoardSerial == NULL) ? 0 : AsciiStrLen((char*)gSmbBaseBoardSerial) + 1;
+ idLen += (gSmbProcessorID == NULL) ? 0 : sizeof(*gSmbProcessorID);
+ idLen += (handleSerial == NULL) ? 0 : AsciiStrLen((char*)handleSerial) + 1;
+
+ idBuf = MEM_ALLOC(idLen);
+ if (idBuf == NULL) {
+ res = EFI_BUFFER_TOO_SMALL;
+ goto error;
+ }
+
+ *id = idBuf;
+ *idlength = idLen;
+
+ if (gSmbSystemUUID != NULL) {
+ CopyMem(idBuf, gSmbSystemUUID, sizeof(*gSmbSystemUUID));
+ idBuf += sizeof(*gSmbSystemUUID);
+ }
+
+ if (gSmbSystemSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbSystemSerial) + 1;
+ CopyMem(idBuf, gSmbSystemSerial, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbSystemSKU != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbSystemSKU) + 1;
+ CopyMem(idBuf, gSmbSystemSKU, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbBaseBoardSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbBaseBoardSerial) + 1;
+ CopyMem(idBuf, gSmbBaseBoardSerial, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbProcessorID != NULL) {
+ CopyMem(idBuf, gSmbProcessorID, sizeof(*gSmbProcessorID));
+ idBuf += sizeof(*gSmbProcessorID);
+ }
+
+ if (handleSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)handleSerial) + 1;
+ CopyMem(idBuf, handleSerial, ssz);
+ idBuf += ssz;
+ MEM_FREE(handleSerial);
+ }
+
+ return res;
+
+error:
+ MEM_FREE(handleSerial);
+ MEM_FREE(idBuf);
+ return res;
+}
+
+
+EFI_STATUS
+PlatformGetIDCRC(
+ IN EFI_HANDLE handle,
+ OUT UINT32 *crc32
+ )
+{
+ EFI_STATUS res;
+ UINTN crcLen;
+ CHAR8* crcBuf = NULL;
+ res = PlatformGetID(handle, &crcBuf, &crcLen);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = gBS->CalculateCrc32(crcBuf, crcLen, crc32);
+ MEM_FREE(crcBuf);
+ return res;
+}
+
+EFI_STATUS
+PlatformGetAuthDataByType(
+ OUT UINT8 **data,
+ OUT UINTN *len,
+ OUT EFI_HANDLE *secRegionHandle,
+ IN BOOLEAN RemovableMedia)
+{
+ EFI_STATUS res;
+ UINT32 crc;
+ CHAR8* buf = NULL;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+ DCS_AUTH_DATA_MARK* mark = NULL;
+ mark = (DCS_AUTH_DATA_MARK*)MEM_ALLOC(512);
+ for (; gBioIndexAuth < gBIOCount; ++gBioIndexAuth) {
+ bio = EfiGetBlockIO(gBIOHandles[gBioIndexAuth]);
+ if (bio == NULL) continue;
+ if(bio->Media->RemovableMedia != RemovableMedia) continue;
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 61, 512, mark);
+ if (EFI_ERROR(res)) continue;
+
+ res = gBS->CalculateCrc32(&mark->PlatformCrc, sizeof(*mark) - 4, &crc);
+ if (EFI_ERROR(res)) continue;
+ if( crc != mark->HeaderCrc) continue;
+
+ res = PlatformGetIDCRC(gBIOHandles[gBioIndexAuth], &crc);
+ if (EFI_ERROR(res)) continue;
+ if (crc != mark->PlatformCrc) continue;
+
+ buf = MEM_ALLOC(mark->AuthDataSize * 1024 * 128);
+ if (buf == NULL) continue;
+
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 62, mark->AuthDataSize * 1024 * 128, buf);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(buf);
+ continue;
+ }
+ *data = buf;
+ *len = mark->AuthDataSize * 1024 * 128;
+ *secRegionHandle = gBIOHandles[gBioIndexAuth];
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_FOUND;
+}
+
+BOOLEAN gBioIndexAuthOnRemovable = TRUE;
+
+EFI_STATUS
+PlatformGetAuthData(
+ OUT UINT8 **data,
+ OUT UINTN *len,
+ OUT EFI_HANDLE *secRegionHandle
+ )
+{
+ EFI_STATUS res;
+ res = PlatformGetAuthDataByType(data, len, secRegionHandle, gBioIndexAuthOnRemovable);
+ if (EFI_ERROR(res)) {
+ if (gBioIndexAuthOnRemovable) {
+ gBioIndexAuthOnRemovable = FALSE;
+ gBioIndexAuth = 0;
+ res = PlatformGetAuthDataByType(data, len, secRegionHandle, FALSE);
+ }
+ }
+ return res;
+}
+
diff --git a/Library/VeraCryptLib/DcsVeraCrypt.c b/Library/VeraCryptLib/DcsVeraCrypt.c
new file mode 100644
index 0000000..9cf57ce
--- /dev/null
+++ b/Library/VeraCryptLib/DcsVeraCrypt.c
@@ -0,0 +1,391 @@
+/** @file
+Interface for DCS
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the Apache License, Version 2.0.
+
+The full text of the license may be found at
+https://opensource.org/licenses/Apache-2.0
+**/
+
+#include <DcsVeraCrypt.h>
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/PasswordLib.h>
+#include <Library/DcsCfgLib.h>
+
+#include <common/Password.h>
+#include "common/Crypto.h"
+#include "common/Xml.h"
+#include "common/Crc.h"
+#include "BootCommon.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Config
+//////////////////////////////////////////////////////////////////////////
+char *ConfigBuffer = NULL;
+UINTN ConfigBufferSize = 0;
+
+BOOL ConfigRead(char *configKey, char *configValue, int maxValueSize)
+{
+ char *xml;
+
+ if (ConfigBuffer == NULL)
+ FileLoad(NULL, L"\\EFI\\VeraCrypt\\DcsProp", &ConfigBuffer, &ConfigBufferSize);
+
+ xml = ConfigBuffer;
+ if (xml != NULL)
+ {
+ xml = XmlFindElementByAttributeValue(xml, "config", "key", configKey);
+ if (xml != NULL)
+ {
+ XmlGetNodeText(xml, configValue, maxValueSize);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+int ConfigReadInt(char *configKey, int defaultValue)
+{
+ char s[32];
+ if (ConfigRead(configKey, s, sizeof(s))) {
+ if (*s == '-') {
+ return (-1) * (int)AsciiStrDecimalToUintn(&s[1]);
+ }
+ return (int)AsciiStrDecimalToUintn(s);
+ }
+ else
+ return defaultValue;
+}
+
+
+char *ConfigReadString(char *configKey, char *defaultValue, char *str, int maxLen)
+{
+ if (!ConfigRead(configKey, str, maxLen)) {
+ AsciiStrCpyS(str, maxLen, defaultValue);
+ }
+ return str;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// Globals
+//////////////////////////////////////////////////////////////////////////
+#define MAX_MSG 256
+int gAuthPasswordType = 0;
+char* gAuthPasswordMsg = NULL;
+Password gAuthPassword;
+
+char* gAuthPimMsg = NULL;
+int gAuthPimRqt = 1;
+int gAuthPim = 0;
+
+int gAuthTcRqt = 0;
+int gAuthTc = 0;
+
+char *gAuthHashMsg = NULL;
+int gAuthHashRqt = 1;
+int gAuthHash = 0;
+
+int gAuthBootRqt = 0;
+int gAuthBoot = 1;
+
+int gAuthRetry = 10;
+int gAuthPwdCode = 1;
+
+INT32 gRUD = 0;
+
+int gAuthSecRegionSearch = 0;
+
+CHAR8* gPlatformKeyFile = NULL;
+UINTN gPlatformKeyFileSize = 0;
+
+EFI_GUID *gPartitionGuidOS = NULL;
+
+int gDcsBootForce = 1;
+
+CHAR8* gOnExitFailed = NULL;
+CHAR8* gOnExitSuccess = NULL;
+CHAR8* gOnExitNotFound = NULL;
+
+//////////////////////////////////////////////////////////////////////////
+// Authorize
+/////////////////////////////////////////////////////////////////////////
+
+VOID
+VCAuthLoadConfig()
+{
+ int tmp;
+
+ if (gAuthPasswordMsg != NULL) return; // Already loaded
+
+ SetMem(&gAuthPassword, sizeof(gAuthPassword), 0);
+ {
+ char* passwordPictureAscii = NULL;
+ passwordPictureAscii = MEM_ALLOC(MAX_MSG);
+ gPasswordPictureFileName = MEM_ALLOC(MAX_MSG * 2);
+ ConfigReadString("PasswordPicture", "\\EFI\\VeraCrypt\\login.bmp", passwordPictureAscii, MAX_MSG);
+ AsciiStrToUnicodeStr(passwordPictureAscii, gPasswordPictureFileName);
+ MEM_FREE(passwordPictureAscii);
+ }
+ SetMem(&gAuthPassword, sizeof(gAuthPassword), 0);
+
+ //
+ gAuthSecRegionSearch = ConfigReadInt("SecRegionSearch", 0);
+ gPlatformLocked = ConfigReadInt("PlatformLocked", 0);
+ gTPMLocked = ConfigReadInt("TPMLocked", 0);
+ gSCLocked = ConfigReadInt("SCLocked", 0);
+ gDcsBootForce = ConfigReadInt("DcsBootForce", 1);
+
+ // Actions for DcsInt
+ gOnExitSuccess = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("ActionSuccess", "Exit", gOnExitSuccess, MAX_MSG);
+ gOnExitNotFound = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("ActionNotFound", "Exit", gOnExitNotFound, MAX_MSG);
+ gOnExitFailed = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("ActionFailed", "Exit", gOnExitFailed, MAX_MSG);
+
+ {
+ char* strTemp = NULL;
+ strTemp = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("PartitionGuidOS", "", strTemp, MAX_MSG);
+ if (strTemp[0] != 0) {
+ EFI_GUID g;
+ if (AsciiStrToGuid(&g, strTemp)) {
+ gPartitionGuidOS = MEM_ALLOC(sizeof(EFI_GUID));
+ if (gPartitionGuidOS != NULL) {
+ memcpy(gPartitionGuidOS, &g, sizeof(g));
+ }
+ }
+ }
+ MEM_FREE(strTemp);
+ }
+
+ gPasswordPictureChars = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("PictureChars", gPasswordPictureCharsDefault, gPasswordPictureChars, MAX_MSG);
+ gPasswordPictureCharsLen = strlen(gPasswordPictureChars);
+
+ gAuthPasswordType = ConfigReadInt("PasswordType", 0);
+ gAuthPasswordMsg = MEM_ALLOC(MAX_MSG);
+ ConfigReadString("PasswordMsg", "Password:", gAuthPasswordMsg, MAX_MSG);
+
+ gAuthPimMsg = MEM_ALLOC(MAX_MSG);
+ gAuthPimRqt = ConfigReadInt("PimRqt", 1);
+ gAuthPim = ConfigReadInt("Pim", 0);
+ ConfigReadString("PimMsg", "Pim:", gAuthPimMsg, MAX_MSG);
+
+ gAuthHashMsg = MEM_ALLOC(MAX_MSG);
+ gAuthHashRqt = ConfigReadInt("HashRqt", 1);
+ gAuthHash = ConfigReadInt("Hash", 0);
+ ConfigReadString("HashMsg", "(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) RIPEMD160\n\rHash:", gAuthHashMsg, MAX_MSG);
+
+ gPasswordVisible = (UINT8)ConfigReadInt("AuthorizeVisible", 0);
+ gPasswordShowMark = ConfigReadInt("AuthorizeMarkTouch", 1);
+ gAuthBootRqt = ConfigReadInt("BootRqt", 0);
+ gAuthTcRqt = ConfigReadInt("TcRqt", 0);
+ gRUD = ConfigReadInt("RUD", 0);
+ gAuthRetry = ConfigReadInt("AuthorizeRetry", 10);
+
+ // touch
+ tmp = ConfigReadInt("TouchDevice", -1);
+ if (tmp == -1) InitTouch();
+ if (tmp >= 0) {
+ if (gTouchCount == 0) InitTouch();
+ if (tmp < (int)gTouchCount) {
+ TouchGetIO(gTouchHandles[tmp], &gTouchPointer);
+ }
+ }
+ gTouchSimulate = ConfigReadInt("TouchSimulate", 0);
+
+ // Graph
+ tmp = ConfigReadInt("GraphDevice", -1);
+ if (tmp == -1) InitGraph();
+ if (tmp >= 0) {
+ if (gGraphCount == 0) InitGraph();
+ if (tmp < (int)gGraphCount) {
+ GraphGetIO(gGraphHandles[tmp], &gGraphOut);
+ }
+ }
+ if (gGraphOut != NULL) {
+ tmp = ConfigReadInt("GraphMode", -1);
+ if (tmp >= 0 && tmp <= (int)gGraphOut->Mode->MaxMode) {
+ gGraphOut->SetMode(gGraphOut, tmp);
+ }
+ }
+
+ // Beep
+ gBeepEnabled = ConfigReadInt("Beep", 0);
+ if (gBeepEnabled) {
+ gBeepNumberDefault = ConfigReadInt("BeepNumber", 1);
+ gBeepDurationDefault = ConfigReadInt("BeepDuration", 100);
+ gBeepIntervalDefault = ConfigReadInt("BeepInterval", 0);
+ gBeepToneDefault = ConfigReadInt("BeepTone", 0x500);
+ gBeepControlEnabled = ConfigReadInt("BeepControl", 1) != 0;
+
+ tmp = ConfigReadInt("BeepDevice", -1);
+ if (tmp == -1) InitSpeaker();
+ if (tmp >= 0) {
+ if (gSpeakerCount == 0) InitSpeaker();
+ if (tmp < (int)gSpeakerCount) {
+ SpeakerSelect(tmp);
+ }
+ }
+ }
+
+}
+
+
+VOID
+VCAskPwd(
+ IN UINTN pwdType,
+ OUT Password* vcPwd) {
+ if (gAuthPasswordMsg == NULL) VCAuthLoadConfig();
+ if (gAuthPasswordType == 1 &&
+ gGraphOut != NULL &&
+ ((gTouchPointer != NULL) || (gTouchSimulate != 0))) {
+ AskPictPwdInt(pwdType, sizeof(vcPwd->Text), vcPwd->Text, &vcPwd->Length, &gAuthPwdCode);
+ } else {
+ switch (pwdType) {
+ case AskPwdNew:
+ OUT_PRINT(L"New password:");
+ break;
+ case AskPwdConfirm:
+ OUT_PRINT(L"Confirm password:");
+ break;
+ case AskPwdLogin:
+ default:
+ OUT_PRINT(L"%a", gAuthPasswordMsg);
+ break;
+ }
+ AskConsolePwdInt(&vcPwd->Length, vcPwd->Text, &gAuthPwdCode, sizeof(vcPwd->Text), gPasswordVisible);
+ }
+
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return;
+ }
+
+ if (gPlatformLocked) {
+ if (gPlatformKeyFile == NULL) {
+ ERR_PRINT(L"Platform key file absent\n");
+ } else {
+ ApplyKeyFile(vcPwd, gPlatformKeyFile, gPlatformKeyFileSize);
+ }
+ }
+
+ if (gTPMLocked) {
+ // TO DO
+ ERR_PRINT(L"TPM lock is not implemented\n");
+ }
+}
+
+VOID
+VCAuthAsk()
+{
+ VCAskPwd(AskPwdLogin, &gAuthPassword);
+
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return;
+ }
+
+ if (gAuthPimRqt) {
+ gAuthPim = AskInt(gAuthPimMsg, gPasswordVisible);
+ }
+ if (gAuthTcRqt) {
+ gAuthTc = AskConfirm("True crypt mode [N]?", gPasswordVisible);
+ }
+
+ if (gAuthBootRqt) {
+ gAuthBoot = AskConfirm("Boot mount mode [N]?", gPasswordVisible);
+ }
+
+ if (gAuthHashRqt) {
+ do {
+ gAuthHash = AskInt(gAuthHashMsg, gPasswordVisible);
+ } while (gAuthHash < 0 || gAuthHash > 4);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// VeraCrypt helpers
+//////////////////////////////////////////////////////////////////////////
+void* VeraCryptMemAlloc(IN UINTN size) {
+ return MEM_ALLOC(size);
+}
+
+void VeraCryptMemFree(IN VOID* ptr) {
+ MEM_FREE(ptr);
+}
+void ThrowFatalException(int line) {
+ ERR_PRINT(L"Fatal %d\n", line);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Random data
+//////////////////////////////////////////////////////////////////////////
+BOOL
+RandgetBytes(unsigned char *buf, int len, BOOL forceSlowPoll) {
+ EFI_STATUS res;
+ res = RndGetBytes(buf, len);
+ return !EFI_ERROR(res);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Key file
+//////////////////////////////////////////////////////////////////////////
+
+#define KEYFILE_POOL_SIZE 64
+#define KEYFILE_MAX_READ_LEN (1024*1024)
+
+VOID
+ApplyKeyFile(
+ IN OUT Password* password,
+ IN CHAR8* keyfileData,
+ IN UINTN keyfileDataSize
+ )
+{
+ unsigned __int32 crc = 0xffffffff;
+ int writePos = 0;
+ size_t totalRead = 0;
+ size_t i;
+ CHAR8 keyPool[KEYFILE_POOL_SIZE];
+
+ ZeroMem(keyPool, sizeof(keyPool));
+
+ for (i = 0; i < keyfileDataSize; i++)
+ {
+ crc = UPDC32(keyfileData[i], crc);
+
+ keyPool[writePos++] += (unsigned __int8)(crc >> 24);
+ keyPool[writePos++] += (unsigned __int8)(crc >> 16);
+ keyPool[writePos++] += (unsigned __int8)(crc >> 8);
+ keyPool[writePos++] += (unsigned __int8)crc;
+
+ if (writePos >= KEYFILE_POOL_SIZE)
+ writePos = 0;
+
+ if (++totalRead >= KEYFILE_MAX_READ_LEN)
+ break;
+ }
+
+ for (i = 0; i < sizeof(keyPool); i++)
+ {
+ if (i < password->Length)
+ password->Text[i] += keyPool[i];
+ else
+ password->Text[i] = keyPool[i];
+ }
+
+ if (password->Length < (int)sizeof(keyPool))
+ password->Length = sizeof(keyPool);
+
+} \ No newline at end of file
diff --git a/Library/VeraCryptLib/DcsVeraCrypt.h b/Library/VeraCryptLib/DcsVeraCrypt.h
new file mode 100644
index 0000000..aae0152
--- /dev/null
+++ b/Library/VeraCryptLib/DcsVeraCrypt.h
@@ -0,0 +1,84 @@
+/** @file
+Interface for DCS services
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the Apache License, Version 2.0.
+
+The full text of the license may be found at
+https://opensource.org/licenses/Apache-2.0
+**/
+
+#ifndef __DCSVERACRYPT_H__
+#define __DCSVERACRYPT_H__
+
+#include <Uefi.h>
+#include <common/Tcdefs.h>
+#include <common/Password.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Auth
+//////////////////////////////////////////////////////////////////////////
+extern int gAuthPasswordType;
+extern CHAR16* gPasswordPictureFileName;
+extern char* gAuthPasswordMsg;
+extern Password gAuthPassword;
+
+extern char* gAuthPimMsg;
+extern int gAuthPimRqt;
+extern int gAuthPim;
+
+extern int gAuthTcRqt;
+extern int gAuthTc;
+
+extern char *gAuthHashMsg;
+extern int gAuthHashRqt;
+extern int gAuthHash;
+
+extern int gAuthBootRqt;
+extern int gAuthBoot;
+
+extern int gAuthRetry;
+extern INT32 gRUD;
+
+extern int gAuthSecRegionSearch;
+
+extern int gPlatformLocked;
+extern int gTPMLocked;
+extern int gSCLocked;
+
+extern int gAuthPwdCode;
+
+extern CHAR8* gPlatformKeyFile;
+extern UINTN gPlatformKeyFileSize;
+
+extern EFI_GUID *gPartitionGuidOS;
+extern int gDcsBootForce;
+
+extern CHAR8* gOnExitFailed;
+extern CHAR8* gOnExitSuccess;
+extern CHAR8* gOnExitNotFound;
+
+void
+VCAuthAsk();
+
+VOID
+VCAskPwd(
+ IN UINTN pwdType,
+ OUT Password* vcPwd);
+
+VOID
+VCAuthLoadConfig();
+
+VOID
+ApplyKeyFile(
+ IN OUT Password* password,
+ IN CHAR8* keyfileData,
+ IN UINTN keyfileDataSize
+ );
+
+#endif
+
diff --git a/Library/VeraCryptLib/VeraCryptLib.inf b/Library/VeraCryptLib/VeraCryptLib.inf
new file mode 100644
index 0000000..a4f257b
--- /dev/null
+++ b/Library/VeraCryptLib/VeraCryptLib.inf
@@ -0,0 +1,120 @@
+## @file
+# Library used for DCS
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = VeraCryptLib
+ MODULE_UNI_FILE = VeraCryptLib.uni
+ FILE_GUID = 6E5F01BD-D550-40AC-AC63-167DE971E3A1
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = VeraCryptLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+common\Crc.c
+common\Crc.h
+common\Crypto.c
+common\Crypto.h
+common\Endian.c
+common\Endian.h
+common\GfMul.h
+common\Password.h
+common\Pkcs5.c
+common\Pkcs5.h
+common\Tcdefs.h
+common\Volumes.c
+common\Volumes.h
+common\Xts.c
+common\Xts.h
+common\Xml.c
+common\Xml.h
+crypto\Aes.h
+crypto\Aeskey.c
+crypto\Aesopt.h
+crypto\Aestab.c
+crypto\Aestab.h
+crypto\Aes_hw_cpu.nasm
+crypto\Aes_hw_cpu.h
+crypto\config.h
+crypto\Rmd160.c
+crypto\Rmd160.h
+crypto\Serpent.c
+crypto\Serpent.h
+crypto\Sha2.c
+crypto\Sha2.h
+crypto\Twofish.c
+crypto\Twofish.h
+crypto\Whirlpool.c
+crypto\Whirlpool.h
+crypto\GostCipher.c
+crypto\GostCipher.h
+crypto\Streebog.c
+crypto\Streebog.h
+crypto\kuznyechik.c
+crypto\kuznyechik.h
+crypto\Camellia.c
+crypto\Camellia.h
+crypto\cpu.c
+crypto\cpu.h
+DcsVeraCrypt.c
+DcsVeraCrypt.h
+
+[Sources.X64]
+crypto\Aes_x64.nasm
+crypto\Gost89_x64.nasm
+
+[Sources.IA32]
+llmath.c
+crypto\Aes_x86.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ RngLib
+
+[Protocols]
+
+
+[BuildOptions.IA32]
+DEBUG_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /FAcs /D_UEFI
+RELEASE_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /FAcs /D_UEFI
+NOOPT_VS2010x86_IA32_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /Od /FAcs /D_UEFI
+
+DEBUG_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /FAcs /D_UEFI
+RELEASE_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /FAcs /D_UEFI
+NOOPT_VS2015x86_IA32_CC_FLAGS == /arch:IA32 /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /Od /FAcs /D_UEFI
+
+RELEASE_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+DEBUG_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+NOOPT_VS2010x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+
+RELEASE_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+DEBUG_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+NOOPT_VS2015x86_IA32_NASM_FLAGS = -Xvc --prefix _ -d_UEFI=1
+
+[BuildOptions.X64]
+DEBUG_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /D_UEFI
+RELEASE_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /D_UEFI
+NOOPT_VS2010x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od /D_UEFI
+
+DEBUG_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /D_UEFI
+RELEASE_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /D_UEFI
+NOOPT_VS2015x86_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od /D_UEFI
+
+RELEASE_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+DEBUG_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+NOOPT_VS2010x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+
+RELEASE_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+DEBUG_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
+NOOPT_VS2015x86_X64_NASM_FLAGS = -Xvc -d_UEFI=1
diff --git a/Library/VeraCryptLib/llmath.c b/Library/VeraCryptLib/llmath.c
new file mode 100644
index 0000000..6b4360c
--- /dev/null
+++ b/Library/VeraCryptLib/llmath.c
@@ -0,0 +1,383 @@
+#include <uefi.h>
+void __cdecl atexit() {}
+
+int __cdecl _purecall() { return 0; }
+
+#if defined(_M_IX86)
+//////////////////////////////////////////////////////////////////////////
+// _allmul
+//////////////////////////////////////////////////////////////////////////
+__declspec(naked) void __cdecl _allmul(void)
+{
+ _asm {
+ mov ebx, [esp + 4] ; ebx <- M1[0..31]
+ mov edx, [esp + 12] ; edx <- M2[0..31]
+ mov ecx, ebx
+ mov eax, edx
+ imul ebx, [esp + 16] ; ebx <- M1[0..31] * M2[32..63]
+ imul edx, [esp + 8] ; edx <- M1[32..63] * M2[0..31]
+ add ebx, edx ; carries are abandoned
+ mul ecx ; edx:eax <- M1[0..31] * M2[0..31]
+ add edx, ebx ; carries are abandoned
+ ret 16
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// _aullmul
+//////////////////////////////////////////////////////////////////////////
+__declspec(naked) void __cdecl _aullmul()
+{
+ _asm {
+ mov ebx, [esp + 4] ; ebx <- M1[0..31]
+ mov edx, [esp + 12] ; edx <- M2[0..31]
+ mov ecx, ebx
+ mov eax, edx
+ imul ebx, [esp + 16] ; ebx <- M1[0..31] * M2[32..63]
+ imul edx, [esp + 8] ; edx <- M1[32..63] * M2[0..31]
+ add ebx, edx ; carries are abandoned
+ mul ecx ; edx:eax <- M1[0..31] * M2[0..31]
+ add edx, ebx ; carries are abandoned
+ ret 16
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// _alldiv
+//////////////////////////////////////////////////////////////////////////
+__declspec(naked) void __cdecl _alldiv()
+{
+ _asm {
+ ; Check sign of res
+ mov ebx, [esp + 8] ; dividend msdw
+ mov ecx, [esp + 16] ; divisor msdw
+ xor ebx, ecx
+ shr ebx, 31
+ jz _PosRes ; if Result is positive
+ push 1 ; if is negative
+ jmp _Preparing
+ _PosRes:
+ push 0
+
+ ; Preparing operands
+ ; Dividend
+ _Preparing:
+ mov ecx, [esp + 12]
+ shr ecx, 31
+ jz _ChkDvsr ; Divident is positive
+ mov eax, [esp + 12] ; is negative
+ mov ecx, [esp + 8]
+ xor eax, 0xFFFFFFFF
+ xor ecx, 0xFFFFFFFF
+ add ecx, 1
+ jnc _DvntOK
+ adc eax, 0
+ _DvntOK:
+ mov [esp + 12], eax
+ mov [esp + 8], ecx
+
+ ; Divisor
+ _ChkDvsr:
+ mov ecx, [esp + 20]
+ shr ecx, 31
+ jz _Divide ; Divisor is positive
+ mov eax, [esp + 20] ; is negative
+ mov ecx, [esp + 16]
+ xor eax, 0xFFFFFFFF
+ xor ecx, 0xFFFFFFFF
+ add ecx, 1
+ jnc _DvsrOK
+ adc eax, 0
+ _DvsrOK:
+ mov [esp + 20], eax
+ mov [esp + 16], ecx
+
+ _Divide:
+ mov ecx, [esp + 20] ; ecx <- divisor[32..63]
+ test ecx, ecx
+ jnz __DivRemU64x64 ; call __DivRemU64x64 if Divisor > 2^32
+ mov ecx, [esp + 16] ; ecx <- divisor
+ mov eax, [esp + 12] ; eax <- dividend[32..63]
+ xor edx, edx
+ div ecx ; eax <- quotient[32..63], edx <- remainder
+ push eax
+ mov eax, [esp + 12] ; eax <- dividend[0..31]
+ div ecx ; eax <- quotient[0..31]
+ pop edx ; edx <- quotient[32..63] - edx:eax
+ jmp _GetSign
+
+ __DivRemU64x64:
+ mov edx, dword ptr [esp + 12]
+ mov eax, dword ptr [esp + 8] ; edx:eax <- dividend
+ mov edi, edx
+ mov esi, eax ; edi:esi <- dividend
+ mov ebx, dword ptr [esp + 16] ; ecx:ebx <- divisor
+ _B:
+ shr edx, 1
+ rcr eax, 1
+ shrd ebx, ecx, 1
+ shr ecx, 1
+ jnz _B
+ div ebx
+ mov ebx, eax ; ebx <- quotient
+ mov ecx, [esp + 20] ; ecx <- high dword of divisor
+ mul dword ptr [esp + 16] ; edx:eax <- quotient * divisor[0..31]
+ imul ecx, ebx ; ecx <- quotient * divisor[32..63]
+ add edx, ecx ; edx <- (quotient * divisor)[32..63]
+ ;mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder
+ jc _TooLarge ; product > 2^64
+ cmp edi, edx ; compare high 32 bits
+ ja _Correct
+ jb _TooLarge ; product > dividend
+ cmp esi, eax
+ jae _Correct ; product <= dividend
+ _TooLarge:
+ dec ebx ; adjust quotient by -1
+ jecxz _Return ; return if Remainder == NULL
+ sub eax, dword ptr [esp + 16]
+ sbb edx, dword ptr [esp + 20] ; edx:eax <- (quotient - 1) * divisor
+ _Correct:
+ jecxz _Return
+ sub esi, eax
+ sbb edi, edx ; edi:esi <- remainder
+ ;mov [ecx], esi
+ ;mov [ecx + 4], edi
+ _Return:
+ mov eax, ebx ; eax <- quotient
+ xor edx, edx ; quotient is 32 bits long
+
+ ; Get sign of result
+ _GetSign:
+ pop ecx ; Sign of res
+ jecxz _Rtrn ; Result is positive
+ xor eax, 0xFFFFFFFF
+ xor edx, 0xFFFFFFFF
+ add eax, 1 ; edx:eax
+ jnc _Rtrn
+ adc edx, 0
+
+ _Rtrn:
+ ret 16
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// _aulldiv
+//////////////////////////////////////////////////////////////////////////
+__declspec(naked) void __cdecl _aulldiv()
+{
+ _asm {
+ mov ecx, [esp + 16] ; ecx <- divisor[32..63]
+ test ecx, ecx
+ jnz __DivRemU64x64 ; call __DivRemU64x64 if Divisor > 2^32
+ mov ecx, [esp + 12] ; ecx <- divisor
+ mov eax, [esp + 8] ; eax <- dividend[32..63]
+ xor edx, edx
+ div ecx ; eax <- quotient[32..63], edx <- remainder
+ push eax
+ mov eax, [esp + 8] ; eax <- dividend[0..31]
+ div ecx ; eax <- quotient[0..31]
+ pop edx ; edx <- quotient[32..63]
+ ret 16
+
+ __DivRemU64x64:
+ mov edx, dword ptr [esp + 8]
+ mov eax, dword ptr [esp + 4] ; edx:eax <- dividend
+ mov edi, edx
+ mov esi, eax ; edi:esi <- dividend
+ mov ebx, dword ptr [esp + 12] ; ecx:ebx <- divisor
+ _B:
+ shr edx, 1
+ rcr eax, 1
+ shrd ebx, ecx, 1
+ shr ecx, 1
+ jnz _B
+ div ebx
+ mov ebx, eax ; ebx <- quotient
+ mov ecx, [esp + 16] ; ecx <- high dword of divisor
+ mul dword ptr [esp + 12] ; edx:eax <- quotient * divisor[0..31]
+ imul ecx, ebx ; ecx <- quotient * divisor[32..63]
+ add edx, ecx ; edx <- (quotient * divisor)[32..63]
+ ;mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder
+ jc _TooLarge ; product > 2^64
+ cmp edi, edx ; compare high 32 bits
+ ja _Correct
+ jb _TooLarge ; product > dividend
+ cmp esi, eax
+ jae _Correct ; product <= dividend
+ _TooLarge:
+ dec ebx ; adjust quotient by -1
+ jecxz _Return ; return if Remainder == NULL
+ sub eax, dword ptr [esp + 12]
+ sbb edx, dword ptr [esp + 16] ; edx:eax <- (quotient - 1) * divisor
+ _Correct:
+ jecxz _Return
+ sub esi, eax
+ sbb edi, edx ; edi:esi <- remainder
+ ;mov [ecx], esi
+ ;mov [ecx + 4], edi
+ _Return:
+ mov eax, ebx ; eax <- quotient
+ xor edx, edx ; quotient is 32 bits long
+
+ ret 16
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Shifts
+//////////////////////////////////////////////////////////////////////////
+__declspec(naked) void __cdecl _aullshr() {
+ _asm {
+ ;
+ ; Checking: Only handle 64bit shifting or more
+ ;
+ cmp cl, 64
+ jae _Exit
+
+ ;
+ ; Handle shifting between 0 and 31 bits
+ ;
+ cmp cl, 32
+ jae More32
+ shrd eax, edx, cl
+ shr edx, cl
+ ret
+
+ ;
+ ; Handle shifting of 32-63 bits
+ ;
+More32:
+ mov eax, edx
+ xor edx, edx
+ and cl, 31
+ shr eax, cl
+ ret
+
+ ;
+ ; Invalid number (less then 32bits), return 0
+ ;
+_Exit:
+ xor eax, eax
+ xor edx, edx
+ ret
+ }
+}
+
+__declspec(naked) void __cdecl _allshl() {
+ _asm {
+ ;
+ ; Handle shifting of 64 or more bits (return 0)
+ ;
+ cmp cl, 64
+ jae short ReturnZero
+
+ ;
+ ; Handle shifting of between 0 and 31 bits
+ ;
+ cmp cl, 32
+ jae short More32
+ shld edx, eax, cl
+ shl eax, cl
+ ret
+
+ ;
+ ; Handle shifting of between 32 and 63 bits
+ ;
+More32:
+ mov edx, eax
+ xor eax, eax
+ and cl, 31
+ shl edx, cl
+ ret
+
+ReturnZero:
+ xor eax,eax
+ xor edx,edx
+ ret
+ }
+}
+
+UINT64
+EFIAPI
+DivU64x64Remainder(
+IN UINT64 Dividend,
+IN UINT64 Divisor,
+OUT UINT64 *Remainder OPTIONAL
+);
+/*
+ * Divides a 64-bit unsigned value by another 64-bit unsigned value and returns
+ * the 64-bit unsigned remainder.
+ */
+__declspec(naked) void __cdecl _aullrem(void)
+{
+ //
+ // Wrapper Implementation over EDKII DivU64x64Remainder() routine
+ // UINT64
+ // EFIAPI
+ // DivU64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder OPTIONAL
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _aullrem
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for Reminder pointer
+ ;
+ sub esp, 8
+ push esp
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Call native DivU64x64Remainder of BaseLib
+ ;
+ call DivU64x64Remainder
+
+ ;
+ ; Put the Reminder in EDX:EAX as return value
+ ;
+ mov eax, [esp + 20]
+ mov edx, [esp + 24]
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 28
+
+ ret 16
+ }
+}
+
+#endif
diff --git a/Library/VeraCryptLib/mklinks_src.bat b/Library/VeraCryptLib/mklinks_src.bat
new file mode 100644
index 0000000..aad3094
--- /dev/null
+++ b/Library/VeraCryptLib/mklinks_src.bat
@@ -0,0 +1,112 @@
+@echo off
+pushd %~dp0
+
+call :select_path "%veracrypt_src%" "Select VeraCrypt directory:"
+set veracrypt_src=%select_path_result%
+
+set /P YesNo=Create links[Y/N]?
+if /I ["%YesNo%"]==["Y"] goto :check_links
+goto :end
+
+:check_links
+if NOT EXIST common goto :create_links
+set /P create_links_del_ren=Old links detected [D]elete or [R]ename?
+
+:create_links
+if NOT EXIST common mkdir common
+call :create_link common\Crc.c
+call :create_link common\Crc.h
+call :create_link common\Crypto.c
+call :create_link common\Crypto.h
+call :create_link common\Endian.c
+call :create_link common\Endian.h
+call :create_link common\GfMul.h
+call :create_link common\Password.h
+call :create_link common\Pkcs5.c
+call :create_link common\Pkcs5.h
+call :create_link common\Tcdefs.h
+call :create_link common\Volumes.c
+call :create_link common\Volumes.h
+call :create_link common\Xml.c
+call :create_link common\Xml.h
+call :create_link common\Xts.c
+call :create_link common\Xts.h
+
+if NOT EXIST crypto mkdir crypto
+call :create_link crypto\GostCipher.c
+call :create_link crypto\GostCipher.h
+call :create_link crypto\Gost89_x64.asm Gost89_x64.nasm
+call :create_link crypto\Streebog.c
+call :create_link crypto\Streebog.h
+call :create_link crypto\kuznyechik.c
+call :create_link crypto\kuznyechik.h
+call :create_link crypto\Aes.h
+call :create_link crypto\Aeskey.c
+call :create_link crypto\Aesopt.h
+call :create_link crypto\Aestab.c
+call :create_link crypto\Aestab.h
+call :create_link crypto\Aes_hw_cpu.h
+call :create_link crypto\Aes_hw_cpu.asm Aes_hw_cpu.nasm
+call :create_link crypto\Aes_x64.asm Aes_x64.nasm
+call :create_link crypto\Aes_x86.asm Aes_x86.nasm
+call :create_link crypto\cpu.h
+call :create_link crypto\cpu.c
+call :create_link crypto\config.h
+call :create_link crypto\misc.h
+call :create_link crypto\Rmd160.c
+call :create_link crypto\Rmd160.h
+call :create_link crypto\Serpent.c
+call :create_link crypto\Serpent.h
+call :create_link crypto\Sha2.c
+call :create_link crypto\Sha2.h
+call :create_link crypto\Twofish.c
+call :create_link crypto\Twofish.h
+call :create_link crypto\Whirlpool.c
+call :create_link crypto\Whirlpool.h
+call :create_link crypto\Camellia.c
+call :create_link crypto\Camellia.h
+
+set create_link_skip_pushd=Y
+call :create_link Boot\Windows\BootCommon.h
+call :create_link Boot\Windows\BootDefs.h
+set create_link_skip_pushd=N
+
+goto :end
+
+:create_link
+if /I NOT ["%create_link_skip_pushd%"]==["Y"] pushd %~dp1
+set fn=%~n1%~x1
+if NOT ["%2"]==[""] set fn=%2
+call :get_bak_name %fn%
+if /I ["%create_links_del_ren%"]==["R"] ren %fn% %name_bak%
+if EXIST "%fn%" del %fn%
+@echo on
+mklink /H %fn% %veracrypt_src%\%1
+@echo off
+if /I NOT ["%create_link_skip_pushd%"]==["Y"] popd
+goto :eof
+
+:get_bak_name
+set name_bak=%1
+:get_bak_name_retry
+if NOT EXIST %name_bak% goto :eof
+set name_bak=%name_bak%.sv
+goto :get_bak_name_retry
+
+rem call select path
+:select_path
+set select_path_default=%1
+if not exist "%select_path_default%" echo not found %select_path_default%
+set select_path_msg=%2
+set select_path_msg=%select_path_msg:~1,-1%
+
+:select_path_retry
+set select_path_result=
+set /p select_path_result=[%select_path_default:~1,-1%] %select_path_msg%
+if ["%select_path_result%"]==[""] set select_path_result=%select_path_default:~1,-1%
+if exist %select_path_result% goto :eof
+echo can not find %select_path_result%
+goto :select_path_retry
+
+:end
+popd \ No newline at end of file
diff --git a/SecureBoot/certs/DCS_key_exchange.crt b/SecureBoot/certs/DCS_key_exchange.crt
new file mode 100644
index 0000000..80bc7ca
--- /dev/null
+++ b/SecureBoot/certs/DCS_key_exchange.crt
Binary files differ
diff --git a/SecureBoot/certs/DCS_platform.crt b/SecureBoot/certs/DCS_platform.crt
new file mode 100644
index 0000000..a7cf8ce
--- /dev/null
+++ b/SecureBoot/certs/DCS_platform.crt
Binary files differ
diff --git a/SecureBoot/certs/DCS_sign.crt b/SecureBoot/certs/DCS_sign.crt
new file mode 100644
index 0000000..f0538db
--- /dev/null
+++ b/SecureBoot/certs/DCS_sign.crt
Binary files differ
diff --git a/SecureBoot/certs/MicCorUEFCA2011_2011-06-27.crt b/SecureBoot/certs/MicCorUEFCA2011_2011-06-27.crt
new file mode 100644
index 0000000..9aa6ac6
--- /dev/null
+++ b/SecureBoot/certs/MicCorUEFCA2011_2011-06-27.crt
Binary files differ
diff --git a/SecureBoot/certs/MicWinProPCA2011_2011-10-19.crt b/SecureBoot/certs/MicWinProPCA2011_2011-10-19.crt
new file mode 100644
index 0000000..a6d001c
--- /dev/null
+++ b/SecureBoot/certs/MicWinProPCA2011_2011-10-19.crt
Binary files differ
diff --git a/SecureBoot/certs/readme.txt b/SecureBoot/certs/readme.txt
new file mode 100644
index 0000000..29bed3c
--- /dev/null
+++ b/SecureBoot/certs/readme.txt
@@ -0,0 +1,3 @@
+There are two public DB entries - one for Windows and one for the UEFI Certificate Authority (CA).
+Windows DB: http://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt
+UEFI DB: http://www.microsoft.com/pkiops/certs/MicCorUEFCA2011_2011-06-27.crt
diff --git a/SecureBoot/efi_sign.bat b/SecureBoot/efi_sign.bat
new file mode 100644
index 0000000..4b4b764
--- /dev/null
+++ b/SecureBoot/efi_sign.bat
@@ -0,0 +1 @@
+signtool sign /ac %3 /f %2 /fd sha256 %1 \ No newline at end of file
diff --git a/SecureBoot/readme.txt b/SecureBoot/readme.txt
new file mode 100644
index 0000000..6e2dc43
--- /dev/null
+++ b/SecureBoot/readme.txt
@@ -0,0 +1,13 @@
+To update secure boot configuration
+1. Enter BIOS configuration
+2. Switch Secure boot to setup mode (or custom mode). It deletes PK (platform certificate) and allows to load DCS platform key.
+3. Boot Windows
+4. execute from admin command prompt
+ powershell -File sb_set_siglists.ps1
+It sets in PK (platform key) - DCS_platform
+It sets in KEK (key exchange key) - DCS_key_exchange
+It sets in db - DCS_sign MicWinProPCA2011_2011-10-19 MicCorUEFCA2011_2011-06-27
+
+All DCS modules are protected by DCS_sign.
+All Windows modules are protected by MicWinProPCA2011_2011-10-19
+All SHIM(linux) modules are protected by MicCorUEFCA2011_2011-06-27 \ No newline at end of file
diff --git a/SecureBoot/sb_set_siglists.ps1 b/SecureBoot/sb_set_siglists.ps1
new file mode 100644
index 0000000..ae53ca8
--- /dev/null
+++ b/SecureBoot/sb_set_siglists.ps1
@@ -0,0 +1,22 @@
+Set-ExecutionPolicy Bypass -Force
+Import-Module secureboot
+
+Set-SecureBootUEFI -Name PK -Time 2015-09-11 -Content $null
+Set-SecureBootUEFI -Name KEK -Time 2015-09-11 -Content $null
+Set-SecureBootUEFI -Name db -Time 2015-09-11 -Content $null
+Set-SecureBootUEFI -Name dbx -Time 2015-09-11 -Content $null
+
+Write-Host "Setting self-signed PK..."
+Set-SecureBootUEFI -Time 2016-08-08T00:00:00Z -ContentFilePath siglists\DCS_platform_SigList.bin -SignedFilePath siglists\DCS_platform_SigList_Serialization.bin.p7 -Name PK
+
+Write-Host "Setting PK-signed KEK..."
+Set-SecureBootUEFI -Time 2016-08-08T00:00:00Z -ContentFilePath siglists\DCS_key_exchange_SigList.bin -SignedFilePath siglists\DCS_key_exchange_SigList_Serialization.bin.p7 -Name KEK
+
+Write-Host "Setting KEK-signed DCS cert in db..."
+Set-SecureBootUEFI -Time 2016-08-08T00:00:00Z -ContentFilePath siglists\DCS_sign_SigList.bin -SignedFilePath siglists\DCS_sign_SigList_Serialization.bin.p7 -Name db
+
+Write-Host "Setting KEK-signed MS cert in db..."
+Set-SecureBootUEFI -Time 2016-08-08T00:00:00Z -ContentFilePath siglists\MicWinProPCA2011_2011-10-19_SigList.bin -SignedFilePath siglists\MicWinProPCA2011_2011-10-19_SigList_Serialization.bin.p7 -Name db -AppendWrite:$true
+
+Write-Host "Setting KEK-signed MS UEFI cert in db..."
+Set-SecureBootUEFI -Time 2016-08-08T00:00:00Z -ContentFilePath siglists\MicCorUEFCA2011_2011-06-27_SigList.bin -SignedFilePath siglists\MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin.p7 -Name db -AppendWrite:$true
diff --git a/SecureBoot/siglists/DCS_key_exchange_SigList.bin b/SecureBoot/siglists/DCS_key_exchange_SigList.bin
new file mode 100644
index 0000000..62f5cc6
--- /dev/null
+++ b/SecureBoot/siglists/DCS_key_exchange_SigList.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin b/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin
new file mode 100644
index 0000000..1cffcf0
--- /dev/null
+++ b/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin.p7 b/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin.p7
new file mode 100644
index 0000000..1e9d29a
--- /dev/null
+++ b/SecureBoot/siglists/DCS_key_exchange_SigList_Serialization.bin.p7
Binary files differ
diff --git a/SecureBoot/siglists/DCS_platform_SigList.bin b/SecureBoot/siglists/DCS_platform_SigList.bin
new file mode 100644
index 0000000..0b6d7e1
--- /dev/null
+++ b/SecureBoot/siglists/DCS_platform_SigList.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin b/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin
new file mode 100644
index 0000000..e8fbf79
--- /dev/null
+++ b/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin.p7 b/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin.p7
new file mode 100644
index 0000000..19cb86d
--- /dev/null
+++ b/SecureBoot/siglists/DCS_platform_SigList_Serialization.bin.p7
Binary files differ
diff --git a/SecureBoot/siglists/DCS_sign_SigList.bin b/SecureBoot/siglists/DCS_sign_SigList.bin
new file mode 100644
index 0000000..9a3f568
--- /dev/null
+++ b/SecureBoot/siglists/DCS_sign_SigList.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin b/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin
new file mode 100644
index 0000000..de58d77
--- /dev/null
+++ b/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin
Binary files differ
diff --git a/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin.p7 b/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin.p7
new file mode 100644
index 0000000..01753a8
--- /dev/null
+++ b/SecureBoot/siglists/DCS_sign_SigList_Serialization.bin.p7
Binary files differ
diff --git a/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList.bin b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList.bin
new file mode 100644
index 0000000..413ccab
--- /dev/null
+++ b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList.bin
Binary files differ
diff --git a/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin
new file mode 100644
index 0000000..735d962
--- /dev/null
+++ b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin
Binary files differ
diff --git a/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin.p7 b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin.p7
new file mode 100644
index 0000000..ed8cefd
--- /dev/null
+++ b/SecureBoot/siglists/MicCorUEFCA2011_2011-06-27_SigList_Serialization.bin.p7
Binary files differ
diff --git a/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList.bin b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList.bin
new file mode 100644
index 0000000..ac542ca
--- /dev/null
+++ b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList.bin
Binary files differ
diff --git a/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin
new file mode 100644
index 0000000..9138dae
--- /dev/null
+++ b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin
Binary files differ
diff --git a/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin.p7 b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin.p7
new file mode 100644
index 0000000..b08c60a
--- /dev/null
+++ b/SecureBoot/siglists/MicWinProPCA2011_2011-10-19_SigList_Serialization.bin.p7
Binary files differ
diff --git a/bld.bat b/bld.bat
new file mode 100644
index 0000000..75859a4
--- /dev/null
+++ b/bld.bat
@@ -0,0 +1,7 @@
+if not defined WORKSPACE (
+ echo WORKSPACE not defined
+ goto :eof
+)
+pushd %WORKSPACE%
+build %*
+popd \ No newline at end of file
diff --git a/setenv.bat b/setenv.bat
new file mode 100644
index 0000000..82a963a
--- /dev/null
+++ b/setenv.bat
@@ -0,0 +1,46 @@
+@echo off
+pushd "%~dp0"
+
+if not defined PYTHONHOME (
+ echo PYTHONHOME not found!
+ goto :end
+)
+
+if defined VS100COMNTOOLS (
+ call "%VS100COMNTOOLS%\vsvars32.bat"
+ goto :initialize
+) else (
+ echo MSVS2010 not found!
+ goto :end
+)
+
+:initialize
+
+if not defined NASM_PREFIX set NASM_PREFIX=c:\Tools\nasm\
+if not defined EDK_PREFIX set EDK_PREFIX=c:\Tools\edk2
+
+call :updatepath "%PYTHONHOME%"
+call :updatepath "%NASM_PREFIX%"
+
+if not defined EDK_TOOLS_BIN (
+ pushd "%EDK_PREFIX%"
+ call edksetup.bat
+ popd
+)
+
+goto :end
+
+:updatepath
+set appendpath=%~1
+for %%A in ("%path:;=";"%") do (
+ if /I "%~1"=="%%~A" (
+ echo %1 in path found
+ set appendpath=
+ )
+rem echo %%~A
+)
+if defined appendpath set path=%path%;%appendpath%
+goto :eof
+
+:end
+popd \ No newline at end of file