From b87fc6b140772ba3017de311c7063c259424264c Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Aug 2016 17:11:31 +0200 Subject: First public release. Used by VeraCrypt 1.18. --- Library/VeraCryptLib/DcsVeraCrypt.c | 391 ++++++++++++++++++++++++++++++++++ Library/VeraCryptLib/DcsVeraCrypt.h | 84 ++++++++ Library/VeraCryptLib/VeraCryptLib.inf | 120 +++++++++++ Library/VeraCryptLib/llmath.c | 383 +++++++++++++++++++++++++++++++++ Library/VeraCryptLib/mklinks_src.bat | 112 ++++++++++ 5 files changed, 1090 insertions(+) create mode 100644 Library/VeraCryptLib/DcsVeraCrypt.c create mode 100644 Library/VeraCryptLib/DcsVeraCrypt.h create mode 100644 Library/VeraCryptLib/VeraCryptLib.inf create mode 100644 Library/VeraCryptLib/llmath.c create mode 100644 Library/VeraCryptLib/mklinks_src.bat (limited to 'Library/VeraCryptLib') 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 +#include +#include + +#include +#include +#include +#include + +#include +#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 +#include +#include + +////////////////////////////////////////////////////////////////////////// +// 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 +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 -- cgit v1.2.3