VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/DcsCfg
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 /DcsCfg
parent68ea2f72cfe6a9b34212ced97882e488c73c8f1d (diff)
downloadVeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.tar.gz
VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.zip
First public release. Used by VeraCrypt 1.18.VeraCrypt_1.18_PreRelease
Diffstat (limited to 'DcsCfg')
-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
10 files changed, 2671 insertions, 0 deletions
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);
+ }
+}
+