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. --- DcsInt/DcsInt.c | 1057 +++++++++++++++++++++++++++++++++++++++++++++++++++ DcsInt/DcsInt.h | 235 ++++++++++++ DcsInt/DcsInt.inf | 93 +++++ DcsInt/DcsIntName.c | 173 +++++++++ 4 files changed, 1558 insertions(+) create mode 100644 DcsInt/DcsInt.c create mode 100644 DcsInt/DcsInt.h create mode 100644 DcsInt/DcsInt.inf create mode 100644 DcsInt/DcsIntName.c (limited to 'DcsInt') diff --git a/DcsInt/DcsInt.c b/DcsInt/DcsInt.c new file mode 100644 index 0000000..3867067 --- /dev/null +++ b/DcsInt/DcsInt.c @@ -0,0 +1,1057 @@ +/** @file +Block R/W interceptor + +Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov +Copyright (c) 2016. VeraCrypt, Mounir IDRASSI + +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the GNU Lesser General Public License, version 3.0 (LGPL-3.0). + +The full text of the license may be found at +https://opensource.org/licenses/LGPL-3.0 +**/ + +#include "DcsInt.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common/Tcdefs.h" +#include "common/Crypto.h" +#include "common/Volumes.h" +#include "common/Crc.h" +#include "crypto/cpu.h" +#include "BootCommon.h" +#include "DcsVeraCrypt.h" +#include + +// #define TRC_HANDLE_PATH(msg,h) \ +// OUT_PRINT(msg); \ +// EfiPrintDevicePath(h); \ +// OUT_PRINT(L"\n") +#define TRC_HANDLE_PATH(msg,h) + +EFI_DEVICE_PATH* gDcsBoot; +UINTN gDcsBootSize; + +DCSINT_BLOCK_IO* DcsIntBlockIoFirst = NULL; //< List of block I/O head + +EFI_DRIVER_BINDING_PROTOCOL g_DcsIntDriverBinding = { + DcsIntBindingSupported, + DcsIntBindingStart, + DcsIntBindingStop, + DCSINT_DRIVER_VERSION, + NULL, + NULL +}; + +#pragma pack(1) +typedef struct _BOOT_PARAMS { + CHAR8 Offset[TC_BOOT_LOADER_ARGS_OFFSET]; + BootArguments BootArgs; + BOOT_CRYPTO_HEADER BootCryptoInfo; + uint16 pad1; + SECREGION_BOOT_PARAMS SecRegion; +} BOOT_PARAMS, *PBOOT_PARAMS; +#pragma pack() + +UINT32 gHeaderSaltCrc32 = 0; +PBOOT_PARAMS bootParams = NULL; +//#define EFI_BOOTARGS_REGIONS_TEST ,0x9000000, 0xA000000 +#define EFI_BOOTARGS_REGIONS_TEST +UINTN BootArgsRegions[] = { EFI_BOOTARGS_REGIONS_HIGH, EFI_BOOTARGS_REGIONS_LOW EFI_BOOTARGS_REGIONS_TEST }; + +CHAR8 Header[512]; +UINT32 BootDriveSignature; +EFI_GUID BootDriveSignatureGpt; + +EFI_HANDLE SecRegionHandle = NULL; +UINT64 SecRegionSector = 0; +UINT8* SecRegionData = NULL; +UINTN SecRegionSize = 0; +UINTN SecRegionOffset = 0; +PCRYPTO_INFO SecRegionCryptInfo = NULL; + +void HaltPrint(const CHAR16* Msg) +{ + Print(L"%s - system Halted\n", Msg); + EfiCpuHalt(); +} + +////////////////////////////////////////////////////////////////////////// +// Boot params memory +////////////////////////////////////////////////////////////////////////// + +EFI_STATUS +GetBootParamsMemory() { + EFI_STATUS status = 0; + UINTN index; + if (bootParams != NULL) return EFI_SUCCESS; + for (index = 0; index < sizeof(BootArgsRegions) / sizeof(BootArgsRegions[1]); ++index) { + status = PrepareMemory(BootArgsRegions[index], sizeof(*bootParams), &bootParams); + if (!EFI_ERROR(status)) { + return status; + } + } + return status; +} + +EFI_STATUS +SetSecRegionParamsMemory() { + EFI_STATUS status = 0; + UINTN index; + UINT8* secRegion = NULL; + UINT32 crc; + if (bootParams == NULL) return EFI_NOT_READY; + + bootParams->SecRegion.Ptr = 0; + bootParams->SecRegion.Size = 0; + if (DeList != NULL) { + for (index = 0; index < sizeof(BootArgsRegions) / sizeof(BootArgsRegions[1]); ++index) { + status = PrepareMemory(BootArgsRegions[index], DeList->DataSize, &secRegion); + if (!EFI_ERROR(status)) { +// OUT_PRINT(L"bootParams %08x SecRegion %08x\n", (UINTN)bootParams, (UINTN)secRegion); + CopyMem(secRegion, SecRegionData + SecRegionOffset, DeList->DataSize); + bootParams->SecRegion.Ptr = (UINT64)secRegion; + bootParams->SecRegion.Size = DeList->DataSize; + break; + } + } + } + status = gBS->CalculateCrc32(&bootParams->SecRegion, sizeof(SECREGION_BOOT_PARAMS) - 4, &crc); + bootParams->SecRegion.Crc = crc; + return status; +} + +EFI_STATUS +PrepareBootParams( + IN UINT32 bootDriveSignature, + IN PCRYPTO_INFO cryptoInfo) +{ + BootArguments *bootArgs; + if (bootParams == NULL) return EFI_UNSUPPORTED; + bootArgs = &bootParams->BootArgs; + TC_SET_BOOT_ARGUMENTS_SIGNATURE(bootArgs->Signature); + bootArgs->BootLoaderVersion = VERSION_NUM; + bootArgs->CryptoInfoOffset = (uint16)(FIELD_OFFSET(BOOT_PARAMS, BootCryptoInfo)); + bootArgs->CryptoInfoLength = (uint16)(sizeof(BOOT_CRYPTO_HEADER) + 2 + sizeof(SECREGION_BOOT_PARAMS)); + bootArgs->HeaderSaltCrc32 = gHeaderSaltCrc32; + CopyMem(&bootArgs->BootPassword, &gAuthPassword, sizeof(gAuthPassword)); + bootArgs->HiddenSystemPartitionStart = 0; + bootArgs->DecoySystemPartitionStart = 0; + bootArgs->BootDriveSignature = bootDriveSignature; + bootArgs->Flags = (uint32)(gAuthPim << 16); + bootArgs->BootArgumentsCrc32 = GetCrc32((byte *)bootArgs, (int)((byte *)&bootArgs->BootArgumentsCrc32 - (byte *)bootArgs)); + bootParams->BootCryptoInfo.ea = (uint16)cryptoInfo->ea; + bootParams->BootCryptoInfo.mode = (uint16)cryptoInfo->mode; + bootParams->BootCryptoInfo.pkcs5 = (uint16)cryptoInfo->pkcs5; + SetSecRegionParamsMemory(); + + // Clean auth data + ZeroMem(&gAuthPassword, sizeof(gAuthPassword)); + gAuthPim = 0; + + return EFI_SUCCESS; +} + +void GetIntersection(uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength) +{ + uint64 end1 = start1 + length1 - 1; + uint64 intersectEnd = (end1 <= end2) ? end1 : end2; + + *intersectStart = (start1 >= start2) ? start1 : start2; + *intersectLength = (uint32)((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart); + + if (*intersectLength == 0) + *intersectStart = start1; +} + +VOID UpdateDataBuffer( + IN OUT UINT8* buf, + IN UINT32 bufSize, + IN UINT64 sector + ) { + UINT64 intersectStart; + UINT32 intersectLength; + UINTN i; + if (DeList == NULL) return; + for (i = 0; i < DeList->Count; ++i) { + if (DeList->DE[i].Type == DE_Sectors) { + GetIntersection( + sector << 9, bufSize, + DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1, + &intersectStart, &intersectLength + ); + if (intersectLength != 0) { +// OUT_PRINT(L"S %d : %lld, %d\n", i, intersectStart, intersectLength); +// OUT_PRINT(L"S"); + CopyMem( + buf + (intersectStart - (sector << 9)), + SecRegionData + SecRegionOffset + DeList->DE[i].Sectors.Offset + (intersectStart - (sector << 9)), + intersectLength + ); + } + } + } + +} + +////////////////////////////////////////////////////////////////////////// +// List of block I/O +////////////////////////////////////////////////////////////////////////// +DCSINT_BLOCK_IO* +GetBlockIoByHandle( + IN EFI_HANDLE handle) +{ + DCSINT_BLOCK_IO *DcsIntBlockIo = DcsIntBlockIoFirst; + while (DcsIntBlockIo != NULL) { + if (DcsIntBlockIo->Controller == handle) { + return DcsIntBlockIo; + } + DcsIntBlockIo = DcsIntBlockIo->Next; + } + return NULL; +} + +DCSINT_BLOCK_IO* +GetBlockIoByProtocol( + IN EFI_BLOCK_IO_PROTOCOL* protocol) +{ + DCSINT_BLOCK_IO *DcsIntBlockIo = DcsIntBlockIoFirst; + while (DcsIntBlockIo != NULL) { + if (DcsIntBlockIo->BlockIo == protocol) { + return DcsIntBlockIo; + } + DcsIntBlockIo = DcsIntBlockIo->Next; + } + return NULL; +} + +////////////////////////////////////////////////////////////////////////// +// Read/Write +////////////////////////////////////////////////////////////////////////// +EFI_STATUS +IntBlockIO_Write( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + DCSINT_BLOCK_IO *DcsIntBlockIo = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_LBA startSector; + DcsIntBlockIo = GetBlockIoByProtocol(This); + + if (DcsIntBlockIo) { + startSector = Lba; + startSector += gAuthBoot ? 0 : DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9; + //Print(L"This[0x%x] mid %x Write: lba=%lld, size=%d %r\n", This, MediaId, Lba, BufferSize, Status); + if ((startSector >= DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9) && + (startSector < ((DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value + DcsIntBlockIo->CryptInfo->EncryptedAreaLength.Value) >> 9))) { + VOID* writeCrypted; + writeCrypted = MEM_ALLOC(BufferSize); + if (writeCrypted == NULL) { + Status = EFI_BAD_BUFFER_SIZE; + + } + CopyMem(writeCrypted, Buffer, BufferSize); + // Print(L"*"); + UpdateDataBuffer(writeCrypted, (UINT32)BufferSize, startSector); + EncryptDataUnits(writeCrypted, (UINT64_STRUCT*)&startSector, (UINT32)(BufferSize >> 9), DcsIntBlockIo->CryptInfo); + Status = DcsIntBlockIo->LowWrite(This, MediaId, startSector, BufferSize, writeCrypted); + MEM_FREE(writeCrypted); + } + else { + Status = DcsIntBlockIo->LowWrite(This, MediaId, startSector, BufferSize, Buffer); + } + } + else { + Status = EFI_BAD_BUFFER_SIZE; + } + return Status; +} + +EFI_STATUS +IntBlockIO_Read( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + DCSINT_BLOCK_IO *DcsIntBlockIo = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_LBA startSector; + + DcsIntBlockIo = GetBlockIoByProtocol(This); + if (DcsIntBlockIo) { + startSector = Lba; + startSector += gAuthBoot ? 0 : DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9; + Status = DcsIntBlockIo->LowRead(This, MediaId, startSector, BufferSize, Buffer); + //Print(L"This[0x%x] mid %x ReadBlock: lba=%lld, size=%d %r\n", This, MediaId, Lba, BufferSize, Status); + if ((startSector >= DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value >> 9) && + (startSector < ((DcsIntBlockIo->CryptInfo->EncryptedAreaStart.Value + DcsIntBlockIo->CryptInfo->EncryptedAreaLength.Value) >> 9))) { + // Print(L"."); + DecryptDataUnits(Buffer, (UINT64_STRUCT*)&startSector, (UINT32)(BufferSize >> 9), DcsIntBlockIo->CryptInfo); + } + UpdateDataBuffer(Buffer, (UINT32)BufferSize, startSector); + } + else { + Status = EFI_BAD_BUFFER_SIZE; + } + return Status; +} + +////////////////////////////////////////////////////////////////////////// +// Block IO hook +////////////////////////////////////////////////////////////////////////// +EFI_STATUS +IntBlockIo_Hook( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_BLOCK_IO_PROTOCOL *BlockIo; + DCSINT_BLOCK_IO *DcsIntBlockIo = 0; + EFI_STATUS Status; +// EFI_TPL Tpl; + + // Already hook? + DcsIntBlockIo = GetBlockIoByHandle(DeviceHandle); + if (DcsIntBlockIo != NULL) { + return EFI_SUCCESS; + } + + Status = gBS->OpenProtocol( + DeviceHandle, + &gEfiBlockIoProtocolGuid, + (VOID**)&BlockIo, + This->DriverBindingHandle, + DeviceHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (!EFI_ERROR(Status)) { + // Check is this protocol already hooked + DcsIntBlockIo = (DCSINT_BLOCK_IO *)MEM_ALLOC(sizeof(DCSINT_BLOCK_IO)); + if (DcsIntBlockIo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // construct new DcsIntBlockIo + DcsIntBlockIo->Sign = DCSINT_BLOCK_IO_SIGN; + DcsIntBlockIo->Controller = DeviceHandle; + DcsIntBlockIo->BlockIo = BlockIo; + DcsIntBlockIo->IsReinstalled = 0; + + if (EFI_ERROR(Status)) { + gBS->CloseProtocol( + DeviceHandle, + &gEfiBlockIoProtocolGuid, + This->DriverBindingHandle, + DeviceHandle + ); + MEM_FREE(DcsIntBlockIo); + return EFI_UNSUPPORTED; + } + // Block +// Tpl = gBS->RaiseTPL(TPL_NOTIFY); + // Install new routines + DcsIntBlockIo->CryptInfo = SecRegionCryptInfo; + DcsIntBlockIo->LowRead = BlockIo->ReadBlocks; + DcsIntBlockIo->LowWrite = BlockIo->WriteBlocks; + BlockIo->ReadBlocks = IntBlockIO_Read; + BlockIo->WriteBlocks = IntBlockIO_Write; + + // close protocol before reinstall + gBS->CloseProtocol( + DeviceHandle, + &gEfiBlockIoProtocolGuid, + This->DriverBindingHandle, + DeviceHandle + ); + + // add to global list + if (DcsIntBlockIoFirst == NULL) { + DcsIntBlockIoFirst = DcsIntBlockIo; + } + else { + DcsIntBlockIoFirst->Next = DcsIntBlockIoFirst; + DcsIntBlockIoFirst = DcsIntBlockIo; + } + + // reinstall BlockIo protocol + Status = gBS->ReinstallProtocolInterface( + DeviceHandle, + &gEfiBlockIoProtocolGuid, + BlockIo, + BlockIo + ); + +// gBS->RestoreTPL(Tpl); + DcsIntBlockIo->IsReinstalled = 1; + + Status = EFI_SUCCESS; + } + return Status; +} + +////////////////////////////////////////////////////////////////////////// +// DriverBinding routines +////////////////////////////////////////////////////////////////////////// +EFI_STATUS +DcsIntBindingStart( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + + TRC_HANDLE_PATH(L"t: ", Controller); + + // hook blockIo + Status = IntBlockIo_Hook(This, Controller); + if (EFI_ERROR(Status)) { + HaltPrint(L"Failed"); + } + return Status; +} + +EFI_STATUS +DcsIntBindingSupported( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_DEVICE_PATH *DevicePath; + DevicePath = DevicePathFromHandle(Controller); + if ((DevicePath != NULL) && CompareMem(DevicePath, gDcsBoot, gDcsBootSize) == 0) { + DCSINT_BLOCK_IO* DcsIntBlockIo = NULL; + // Is installed? + DcsIntBlockIo = GetBlockIoByHandle(Controller); + if (DcsIntBlockIo != NULL) { + return EFI_UNSUPPORTED; + } + return EFI_SUCCESS; + } + return EFI_UNSUPPORTED; +} + +EFI_STATUS +DcsIntBindingStop( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + TRC_HANDLE_PATH(L"p: ", Controller); + return EFI_SUCCESS; +} + +////////////////////////////////////////////////////////////////////////// +// Security regions +////////////////////////////////////////////////////////////////////////// +EFI_STATUS +SecRegionLoadDefault(EFI_HANDLE partHandle) +{ + EFI_STATUS res = EFI_SUCCESS; + HARDDRIVE_DEVICE_PATH dpVolme; + EFI_BLOCK_IO_PROTOCOL *bio = NULL; + EFI_PARTITION_TABLE_HEADER* gptHdr; + res = EfiGetPartDetails(partHandle, &dpVolme, &SecRegionHandle); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Part details: %r\n,", res); + return res; + } + + // get BlockIo protocol + bio = EfiGetBlockIO(SecRegionHandle); + if (bio == NULL) { + ERR_PRINT(L"Block io not supported\n,"); + return EFI_NOT_FOUND; + } + + SecRegionData = MEM_ALLOC(512); + if (SecRegionData == NULL) { + ERR_PRINT(L"No memory\n,"); + return EFI_BUFFER_TOO_SMALL; + } + SecRegionSize = 512; + + res = bio->ReadBlocks(bio, bio->Media->MediaId, 0, 512, SecRegionData); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Read: %r\n", res); + goto error; + } + + BootDriveSignature = *(uint32 *)(SecRegionData + 0x1b8); + + res = bio->ReadBlocks(bio, bio->Media->MediaId, 1, 512, SecRegionData); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Read: %r\n", res); + goto error; + } + + gptHdr = (EFI_PARTITION_TABLE_HEADER*)SecRegionData; + CopyMem(&BootDriveSignatureGpt, &gptHdr->DiskGUID, sizeof(BootDriveSignatureGpt)); + + res = bio->ReadBlocks(bio, bio->Media->MediaId, TC_BOOT_VOLUME_HEADER_SECTOR, 512, SecRegionData); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Read: %r\n", res); + goto error; + } + + return EFI_SUCCESS; +error: + MEM_FREE(SecRegionData); + SecRegionData = NULL; + SecRegionSize = 0; + return res; +} + +EFI_STATUS +SecRegionChangePwd() { + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL* bio = NULL; + PCRYPTO_INFO cryptoInfo, ci; + Password newPassword; + Password confirmPassword; + INT32 vcres; + + Status = RndPreapare(); + if (EFI_ERROR(Status)) { + ERR_PRINT(L"Rnd: %r\n", Status); + return Status; + } + + do { + ZeroMem(&newPassword, sizeof(newPassword)); + ZeroMem(&confirmPassword, sizeof(newPassword)); + VCAskPwd(AskPwdNew, &newPassword); + if (gAuthPwdCode == AskPwdRetCancel) { + return EFI_NOT_READY; + } + VCAskPwd(AskPwdConfirm, &confirmPassword); + if (gAuthPwdCode == AskPwdRetCancel) { + return EFI_NOT_READY; + } + if (newPassword.Length == confirmPassword.Length) { + if (CompareMem(newPassword.Text, confirmPassword.Text, confirmPassword.Length) == 0) { + break; + } + } + ERR_PRINT(L"Password mismatch"); + } while (TRUE); + + OUT_PRINT(L"Generate...\n\r"); + cryptoInfo = SecRegionCryptInfo; + vcres = CreateVolumeHeaderInMemory( + gAuthBoot, Header, + cryptoInfo->ea, + cryptoInfo->mode, + &newPassword, + cryptoInfo->pkcs5, + gAuthPim, + cryptoInfo->master_keydata, + &ci, + cryptoInfo->VolumeSize.Value, + 0, //(volumeType == TC_VOLUME_TYPE_HIDDEN) ? cryptoInfo->hiddenVolumeSize : 0, + cryptoInfo->EncryptedAreaStart.Value, + cryptoInfo->EncryptedAreaLength.Value, + gAuthTc ? 0 : cryptoInfo->RequiredProgramVersion, + cryptoInfo->HeaderFlags, + cryptoInfo->SectorSize, + FALSE); + + if (vcres != 0) { + ERR_PRINT(L"header create error(%x)\n", vcres); + return EFI_INVALID_PARAMETER; + } + + // get BlockIo protocol + bio = EfiGetBlockIO(SecRegionHandle); + if (bio == NULL) { + ERR_PRINT(L"Block io not supported\n,"); + return EFI_NOT_FOUND; + } + + Status = bio->WriteBlocks(bio, bio->Media->MediaId, SecRegionSector, 512, Header); + if (EFI_ERROR(Status)) { + ERR_PRINT(L"Write: %r\n", Status); + return Status; + } + CopyMem(&gAuthPassword, &newPassword, sizeof(gAuthPassword)); + CopyMem(SecRegionData + SecRegionOffset, Header, 512); + ERR_PRINT(L"Update (%r)\n", Status); + return Status; +} + +EFI_STATUS +SelectDcsBootBySignature() +{ + EFI_STATUS res = EFI_NOT_FOUND; + EFI_BLOCK_IO_PROTOCOL* bio = NULL; + EFI_PARTITION_TABLE_HEADER* gptHdr; + UINTN i; + for (i = 0; i < gBIOCount; ++i) { + if(EfiIsPartition(gBIOHandles[i])) continue; + bio = EfiGetBlockIO(gBIOHandles[i]); + if(bio == NULL) continue; + res = bio->ReadBlocks(bio, bio->Media->MediaId, 0, 512, Header); + if(EFI_ERROR(res)) continue; + if((*(UINT32*)(Header+0x1b8)) != BootDriveSignature) continue; + res = bio->ReadBlocks(bio, bio->Media->MediaId, 1, 512, Header); + if (EFI_ERROR(res)) continue; + gptHdr = (EFI_PARTITION_TABLE_HEADER*)Header; + if (CompareMem(&BootDriveSignatureGpt, &gptHdr->DiskGUID, sizeof(BootDriveSignatureGpt)) != 0) continue; + gDcsBoot = DevicePathFromHandle(gBIOHandles[i]); + gDcsBootSize = GetDevicePathSize(gDcsBoot); + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} + +EFI_STATUS +SecRegionTryDecrypt() +{ + int vcres = 1; + EFI_STATUS res = EFI_SUCCESS; + + PlatformGetID(SecRegionHandle, &gPlatformKeyFile, &gPlatformKeyFileSize); + + do { + SecRegionOffset = 0; + VCAuthAsk(); + if (gAuthPwdCode == AskPwdRetCancel) { + return EFI_NOT_READY; + } + OUT_PRINT(L"Authorize...\n\r"); + do { + CopyMem(Header, SecRegionData + SecRegionOffset, 512); + vcres = ReadVolumeHeader(gAuthBoot, Header, &gAuthPassword, gAuthHash, gAuthPim, gAuthTc, &SecRegionCryptInfo, NULL); + SecRegionOffset += (vcres != 0) ? 1024 * 128 : 0; + } while (SecRegionOffset < SecRegionSize && vcres != 0); + if (vcres == 0) { + OUT_PRINT(L"Success\n"); + OUT_PRINT(L"start %lld len %lld\n", SecRegionCryptInfo->EncryptedAreaStart.Value, SecRegionCryptInfo->EncryptedAreaLength.Value); + break; + } else { + ERR_PRINT(L"Decript error(%x)\n\r", vcres); + } + } while (vcres != 0 && gAuthRetry != 0); + if (vcres != 0) { + return EFI_CRC_ERROR; + } + + SecRegionSector = 62 + SecRegionOffset / 512; + DeList = NULL; + if (SecRegionSize > 512) { + UINT64 startUnit = 0; + DecryptDataUnits(SecRegionData + SecRegionOffset + 512, (UINT64_STRUCT*)&startUnit,(UINT32)255, SecRegionCryptInfo); + if (CompareMem(SecRegionData + SecRegionOffset + 512, &gDcsDiskEntryListHeaderID, sizeof(gDcsDiskEntryListHeaderID)) != 0) { + ERR_PRINT(L"Wrong DCS list header"); + return EFI_CRC_ERROR; + } + DeList = (DCS_DISK_ENTRY_LIST *)(SecRegionData + SecRegionOffset + 512); + CopyMem(&BootDriveSignature, &DeList->DE[DE_IDX_DISKID].DiskId.MbrID, sizeof(BootDriveSignature)); + CopyMem(&BootDriveSignatureGpt, &DeList->DE[DE_IDX_DISKID].DiskId.GptID, sizeof(BootDriveSignatureGpt)); + + if (DeList->DE[DE_IDX_EXEC].Type == DE_ExecParams) { + DCS_DEP_EXEC *execParams = NULL; + execParams = (DCS_DEP_EXEC *)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_EXEC].Offset); + EfiSetVar(L"DcsExecPartGuid", NULL, &execParams->ExecPartGuid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS); + EfiSetVar(L"DcsExecCmd", NULL, &execParams->ExecCmd, (StrLen((CHAR16*)&execParams->ExecCmd) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS); + } + + if (DeList->DE[DE_IDX_PWDCACHE].Type == DE_PwdCache) { + DCS_DEP_PWD_CACHE *pwdCache = NULL; + UINT64 sector = 0; + pwdCache = (DCS_DEP_PWD_CACHE *)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_PWDCACHE].Offset); + EncryptDataUnits((UINT8*)pwdCache, (UINT64_STRUCT*)§or, 1, SecRegionCryptInfo); + } + + if (DeList->DE[DE_IDX_RND].Type == DE_Rnd) { + UINT8 temp[4]; + UINT64 sector = 0; + DCS_RND_SAVED* rndNewSaved; + DCS_RND_SAVED* rndSaved = (DCS_RND_SAVED*)(SecRegionData + SecRegionOffset + DeList->DE[DE_IDX_RND].Offset); + if (DeList->DE[DE_IDX_RND].Length == sizeof(DCS_RND_SAVED)) { + if (!EFI_ERROR(res = RndLoad(rndSaved, &gRnd)) && + !EFI_ERROR(res = RndGetBytes(temp, sizeof(temp))) && + !EFI_ERROR(res = RndSave(gRnd, &rndNewSaved)) + ) { + EFI_BLOCK_IO_PROTOCOL *bio = NULL; + sector = (DeList->DE[DE_IDX_RND].Offset >> 9) - 1; + OUT_PRINT(L"Last login %H%t%N\n", &rndSaved->SavedAt); + + EncryptDataUnits((UINT8*)rndNewSaved, (UINT64_STRUCT*)§or, 1, SecRegionCryptInfo); + sector = SecRegionSector + (DeList->DE[DE_IDX_RND].Offset >> 9); + + // get BlockIo protocol + bio = EfiGetBlockIO(SecRegionHandle); + if (bio == NULL) { + ERR_PRINT(L"Block io not supported\n,"); + } + + res = bio->WriteBlocks(bio, bio->Media->MediaId, sector, 512, rndNewSaved); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Write: %r\n", res); + } + } + } + } + } + + // Select boot device + res = SelectDcsBootBySignature(); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Decrypt device not found\n"); + return res; + } + + // Change password if requested + if (gAuthPwdCode == AskPwdRetChange && gRnd != NULL) { + res = RndPreapare(); + if (!EFI_ERROR(res)) { + res = SecRegionChangePwd(); + if (EFI_ERROR(res)) { + return res; + } + } else { + ERR_PRINT(L"Random: %r\n", res); + } + } + gHeaderSaltCrc32 = GetCrc32(SecRegionData + SecRegionOffset, PKCS5_SALT_SIZE); + return EFI_SUCCESS; +} + +////////////////////////////////////////////////////////////////////////// +// Exit action +////////////////////////////////////////////////////////////////////////// +enum OnExitTypes{ + OnExitAuthFaild = 1, + OnExitAuthNotFound, + OnExitSuccess +}; + +BOOLEAN +AsciiCharNCmp( + IN CHAR8 ch1, + IN CHAR8 ch2 + ) +{ + return (ch1 | 0x20) == (ch2 | 0x20); +} + +CHAR8* +AsciiStrNStr( + IN CHAR8* str, + IN CHAR8* pattern) +{ + CHAR8* pos1 = str; + CHAR8* pos2; + CHAR8* posp; + while (*pos1 != 0) { + posp = pattern; + pos2 = pos1; + while (*posp != 0 && *pos2 != 0 && AsciiCharNCmp(*pos2,*posp)) { + ++posp; + ++pos2; + } + if (*pos2 == 0) return NULL; + if (*posp == 0) return pos1; + ++pos1; + } + return NULL; +} + +BOOLEAN +OnExitGetParam( + IN CHAR8 *action, + IN CHAR8 *name, + OUT CHAR8 **value, + OUT CHAR16 **valueU + ) +{ + CHAR8* pos; + UINTN len = 0; + UINTN i = 0; + pos = AsciiStrNStr(action, name); + if (pos == NULL) return FALSE; + pos += AsciiStrLen(name); + if(*pos != '(') return FALSE; + pos++; + while (pos[len] != 0 && pos[len] != ')') len++; + if (pos[len] == 0) return FALSE; + if (value != NULL) *value = MEM_ALLOC(len + 1); + if (valueU != NULL) *valueU = MEM_ALLOC((len + 1) * 2); + for (i = 0; i < len; ++i) { + if (value != NULL) (*value)[i] = pos[i]; + if (valueU != NULL) (*valueU)[i] = pos[i]; + } + return TRUE; +} + +EFI_STATUS +OnExit( + IN CHAR8 *action, + IN UINTN type, + IN EFI_STATUS retValue) +{ + CHAR8* guidStr = NULL; + CHAR8* exitStatusStr = NULL; + CHAR8* messageStr = NULL; + CHAR8* delayStr = NULL; + EFI_GUID *guid = NULL; + CHAR16 *fileStr = NULL; + if (action == NULL) return retValue; + if (OnExitGetParam(action, "guid", &guidStr, NULL)) { + EFI_GUID tmp; + if (AsciiStrToGuid(&tmp, guidStr)) { + guid = MEM_ALLOC(sizeof(EFI_GUID)); + CopyMem(guid, &tmp, sizeof(EFI_GUID)); + } + } + + if (OnExitGetParam(action, "status", &exitStatusStr, NULL)) { + retValue = AsciiStrDecimalToUintn(exitStatusStr); + } + + OnExitGetParam(action, "file", NULL, &fileStr); + + + if (OnExitGetParam(action, "printinfo", NULL, NULL)) { + OUT_PRINT(L"type %d\naction %a\n", type, action); + if (guid != NULL) OUT_PRINT(L"guid %g\n", guid); + if (fileStr != NULL) OUT_PRINT(L"file %s\n", fileStr); + if (exitStatusStr != NULL) OUT_PRINT(L"status %d, %r\n", retValue, retValue); + } + + if (OnExitGetParam(action, "message", &messageStr, NULL)) { + OUT_PRINT(L"%a", messageStr); + } + + if (OnExitGetParam(action, "delay", &delayStr, NULL)) { + UINTN delay; + EFI_INPUT_KEY key; + delay = AsciiStrDecimalToUintn(delayStr); + OUT_PRINT(L"\n"); + key = KeyWait(L"\r%d ", delay, 0, 0); + if (key.UnicodeChar != 0) GetKey(); + } + + if (AsciiStrNStr(action, "halt") == action) { + EfiCpuHalt(); + } + + if (AsciiStrNStr(action, "exec") == action) { + if (guid != NULL) { + EFI_STATUS res; + EFI_HANDLE h; + res = EfiFindPartByGUID(guid, &h); + if (EFI_ERROR(res)) { + ERR_PRINT(L"\nCan't find start partition\n"); + EfiCpuHalt(); + } + // Try to exec + res = EfiExec(h, fileStr); + if (EFI_ERROR(res)) { + ERR_PRINT(L"\nStart %s - %r\n", fileStr, res); + EfiCpuHalt(); + } + } + + if (fileStr != NULL) { + EfiSetVar(L"DcsExecCmd", NULL, fileStr, (StrLen(fileStr) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS); + } + goto exit; + } + + if (AsciiStrNStr(action, "postexec") == action) { + if (guid != NULL) { + EfiSetVar(L"DcsExecPartGuid", NULL, &guid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS); + } + if (fileStr != NULL) { + EfiSetVar(L"DcsExecCmd", NULL, fileStr, (StrLen(fileStr) + 1) * 2, EFI_VARIABLE_BOOTSERVICE_ACCESS); + } + goto exit; + } + + if (AsciiStrStr(action, "exit") == action) { + goto exit; + } + +exit: + MEM_FREE(guidStr); + MEM_FREE(exitStatusStr); + MEM_FREE(messageStr); + MEM_FREE(delayStr); + MEM_FREE(guid); + MEM_FREE(fileStr); + return retValue; +} + +////////////////////////////////////////////////////////////////////////// +// Exit boot loader event +////////////////////////////////////////////////////////////////////////// +EFI_EVENT mVirtualAddrChangeEvent; +VOID +EFIAPI +VirtualNotifyEvent( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // Clean all sensible info and keys before transfer to OS + if (SecRegionCryptInfo != NULL) { + ZeroMem(SecRegionCryptInfo, sizeof(*SecRegionCryptInfo)); + } + + if (gRnd != NULL) { + ZeroMem(gRnd, sizeof(*gRnd)); + } + + if (SecRegionData != NULL) { + ZeroMem(SecRegionData, SecRegionSize); + } +} + +////////////////////////////////////////////////////////////////////////// +// Driver Entry Point +////////////////////////////////////////////////////////////////////////// +EFI_STATUS +UefiMain( + EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_STATUS res; + + InitBio(); + InitFS(); + + // Remove BootNext to restore boot order + BootMenuItemRemove(L"BootNext"); + + // Load auth parameters + VCAuthLoadConfig(); + if (gAuthSecRegionSearch) { + res = PlatformGetAuthData(&SecRegionData, &SecRegionSize, &SecRegionHandle); + if (!EFI_ERROR(res)) { + EFI_INPUT_KEY key; + EfiPrintDevicePath(SecRegionHandle); + OUT_PRINT(L"\n"); + key = KeyWait(L"%2d \r", 2, 0, 0); + if (key.UnicodeChar != 0) { + GetKey(); + } + } + } else if (gRUD != 0) { + // RUD defined + UINTN i; + BOOLEAN devFound = FALSE; + InitUsb(); + for (i = 0; i < gUSBCount; ++i) { + CHAR8* id = NULL; + res = UsbGetId(gUSBHandles[i], &id); + if (!EFI_ERROR(res) && id != NULL) { + INT32 rud; + rud = GetCrc32((unsigned char*)id, (int)AsciiStrLen(id)); + MEM_FREE(id); + if (rud == gRUD) { + devFound = TRUE; + break; + } + } + } + if (!devFound) return OnExit(gOnExitNotFound, OnExitAuthNotFound, EFI_NOT_FOUND); + } + + // Try to find by OS partition GUID + if (SecRegionData == NULL && gPartitionGuidOS != NULL) { + UINTN i; + for (i = 0; i < gBIOCount; ++i) { + EFI_GUID guid; + res = EfiGetPartGUID(gBIOHandles[i], &guid); + if(EFI_ERROR(res)) continue; + if (memcmp(gPartitionGuidOS, &guid, sizeof(guid)) == 0) { + res = SecRegionLoadDefault(gBIOHandles[i]); + if (EFI_ERROR(res)) { + return OnExit(gOnExitNotFound, OnExitAuthNotFound, res); + } + } + } + } + + // ask any way? (by DcsBoot flag) + if (SecRegionData == NULL) { + if (gDcsBootForce != 0) { + res = SecRegionLoadDefault(gFileRootHandle); + if (EFI_ERROR(res)) { + return OnExit(gOnExitNotFound, OnExitAuthNotFound, res); + } + } else { + return OnExit(gOnExitNotFound, OnExitAuthNotFound, EFI_NOT_FOUND); + } + } + + res = GetBootParamsMemory(); + if (EFI_ERROR(res)) { + ERR_PRINT(L"No boot args memory: %r\n\r", res); + KeyWait(L"%02d\r", 10, 0, 0); + return res; + } + + DetectX86Features(); + res = SecRegionTryDecrypt(); + if (EFI_ERROR(res)) { + return OnExit(gOnExitFailed, OnExitAuthFaild, res); + } + + res = PrepareBootParams(BootDriveSignature, SecRegionCryptInfo); + if (EFI_ERROR(res)) { + ERR_PRINT(L"Can not set params for OS: %r", res); + return OnExit(gOnExitFailed, OnExitAuthFaild, res); + } + + // Lock EFI boot variables + EfiExec(NULL, L"EFI\\VeraCrypt\\DcsBml.dcs"); + + // Install decrypt + res = EfiLibInstallDriverBindingComponentName2( + ImageHandle, + SystemTable, + &g_DcsIntDriverBinding, + ImageHandle, + &gDcsIntComponentName, + &gDcsIntComponentName2); + + if (EFI_ERROR(res)) { + ERR_PRINT(L"Bind %r\n", res); + return OnExit(gOnExitFailed, OnExitAuthFaild, res); + } + + res = gBS->CreateEventEx( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + VirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mVirtualAddrChangeEvent + ); + + return OnExit(gOnExitSuccess, OnExitSuccess, res); +} diff --git a/DcsInt/DcsInt.h b/DcsInt/DcsInt.h new file mode 100644 index 0000000..ad0e40c --- /dev/null +++ b/DcsInt/DcsInt.h @@ -0,0 +1,235 @@ +/** @file +Block R/W interceptor + +Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov +Copyright (c) 2016. VeraCrypt, Mounir IDRASSI + +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the GNU Lesser General Public License, version 3.0 (LGPL-3.0). + +The full text of the license may be found at +https://opensource.org/licenses/LGPL-3.0 +**/ + +#ifndef __DCSINT_H__ +#define __DCSINT_H__ + +#include +#include +#include +#include +#include + +#define DCSINT_DRIVER_VERSION 1 +#define DCS_SIGNATURE_16(A, B) ((A) | (B << 8)) +#define DCS_SIGNATURE_32(A, B, C, D) (DCS_SIGNATURE_16 (A, B) | (DCS_SIGNATURE_16 (C, D) << 16)) + +#define DCSINT_BLOCK_IO_SIGN DCS_SIGNATURE_32('D','C','S', 'I') + +extern EFI_COMPONENT_NAME_PROTOCOL gDcsIntComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gDcsIntComponentName2; + +typedef struct _DCSINT_BLOCK_IO DCSINT_BLOCK_IO, *PDCSINT_BLOCK_IO; +typedef struct CRYPTO_INFO_t CRYPTO_INFO, *PCRYPTO_INFO; + +typedef struct _DCSINT_BLOCK_IO { + UINT32 Sign; + EFI_HANDLE Controller; + + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_BLOCK_READ LowRead; + EFI_BLOCK_WRITE LowWrite; + UINT32 IsReinstalled; + PCRYPTO_INFO CryptInfo; + DCSINT_BLOCK_IO* Next; +} DCSINT_BLOCK_IO, *PDCSINT_BLOCK_IO; + +// +// Functions for Driver Binding Protocol +// + +/** + Check whether the controller is a supported. + + @param This The driver binding protocol. + @param Controller The controller handle to check. + @param RemainingDevicePath The remaining device path. + + @retval EFI_SUCCESS The driver supports this controller. + @retval other This device isn't supported. + +**/ +EFI_STATUS +EFIAPI +DcsIntBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Starts the BlockIo device with this driver. + + @param This The driver binding protocol. + @param Controller The Block MMIO device to start on + @param RemainingDevicePath The remaining device path. + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_UNSUPPORTED This driver does not support this device. + @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ALREADY_STARTED This driver has been started. + +**/ +EFI_STATUS +EFIAPI +DcsIntBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Stop controlling the device. + + @param This The driver binding + @param Controller The device controller controlled by the driver. + @param NumberOfChildren The number of children of this device + @param ChildHandleBuffer The buffer of children handle. + + @retval EFI_SUCCESS The driver stopped from controlling the device. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + @retval EFI_UNSUPPORTED Block I/O Protocol is not installed on Controller. + @retval Others Failed to stop the driver + +**/ +EFI_STATUS +EFIAPI +DcsIntBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +// +// Functions for Block I/O Protocol +// + +// +// EFI Component Name Functions +// + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + @param DriverName A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +DcsIntComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + @param ChildHandle The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + @param Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + @param ControllerName A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +DcsIntComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +#endif \ No newline at end of file diff --git a/DcsInt/DcsInt.inf b/DcsInt/DcsInt.inf new file mode 100644 index 0000000..e79dcc6 --- /dev/null +++ b/DcsInt/DcsInt.inf @@ -0,0 +1,93 @@ +# Block R/W interceptor +# +# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov +# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI +# +# This program and the accompanying materials are licensed and made available +# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0). +# +# The full text of the license may be found at +# https://opensource.org/licenses/LGPL-3.0 +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DcsInt + FILE_GUID = 26BC5841-0606-450F-A39B-F2DB0D7E002E + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + DcsInt.c + DcsInt.h + DcsIntName.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + DcsPkg/DcsPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiLib + BaseLib + MemoryAllocationLib + GraphLib + CommonLib + PasswordLib + DcsCfgLib + VeraCryptLib + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiLoadedImageProtocolGuid + +[Guids] + gEfiGlobalVariableGuid + gEfiDcsVariableGuid + gEfiFileInfoGuid + gEfiPartTypeUnusedGuid + gEfiPartTypeSystemPartGuid + gEfiEventVirtualAddressChangeGuid + +[BuildOptions.IA32] + +RELEASE_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI +DEBUG_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI +NOOPT_VS2010x86_IA32_CC_FLAGS = /FAcs /D_UEFI + +RELEASE_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI +DEBUG_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI +NOOPT_VS2015x86_IA32_CC_FLAGS = /arch:IA32 /FAcs /D_UEFI + +[BuildOptions.X64] +RELEASE_VS2010x86_X64_CC_FLAGS = /D_UEFI +DEBUG_VS2010x86_X64_CC_FLAGS = /D_UEFI +NOOPT_VS2010x86_X64_CC_FLAGS = /D_UEFI + +RELEASE_VS2015x86_X64_CC_FLAGS = /D_UEFI +DEBUG_VS2015x86_X64_CC_FLAGS = /D_UEFI +NOOPT_VS2015x86_X64_CC_FLAGS = /D_UEFI + +DEBUG_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG +RELEASE_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data +NOOPT_VS2010x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + +DEBUG_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG +RELEASE_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data +NOOPT_VS2015x86_X64_DLINK_FLAGS == /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:64 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + + +[FeaturePcd] + +[Pcd] + diff --git a/DcsInt/DcsIntName.c b/DcsInt/DcsIntName.c new file mode 100644 index 0000000..ccf8698 --- /dev/null +++ b/DcsInt/DcsIntName.c @@ -0,0 +1,173 @@ +/** @file +Block R/W interceptor + +Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov +Copyright (c) 2016. VeraCrypt, Mounir IDRASSI + +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the GNU Lesser General Public License, version 3.0 (LGPL-3.0). + +The full text of the license may be found at +https://opensource.org/licenses/LGPL-3.0 +**/ + +#include "DcsInt.h" +#include +#include +#include + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gDcsIntComponentName = { + DcsIntComponentNameGetDriverName, + DcsIntComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gDcsIntComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) DcsIntComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) DcsIntComponentNameGetControllerName, + "en" +}; + +// +// Driver name table for module. +// It is shared by the implementation of ComponentName & ComponentName2 Protocol. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDcsIntComponentNameDriverNameTable[] = { + { + "eng;en", + (CHAR16 *)L"DCSINT Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + @param DriverName A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +DcsIntComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mDcsIntComponentNameDriverNameTable, + DriverName, + (BOOLEAN)(This == &gDcsIntComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + @param ChildHandle The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + @param Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + @param ControllerName A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +DcsIntComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return EFI_UNSUPPORTED; +} \ No newline at end of file -- cgit v1.2.3