VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/Library/VeraCryptLib
diff options
context:
space:
mode:
Diffstat (limited to 'Library/VeraCryptLib')
-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
5 files changed, 1090 insertions, 0 deletions
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