diff options
author | Alex <kavsrf@gmail.com> | 2016-08-15 17:11:31 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-08-15 17:14:26 +0200 |
commit | b87fc6b140772ba3017de311c7063c259424264c (patch) | |
tree | 41ad139e7469380704361ae757a155464e8b68e3 /DcsRe/DcsRe.c | |
parent | 68ea2f72cfe6a9b34212ced97882e488c73c8f1d (diff) | |
download | VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.tar.gz VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.zip |
First public release. Used by VeraCrypt 1.18.VeraCrypt_1.18_PreRelease
Diffstat (limited to 'DcsRe/DcsRe.c')
-rw-r--r-- | DcsRe/DcsRe.c | 330 |
1 files changed, 330 insertions, 0 deletions
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;
+}
|