VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DcsCfg/DcsCfg.h13
-rw-r--r--DcsCfg/DcsCfg.inf2
-rw-r--r--DcsCfg/DcsCfg.man19
-rw-r--r--DcsCfg/DcsCfgMain.c128
-rw-r--r--DcsCfg/DcsCfgTpm.c88
-rw-r--r--DcsInt/DcsInt.c44
-rw-r--r--DcsPkg.dsc5
-rw-r--r--DcsRe/DcsRe.c102
-rw-r--r--Include/Library/CommonLib.h43
-rw-r--r--Include/Library/DcsCfgLib.h5
-rw-r--r--Include/Library/DcsTpmLib.h106
-rw-r--r--Library/CommonLib/EfiConsole.c67
-rw-r--r--Library/DcsCfgLib/DcsCfgLib.inf3
-rw-r--r--Library/DcsCfgLib/DcsRandom.c144
-rw-r--r--Library/DcsTpmLib/DcsTpmLib.inf48
-rw-r--r--Library/DcsTpmLib/Tpm12.c1344
-rw-r--r--Library/VeraCryptLib/DcsVeraCrypt.c176
-rw-r--r--Library/VeraCryptLib/DcsVeraCrypt.h3
-rw-r--r--Library/VeraCryptLib/VeraCryptLib.inf2
-rw-r--r--Library/VeraCryptLib/llmath.c4
20 files changed, 2136 insertions, 210 deletions
diff --git a/DcsCfg/DcsCfg.h b/DcsCfg/DcsCfg.h
index 2ffd50d..8a9a15a 100644
--- a/DcsCfg/DcsCfg.h
+++ b/DcsCfg/DcsCfg.h
@@ -161,6 +161,19 @@ TestTouch();
EFI_STATUS
DcsInteractiveSetup();
+//////////////////////////////////////////////////////////////////////////
+// TPM
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12ListPcrs(
+ UINT32 sPcr,
+ UINT32 ePcr
+ );
+EFI_STATUS
+Tpm12NvList();
+
+EFI_STATUS
+Tpm12DcsConfigure();
#endif // DcsCfg_h__
diff --git a/DcsCfg/DcsCfg.inf b/DcsCfg/DcsCfg.inf
index c7218aa..c057b96 100644
--- a/DcsCfg/DcsCfg.inf
+++ b/DcsCfg/DcsCfg.inf
@@ -34,6 +34,7 @@
DcsCfgGraphics.c
DcsCfgBlockio.c
DcsCfgTouch.c
+ DcsCfgTpm.c
DcsCfgSetup.c
[Packages]
@@ -51,6 +52,7 @@
GraphLib
PasswordLib
DcsCfgLib
+ DcsTpmLib
VeraCryptLib
ShellLib
diff --git a/DcsCfg/DcsCfg.man b/DcsCfg/DcsCfg.man
index bb6fda4..72575dc 100644
--- a/DcsCfg/DcsCfg.man
+++ b/DcsCfg/DcsCfg.man
@@ -35,16 +35,20 @@ DcsCfg -ds <BN> -wipe <start> <end>
.SH OPTIONS
+ -dc - check devices (try to authorize)
-dl - block device list (order numbers are used in -db and -se)
-ds <BN> – select device
-de <BN> – end device to check (starts from select)
- -dc check devices (try to authorize)
-db <BN> - boot partition selection
-aa - ask authorization parameters
-ach - create header on block device
-vec <BN> - block device encrypt
-vdc <BN> - block device decrypt
-vcp <BN> - block device change password
+ -rnd <type> <param>- select rnadom type (0 - none, 1 - file, 2- rdrand, 3 HMAC, 4 OPENSSL 5 TPM)
+ -rndgen <file> - generate random file
+ -rndload - load rnd generator state from file
+ -rndsave - save rnd generator state to file
-ul - USB device list
-tl - touch device
-tt <TN> - Test touch device
@@ -55,18 +59,29 @@ DcsCfg -ds <BN> -wipe <start> <end>
-bt - Beep device test
-setup - interactive setup
-pl - GPT list
- -pf <gpt_file_name> - file with GPT
+ -pf <gpt_file_name> - file with GPT and params
-ps - save GPT to file
+ -pz - delete info from GPT to file
-pa - applay GPT from file to disk
-pe - encrypt GPT
-pd - decrypt GPT
-pnt <PNT> - partition number as template (from -pl)
-phide <PHS> <PHE> - hide partions from <PHS> to <PHE>; <PHS> - start sector of hidden partition, <PHE> - end sector of hidden partition
+ -pedt <PN> - partition number to edit(from -pl)
+ -pexec - edit executable parameter
+ -prndsave - save random state to params
+ -prndload - load random state from params
+ -pwdcache - edit password cache in params
-kp <key_file_name> - keys file of platform to save
-srm <SRT> - mark disk as security regions container(write CRC of platform to 61 sector); <SRT> - number of possible security regions
-srw <SRT> - wipe security regions data with random data (write random data [62, 62 + 256 * SRT]) it has to be free! check first partition start sector!
-sra <SRN> - add <gpt_file_name> to security region <SRN>
-wipe <SS SE> - write random data to sectors range [SS,SE]
+ -osdecrypt - decrypt OS (rescue)
+ -osrestorekey - restore key (rescue)
+ -tpmpcrs <s> <e>- print PCRs
+ -tpmnvlist - List NV regions in TPM
+ -tpmcfg - Configure TPM
.SH DESCRIPTION
diff --git a/DcsCfg/DcsCfgMain.c b/DcsCfg/DcsCfgMain.c
index 59ff730..6e4c863 100644
--- a/DcsCfg/DcsCfgMain.c
+++ b/DcsCfg/DcsCfgMain.c
@@ -34,51 +34,53 @@ https://opensource.org/licenses/LGPL-3.0
//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
-#define OPT_DISK_CHECK L"-dc"
-#define OPT_DISK_LIST L"-dl"
-#define OPT_DISK_START L"-ds"
-#define OPT_DISK_END L"-de"
-#define OPT_DISK_BOOT L"-db"
-#define OPT_AUTH_ASK L"-aa"
-#define OPT_AUTH_CREATE_HEADER L"-ach"
-#define OPT_RND L"-rnd"
-#define OPT_RND_GEN L"-rndgen"
-#define OPT_RND_LOAD L"-rndload"
-#define OPT_RND_SAVE L"-rndsave"
-#define OPT_VOLUME_ENCRYPT L"-vec"
-#define OPT_VOLUME_DECRYPT L"-vdc"
-#define OPT_VOLUME_CHANGEPWD L"-vcp"
-#define OPT_USB_LIST L"-ul"
-#define OPT_TOUCH_LIST L"-tl"
-#define OPT_TOUCH_TEST L"-tt"
-#define OPT_GRAPH_LIST L"-gl"
-#define OPT_GRAPH_DEVICE L"-gd"
-#define OPT_GRAPH_MODE L"-gm"
-#define OPT_BEEP_LIST L"-bl"
-#define OPT_BEEP_TEST L"-bt"
-#define OPT_SETUP L"-setup"
-#define OPT_PARTITION_LIST L"-pl"
-#define OPT_PARTITION_FILE L"-pf"
-#define OPT_PARTITION_SAVE L"-ps"
-#define OPT_PARTITION_ZERO L"-pz"
-#define OPT_PARTITION_APPLY L"-pa"
-#define OPT_PARTITION_ENCRYPT L"-pe"
-#define OPT_PARTITION_DECRYPT L"-pd"
-#define OPT_PARTITION_IDX_TEMPLATE L"-pnt"
-#define OPT_PARTITION_HIDE L"-phide"
-#define OPT_PARTITION_EDIT L"-pedt"
-#define OPT_PARTITION_EDIT_EXEC L"-pexec"
-#define OPT_PARTITION_RND_LOAD L"-prndload"
-#define OPT_PARTITION_RND_SAVE L"-prndsave"
+#define OPT_DISK_CHECK L"-dc"
+#define OPT_DISK_LIST L"-dl"
+#define OPT_DISK_START L"-ds"
+#define OPT_DISK_END L"-de"
+#define OPT_DISK_BOOT L"-db"
+#define OPT_AUTH_ASK L"-aa"
+#define OPT_AUTH_CREATE_HEADER L"-ach"
+#define OPT_RND L"-rnd"
+#define OPT_RND_GEN L"-rndgen"
+#define OPT_RND_LOAD L"-rndload"
+#define OPT_RND_SAVE L"-rndsave"
+#define OPT_VOLUME_ENCRYPT L"-vec"
+#define OPT_VOLUME_DECRYPT L"-vdc"
+#define OPT_VOLUME_CHANGEPWD L"-vcp"
+#define OPT_USB_LIST L"-ul"
+#define OPT_TOUCH_LIST L"-tl"
+#define OPT_TOUCH_TEST L"-tt"
+#define OPT_GRAPH_LIST L"-gl"
+#define OPT_GRAPH_DEVICE L"-gd"
+#define OPT_GRAPH_MODE L"-gm"
+#define OPT_BEEP_LIST L"-bl"
+#define OPT_BEEP_TEST L"-bt"
+#define OPT_SETUP L"-setup"
+#define OPT_PARTITION_LIST L"-pl"
+#define OPT_PARTITION_FILE L"-pf"
+#define OPT_PARTITION_SAVE L"-ps"
+#define OPT_PARTITION_ZERO L"-pz"
+#define OPT_PARTITION_APPLY L"-pa"
+#define OPT_PARTITION_ENCRYPT L"-pe"
+#define OPT_PARTITION_DECRYPT L"-pd"
+#define OPT_PARTITION_IDX_TEMPLATE L"-pnt"
+#define OPT_PARTITION_HIDE L"-phide"
+#define OPT_PARTITION_EDIT L"-pedt"
+#define OPT_PARTITION_EDIT_EXEC L"-pexec"
+#define OPT_PARTITION_RND_LOAD L"-prndload"
+#define OPT_PARTITION_RND_SAVE L"-prndsave"
#define OPT_PARTITION_EDIT_PWD_CACHE L"-pwdcache"
-#define OPT_KEYFILE_PLATFORM L"-kp"
-#define OPT_SECREGION_MARK L"-srm"
-#define OPT_SECREGION_WIPE L"-srw"
-#define OPT_SECREGION_ADD L"-sra"
-#define OPT_WIPE L"-wipe"
-#define OPT_OS_DECRYPT L"-osdecrypt"
-#define OPT_OS_RESTORE_KEY L"-osrestorekey"
-
+#define OPT_KEYFILE_PLATFORM L"-kp"
+#define OPT_SECREGION_MARK L"-srm"
+#define OPT_SECREGION_WIPE L"-srw"
+#define OPT_SECREGION_ADD L"-sra"
+#define OPT_WIPE L"-wipe"
+#define OPT_OS_DECRYPT L"-osdecrypt"
+#define OPT_OS_RESTORE_KEY L"-osrestorekey"
+#define OPT_TPM_PCRS L"-tpmpcrs"
+#define OPT_TPM_NVLIST L"-tpmnvlist"
+#define OPT_TPM_CFG L"-tpmcfg"
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
{ OPT_DISK_LIST, TypeValue },
{ OPT_DISK_CHECK, TypeFlag },
@@ -124,6 +126,9 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
{ OPT_WIPE, TypeDoubleValue },
{ OPT_OS_DECRYPT, TypeFlag },
{ OPT_OS_RESTORE_KEY, TypeFlag },
+ { OPT_TPM_PCRS, TypeDoubleValue },
+ { OPT_TPM_NVLIST, TypeFlag },
+ { OPT_TPM_CFG, TypeFlag },
{ NULL, TypeMax }
};
@@ -257,6 +262,30 @@ DcsCfgMain(
TestTouch();
}
+ // TPM
+ if (ShellCommandLineGetFlag(Package, OPT_TPM_PCRS)) {
+ CONST CHAR16* opt1 = NULL;
+ CONST CHAR16* opt2 = NULL;
+ UINT32 sPcr;
+ UINT32 ePcr;
+ opt1 = ShellCommandLineGetValue(Package, OPT_TPM_PCRS);
+ sPcr = (UINT32)StrDecimalToUintn(opt1);
+ opt2 = StrStr(opt1, L" ");
+ if (opt2 != NULL) {
+ opt2++;
+ }
+ ePcr = (UINT32)StrDecimalToUintn(opt2);
+ Tpm12ListPcrs(sPcr, ePcr);
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_TPM_NVLIST)) {
+ Tpm12NvList();
+ }
+
+ if (ShellCommandLineGetFlag(Package, OPT_TPM_CFG)) {
+ Tpm12DcsConfigure();
+ }
+
// Graph
if (ShellCommandLineGetFlag(Package, OPT_GRAPH_DEVICE)) {
CONST CHAR16* opt = NULL;
@@ -294,15 +323,20 @@ DcsCfgMain(
// Create random
if (ShellCommandLineGetFlag(Package, OPT_RND)) {
CONST CHAR16* opt = NULL;
- CONST CHAR16* context = NULL;
+ CHAR16* context = NULL;
UINTN rndType;
+ UINTN contextSize = 0;
opt = ShellCommandLineGetValue(Package, OPT_RND);
rndType = StrDecimalToUintn(opt);
- context = StrStr(opt, L" ");
+ context = (CHAR16*)StrStr(opt, L" ");
if (context != NULL) {
context++;
+ contextSize = StrLen(context) * 2;
+ if (!EFI_ERROR(FileExist(NULL, context))) {
+ FileLoad(NULL, context, &context, &contextSize);
+ }
}
- res = RndInit(rndType, (CHAR16*)context, &gRnd);
+ res = RndInit(rndType, context, contextSize, &gRnd);
if (EFI_ERROR(res)) {
ERR_PRINT(L"Random: %r\n", res);
}
diff --git a/DcsCfg/DcsCfgTpm.c b/DcsCfg/DcsCfgTpm.c
new file mode 100644
index 0000000..5003132
--- /dev/null
+++ b/DcsCfg/DcsCfgTpm.c
@@ -0,0 +1,88 @@
+/** @file
+This is DCS configuration, TPM
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/DcsTpmLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DcsCfgLib.h>
+#include "DcsVeraCrypt.h"
+
+EFI_STATUS
+Tpm12ListPcrs(
+ UINT32 sPcr,
+ UINT32 ePcr
+ ) {
+ EFI_STATUS res;
+ res = InitTpm12();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ return res;
+ }
+ return Tpm12DumpPcrs(sPcr, ePcr);
+}
+
+EFI_STATUS
+Tpm12NvList(
+ ) {
+ EFI_STATUS res;
+ UINT32 count;
+ UINT32 i;
+ UINT32 nv[256];
+ res = InitTpm12();
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ return res;
+ }
+ count = sizeof(nv);
+ res = Tpm12GetNvList(&count, nv);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ return res;
+ }
+ count = count >> 2;
+ for (i = 0; i < count; ++i) {
+ UINT32 index = SwapBytes32(nv[i]);
+ UINT32 attr = 0;
+ UINT32 dataSz = 0;
+ UINT32 pcrR = 0;
+ UINT32 pcrW = 0;
+ OUT_PRINT(L"%H%08x%N ", index);
+ res = Tpm12NvDetails(index, &attr, &dataSz, &pcrR, &pcrW);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ continue;
+ }
+
+ OUT_PRINT(L"Attr[%08x] PcrR[%08x] PcrW[%08x] [%d] ", attr, pcrR, pcrW, dataSz);
+ OUT_PRINT(L"\n");
+ }
+ return res;
+}
+
+EFI_STATUS
+Tpm12DcsConfigure(
+ ) {
+ EFI_STATUS res;
+ Password pwd;
+ ZeroMem(&pwd, sizeof(pwd));
+ CE(GetTpm());
+ CE(RndInit(RndTypeTpm, NULL, 0, &gRnd));
+ CE(gTpm->Configure(gTpm));
+ CE(gTpm->Apply(gTpm, &pwd));
+ return res;
+
+err:
+ ERR_PRINT(L"%r, line %d", res, gCELine);
+ return res;
+}
diff --git a/DcsInt/DcsInt.c b/DcsInt/DcsInt.c
index 6d008cc..af2391b 100644
--- a/DcsInt/DcsInt.c
+++ b/DcsInt/DcsInt.c
@@ -23,6 +23,7 @@ https://opensource.org/licenses/LGPL-3.0
#include <Library/PasswordLib.h>
#include <Library/BaseLib.h>
#include <Library/DcsCfgLib.h>
+#include <Library/DcsTpmLib.h>
#include "common/Tcdefs.h"
#include "common/Crypto.h"
@@ -262,7 +263,7 @@ IntBlockIO_Write(
writeCrypted = MEM_ALLOC(BufferSize);
if (writeCrypted == NULL) {
Status = EFI_BAD_BUFFER_SIZE;
- return Status;
+ return Status;
}
CopyMem(writeCrypted, Buffer, BufferSize);
// Print(L"*");
@@ -354,7 +355,7 @@ IntBlockIo_Hook(
DcsIntBlockIo->Controller = DeviceHandle;
DcsIntBlockIo->BlockIo = BlockIo;
DcsIntBlockIo->IsReinstalled = 0;
-// Block
+// Block
// Tpl = gBS->RaiseTPL(TPL_NOTIFY);
// Install new routines
DcsIntBlockIo->CryptInfo = SecRegionCryptInfo;
@@ -570,28 +571,28 @@ SecRegionChangePwd() {
if (vcres != 0) {
ERR_PRINT(L"header create error(%x)\n", vcres);
- Status = EFI_INVALID_PARAMETER;
- goto ret;
+ Status = EFI_INVALID_PARAMETER;
+ goto ret;
}
// get BlockIo protocol
bio = EfiGetBlockIO(SecRegionHandle);
if (bio == NULL) {
ERR_PRINT(L"Block io not supported\n,");
- Status = EFI_NOT_FOUND;
- goto ret;
+ Status = EFI_NOT_FOUND;
+ goto ret;
}
Status = bio->WriteBlocks(bio, bio->Media->MediaId, SecRegionSector, 512, Header);
if (EFI_ERROR(Status)) {
ERR_PRINT(L"Write: %r\n", Status);
- goto ret;
+ goto ret;
}
CopyMem(&gAuthPassword, &newPassword, sizeof(gAuthPassword));
CopyMem(SecRegionData + SecRegionOffset, Header, 512);
ERR_PRINT(L"Update (%r)\n", Status);
-
-ret:
+
+ret:
MEM_BURN(&newPassword, sizeof(newPassword));
MEM_BURN(&confirmPassword, sizeof(confirmPassword));
return Status;
@@ -644,7 +645,7 @@ SecRegionTryDecrypt()
} 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);
+ OUT_PRINT(L"Start %d %lld len %lld\n", SecRegionOffset / (1024*128), SecRegionCryptInfo->EncryptedAreaStart.Value, SecRegionCryptInfo->EncryptedAreaLength.Value);
break;
} else {
ERR_PRINT(L"Authorization failed. Wrong password, PIM or hash. Decrypt error(%x)\n\r", vcres);
@@ -963,6 +964,7 @@ UefiMain(
if (key.UnicodeChar != 0) {
GetKey();
}
+ OUT_PRINT(L"\n");
}
} else if (gRUD != 0) {
// RUD defined
@@ -1020,12 +1022,26 @@ UefiMain(
return res;
}
+ res = GetTpm(); // Try to get TPM
+ if (!EFI_ERROR(res)) {
+ if (gConfigBuffer != NULL) {
+ TpmMeasure(gConfigBuffer, gConfigBufferSize); // Measure configuration
+ }
+ RndInit(RndTypeTpm, NULL, 0, &gRnd);
+ if (gTpm->IsConfigured(gTpm) && !gTpm->IsOpen(gTpm)) {
+ ERR_PRINT(L"TPM is configured but locked. Probably boot chain is modified!\n");
+ KeyWait(L"%1d\r", 9, 0, 0);
+ }
+ }
+
DetectX86Features();
res = SecRegionTryDecrypt();
-
- // Reset Console buffer
- gST->ConIn->Reset(gST->ConIn, FALSE);
-
+ if (gTpm != NULL) {
+ gTpm->Lock(gTpm);
+ }
+ // Reset Console buffer
+ gST->ConIn->Reset(gST->ConIn, FALSE);
+
if (EFI_ERROR(res)) {
return OnExit(gOnExitFailed, OnExitAuthFaild, res);
}
diff --git a/DcsPkg.dsc b/DcsPkg.dsc
index e3e4963..8b1004f 100644
--- a/DcsPkg.dsc
+++ b/DcsPkg.dsc
@@ -44,6 +44,10 @@
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+
Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
@@ -61,6 +65,7 @@
PasswordLib|DcsPkg/Library/PasswordLib/PasswordLib.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
DcsCfgLib|DcsPkg/Library/DcsCfgLib/DcsCfgLib.inf
+ DcsTpmLib|DcsPkg/Library/DcsTpmLib/DcsTpmLib.inf
VeraCryptLib|DcsPkg/Library/VeraCryptLib/VeraCryptLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
diff --git a/DcsRe/DcsRe.c b/DcsRe/DcsRe.c
index 1278eea..1d86e50 100644
--- a/DcsRe/DcsRe.c
+++ b/DcsRe/DcsRe.c
@@ -23,61 +23,11 @@ https://opensource.org/licenses/LGPL-3.0
//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////
-typedef EFI_STATUS(*MENU_ACTION)();
-
-typedef struct _MENU_ITEM MENU_ITEM;
-typedef struct _MENU_ITEM {
- CHAR16 Text[128];
- CHAR16 Select;
- MENU_ACTION Action;
- MENU_ITEM *Next;
-} MENU_ITEM, *PMENU_ITEM;
BOOLEAN gContiniue = TRUE;
PMENU_ITEM gMenu = NULL;
-PMENU_ITEM
-AppendMenu(
- IN PMENU_ITEM menu,
- IN CHAR16 *text,
- IN CHAR16 select,
- IN MENU_ACTION action
- ) {
- PMENU_ITEM item;
- item = (PMENU_ITEM)MEM_ALLOC(sizeof(MENU_ITEM));
- if (item == NULL) return item;
- item->Action = action;
- StrCatS(item->Text, sizeof (item->Text) / sizeof (CHAR16), text);
- item->Select = select;
- if (menu != NULL) {
- menu->Next = item;
- }
- return item;
-}
-VOID
-PrintMenu(
- PMENU_ITEM head) {
- PMENU_ITEM menu;
- UINTN i = 0;
- menu = head;
- while (menu != NULL) {
- OUT_PRINT(L"%H%c%N) %s\n", menu->Select, &menu->Text);
- i++;
- if (i == 22) {
- ConsoleShowTip(L"Pause 60s", 60000000);
- i = 0;
- }
- menu = menu->Next;
- }
- OUT_PRINT(L"[");
- menu = head;
- while (menu != NULL) {
- OUT_PRINT(L"%H%c%N", menu->Select);
- menu = menu->Next;
- }
- OUT_PRINT(L"]:");
-}
//////////////////////////////////////////////////////////////////////////
// EFI volume
//////////////////////////////////////////////////////////////////////////
@@ -144,7 +94,7 @@ SelectEfiVolume()
// Actions
//////////////////////////////////////////////////////////////////////////
EFI_STATUS
-ActionBootWinPE() {
+ActionBootWinPE(IN VOID* ctx) {
#ifdef _M_X64
return EfiExec(NULL, L"EFI\\Boot\\WinPE_bootx64.efi");
#else
@@ -153,12 +103,12 @@ ActionBootWinPE() {
}
EFI_STATUS
-ActionShell() {
+ActionShell(IN VOID* ctx) {
return EfiExec(NULL, L"EFI\\Shell\\Shell.efi");
}
EFI_STATUS
-ActionDcsBoot() {
+ActionDcsBoot(IN VOID* ctx) {
SelectEfiVolume();
if (EfiBootVolume == NULL) return EFI_NOT_READY;
return EfiExec(gFSHandles[EfiBootVolumeIndex], L"EFI\\VeraCrypt\\DcsBoot.efi");
@@ -176,7 +126,7 @@ CHAR16* DcsBootBins[] = {
Copy DCS binaries from rescue disk to EFI boot volume
*/
EFI_STATUS
-ActionRestoreDcsLoader() {
+ActionRestoreDcsLoader(IN VOID* ctx) {
EFI_STATUS res = EFI_NOT_READY;
UINTN i;
SelectEfiVolume();
@@ -194,7 +144,7 @@ CHAR16* sDcsBootEfiDesc = L"VeraCrypt(DCS) loader";
Update boot menu
*/
EFI_STATUS
-ActionRestoreDcsBootMenu()
+ActionRestoreDcsBootMenu(IN VOID* ctx)
{
EFI_STATUS res = EFI_NOT_READY;
SelectEfiVolume();
@@ -207,7 +157,7 @@ ActionRestoreDcsBootMenu()
}
EFI_STATUS
-ActionRemoveDcsBootMenu()
+ActionRemoveDcsBootMenu(IN VOID* ctx)
{
EFI_STATUS res = EFI_NOT_READY;
BootMenuItemRemove(L"BootDC5B");
@@ -219,7 +169,7 @@ ActionRemoveDcsBootMenu()
Copy DcsProp from rescue disk to EFI boot volume
*/
EFI_STATUS
-ActionRestoreDcsProp() {
+ActionRestoreDcsProp(IN VOID* ctx) {
SelectEfiVolume();
if (EfiBootVolume == NULL) return EFI_NOT_READY;
return FileCopy(NULL, L"EFI\\VeraCrypt\\DcsProp", EfiBootVolume, L"EFI\\VeraCrypt\\DcsProp", 1024*1024);
@@ -233,27 +183,27 @@ CHAR16* sOSRestoreKey = OPT_OS_RESTORE_KEY;
CHAR16* sDcsCfg = L"EFI\\VeraCrypt\\DcsCfg.dcs";
EFI_STATUS
-ActionRestoreHeader() {
+ActionRestoreHeader(IN VOID* ctx) {
EFI_STATUS res = EFI_NOT_READY;
res = EfiSetVar(L"dcscfgcmd", NULL, sOSRestoreKey, StrSize(sOSRestoreKey), EFI_VARIABLE_BOOTSERVICE_ACCESS);
return EfiExec(NULL, sDcsCfg);
}
EFI_STATUS
-ActionDecryptOS() {
+ActionDecryptOS(IN VOID* ctx) {
EFI_STATUS res = EFI_NOT_READY;
res = EfiSetVar(L"dcscfgcmd", NULL, sOSDecrypt, StrSize(sOSDecrypt), EFI_VARIABLE_BOOTSERVICE_ACCESS);
return EfiExec(NULL, sDcsCfg);
}
EFI_STATUS
-ActionExit() {
+ActionExit(IN VOID* ctx) {
gContiniue = FALSE;
return EFI_SUCCESS;
}
EFI_STATUS
-ActionHelp() {
+ActionHelp(IN VOID* ctx) {
OUT_PRINT(L"\
%HRescue disk for VeraCrypt OS encryption%N\n\r\
Help message to be defined\n\r\
@@ -288,42 +238,38 @@ DcsReMain(
return res;
}
- item = AppendMenu(NULL, L"Decrypt OS", 'd', ActionDecryptOS);
+ item = DcsMenuAppend(NULL, L"Decrypt OS", 'd', ActionDecryptOS, NULL);
gMenu = item;
- item = AppendMenu(item, L"Restore VeraCrypt loader to boot menu", 'm', ActionRestoreDcsBootMenu);
- item = AppendMenu(item, L"Remove VeraCrypt loader from boot menu", 'z' , ActionRemoveDcsBootMenu);
+ item = DcsMenuAppend(item, L"Restore VeraCrypt loader to boot menu", 'm', ActionRestoreDcsBootMenu, NULL);
+ item = DcsMenuAppend(item, L"Remove VeraCrypt loader from boot menu", 'z' , ActionRemoveDcsBootMenu, NULL);
if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\DcsProp"))) {
- item = AppendMenu(item, L"Restore VeraCrypt loader configuration to system disk", 'c', ActionRestoreDcsProp);
+ item = DcsMenuAppend(item, L"Restore VeraCrypt loader configuration to system disk", 'c', ActionRestoreDcsProp, NULL);
}
if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\svh_bak"))) {
- item = AppendMenu(item, L"Restore OS header keys", 'k', ActionRestoreHeader);
+ item = DcsMenuAppend(item, L"Restore OS header keys", 'k', ActionRestoreHeader, NULL);
}
if (!EFI_ERROR(FileExist(NULL, L"EFI\\VeraCrypt\\DcsBoot.efi"))) {
- item = AppendMenu(item, L"Restore VeraCrypt loader binaries to system disk", 'r', ActionRestoreDcsLoader);
- item = AppendMenu(item, L"Boot VeraCrypt loader from rescue disk", 'v', ActionDcsBoot);
+ item = DcsMenuAppend(item, L"Restore VeraCrypt loader binaries to system disk", 'r', ActionRestoreDcsLoader, NULL);
+ item = DcsMenuAppend(item, L"Boot VeraCrypt loader from rescue disk", 'v', ActionDcsBoot, NULL);
}
-#ifdef _M_X64
if (!EFI_ERROR(FileExist(NULL, L"EFI\\Boot\\WinPE_bootx64.efi"))) {
-#else
- if (!EFI_ERROR(FileExist(NULL, L"EFI\\Boot\\WinPE_bootia32.efi"))) {
-#endif
- item = AppendMenu(item, L"Boot Windows PE from rescue disk", 'w', ActionBootWinPE);
+ item = DcsMenuAppend(item, L"Boot Windows PE from rescue disk", 'w', ActionBootWinPE, NULL);
}
if (!EFI_ERROR(FileExist(NULL, L"EFI\\Shell\\Shell.efi"))) {
- item = AppendMenu(item, L"Boot Shell.efi from rescue disk", 's', ActionShell);
+ item = DcsMenuAppend(item, L"Boot Shell.efi from rescue disk", 's', ActionShell, NULL);
}
- item = AppendMenu(item, L"Help", 'h', ActionHelp);
- item = AppendMenu(item, L"Exit", 'e', ActionExit);
+ item = DcsMenuAppend(item, L"Help", 'h', ActionHelp, NULL);
+ item = DcsMenuAppend(item, L"Exit", 'e', ActionExit, NULL);
OUT_PRINT(L"%V%a rescue disk %a%N\n", TC_APP_NAME, VERSION_STRING);
gBS->SetWatchdogTimer(0, 0, 0, NULL);
do {
- PrintMenu(gMenu);
+ DcsMenuPrint(gMenu);
item = NULL;
key.UnicodeChar = 0;
while (item == NULL) {
@@ -335,7 +281,7 @@ DcsReMain(
}
}
OUT_PRINT(L"%c\n",key.UnicodeChar);
- res = item->Action();
+ res = item->Action(item->Context);
if (EFI_ERROR(res)) {
ERR_PRINT(L"%r\n", res);
}
diff --git a/Include/Library/CommonLib.h b/Include/Library/CommonLib.h
index e1e30b0..5f96bba 100644
--- a/Include/Library/CommonLib.h
+++ b/Include/Library/CommonLib.h
@@ -22,6 +22,15 @@ https://opensource.org/licenses/LGPL-3.0
#include <Protocol/AbsolutePointer.h>
#include <Guid/FileInfo.h>
+//////////////////////////////////////////////////////////////////////////
+// Check error
+//////////////////////////////////////////////////////////////////////////
+extern UINTN gCELine;
+#define CE(ex) gCELine = __LINE__; if(EFI_ERROR(res = ex)) goto err
+
+//////////////////////////////////////////////////////////////////////////
+// defines
+//////////////////////////////////////////////////////////////////////////
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
#define FIELD_OFFSET(t, f) ((UINTN)(&((t*)0)->f))
@@ -32,7 +41,7 @@ https://opensource.org/licenses/LGPL-3.0
#define MEM_ALLOC MemAlloc
#define MEM_FREE MemFree
#define MEM_REALLOC MemRealloc
-#define MEM_BURN(ptr,count) do { volatile char *burnPtr = (volatile char *)(ptr); UINT64 burnCount = (UINT64) count; while (burnCount--) *burnPtr++ = 0; } while (0)
+#define MEM_BURN(ptr,count) do { volatile char *burnPtr = (volatile char *)(ptr); UINTN burnCount = (UINTN) count; while (burnCount--) *burnPtr++ = 0; } while (0)
VOID*
MemAlloc(
@@ -182,6 +191,11 @@ TouchGetIO(
#define OUT_PRINT(format, ...) AttrPrintEx(-1,-1, format, ##__VA_ARGS__)
#define ERR_PRINT(format, ...) AttrPrintEx(-1,-1, L"%E" format L"%N" , ##__VA_ARGS__)
+VOID
+PrintBytes(
+ IN UINT8* Data,
+ IN UINT32 Size);
+
EFI_STATUS
ConsoleGetOutput(
IN EFI_HANDLE handle,
@@ -270,6 +284,33 @@ AsciiStrToGuid(
IN CHAR8 *str
);
+//////////////////////////////////////////////////////////////////////////
+// Menu
+//////////////////////////////////////////////////////////////////////////
+typedef EFI_STATUS(*MENU_ACTION)(IN VOID *ctx);
+
+typedef struct _MENU_ITEM MENU_ITEM;
+typedef struct _MENU_ITEM {
+ CHAR16 Text[128];
+ CHAR16 Select;
+ MENU_ACTION Action;
+ VOID* Context;
+ MENU_ITEM *Next;
+} MENU_ITEM, *PMENU_ITEM;
+
+PMENU_ITEM
+DcsMenuAppend(
+ IN PMENU_ITEM menu,
+ IN CHAR16 *text,
+ IN CHAR16 select,
+ IN MENU_ACTION action,
+ IN VOID* actionContext
+ );
+
+VOID
+DcsMenuPrint(
+ IN PMENU_ITEM head
+ );
//////////////////////////////////////////////////////////////////////////
// Attribute print
diff --git a/Include/Library/DcsCfgLib.h b/Include/Library/DcsCfgLib.h
index 6d74729..322aaa1 100644
--- a/Include/Library/DcsCfgLib.h
+++ b/Include/Library/DcsCfgLib.h
@@ -118,7 +118,9 @@ enum RndGeneratorTypes {
RndTypeNone = 0,
RndTypeFile,
RndTypeRDRand,
- RndTypeDtrmHmacSha512
+ RndTypeDtrmHmacSha512,
+ RndTypeOpenSSL,
+ RndTypeTpm
};
#define RND_HEADER_SIGN SIGNATURE_64('D','C','S','_','R','A','N','D')
@@ -186,6 +188,7 @@ EFI_STATUS
RndInit(
IN UINTN rndType,
IN VOID* Context,
+ IN UINTN ContextSize,
OUT DCS_RND **rnd);
// Serialize rnd with state to/from memory
diff --git a/Include/Library/DcsTpmLib.h b/Include/Library/DcsTpmLib.h
new file mode 100644
index 0000000..a8f015e
--- /dev/null
+++ b/Include/Library/DcsTpmLib.h
@@ -0,0 +1,106 @@
+/** @file
+Dcs TPM library
+
+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 __DCSTPMLIB_H__
+#define __DCSTPMLIB_H__
+
+#include <Uefi.h>
+
+EFI_STATUS
+InitTpm12();
+
+EFI_STATUS
+Tpm12PcrRead(
+ IN UINT32 PcrIndex,
+ OUT void *PcrValue
+ );
+
+EFI_STATUS
+Tpm12DumpPcrs(
+ IN UINT32 sPcr,
+ IN UINT32 ePcr);
+
+EFI_STATUS
+Tpm12GetNvList(
+ OUT UINT32 *respSize,
+ OUT UINT32 *resp
+ );
+
+EFI_STATUS
+Tpm12NvDetails(
+ IN UINT32 index,
+ OUT UINT32 *attr,
+ OUT UINT32 *dataSz,
+ OUT UINT32 *pcrR,
+ OUT UINT32 *pcrW
+ );
+
+EFI_STATUS
+Tpm12GetRandom(
+ IN OUT UINT32 *DataSize,
+ OUT UINT8 *Data
+ );
+
+//////////////////////////////////////////////////////////////////////////
+// DCS TPM protocol
+//////////////////////////////////////////////////////////////////////////
+/*
+Lock - Try lock TPM secret
+Apply - Apply secret to password
+Configure - Create TPM secret and configure PCRs
+IsConfigured - TPM secret is set?
+IsOpen - Can apply secret?
+*/
+typedef struct _DCS_TPM_PROTOCOL DCS_TPM_PROTOCOL;
+
+extern DCS_TPM_PROTOCOL* gTpm;
+
+typedef EFI_STATUS(*DCS_TPM_LOCK)(
+ IN DCS_TPM_PROTOCOL *tpm
+ );
+
+typedef EFI_STATUS(*DCS_TPM_APPLY)(
+ IN DCS_TPM_PROTOCOL *tpm,
+ OUT VOID* pwd
+ );
+
+typedef EFI_STATUS(*DCS_TPM_CONFIGURE)(
+ IN DCS_TPM_PROTOCOL *tpm
+ );
+
+typedef BOOLEAN(*DCS_TPM_IS_OPEN)(
+ IN DCS_TPM_PROTOCOL *tpm
+ );
+
+typedef BOOLEAN(*DCS_TPM_IS_CONFIGURED)(
+ IN DCS_TPM_PROTOCOL *tpm
+ );
+
+typedef struct _DCS_TPM_PROTOCOL {
+ DCS_TPM_LOCK Lock;
+ DCS_TPM_APPLY Apply;
+ DCS_TPM_CONFIGURE Configure;
+ DCS_TPM_IS_OPEN IsOpen;
+ DCS_TPM_IS_CONFIGURED IsConfigured;
+} DCS_TPM_PROTOCOL;
+
+EFI_STATUS
+GetTpm();
+
+EFI_STATUS
+TpmMeasure(
+ IN VOID* data,
+ IN UINTN dataSz
+ );
+
+#endif \ No newline at end of file
diff --git a/Library/CommonLib/EfiConsole.c b/Library/CommonLib/EfiConsole.c
index f03f3f8..63b32ae 100644
--- a/Library/CommonLib/EfiConsole.c
+++ b/Library/CommonLib/EfiConsole.c
@@ -19,10 +19,27 @@ https://opensource.org/licenses/LGPL-3.0
#include <Protocol/ConsoleControl.h>
#include <Protocol/Speaker.h>
+UINTN gCELine = 0;
+
//////////////////////////////////////////////////////////////////////////
// Print
//////////////////////////////////////////////////////////////////////////
+VOID
+PrintBytes(
+ IN UINT8* Data,
+ IN UINT32 Size)
+{
+ UINT32 i;
+ for (i = 0; i < Size; ++i) {
+ UINT32 val = Data[i];
+ OUT_PRINT(L"%02X", val);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Input
+//////////////////////////////////////////////////////////////////////////
VOID
FlushInputDelay(
IN UINTN delay
@@ -327,6 +344,56 @@ AsciiStrToGuid(
return res;
}
+//////////////////////////////////////////////////////////////////////////
+// Console menu
+//////////////////////////////////////////////////////////////////////////
+
+PMENU_ITEM
+DcsMenuAppend(
+ IN PMENU_ITEM menu,
+ IN CHAR16 *text,
+ IN CHAR16 select,
+ IN MENU_ACTION action,
+ IN VOID* actionContext
+ ) {
+ PMENU_ITEM item;
+ item = (PMENU_ITEM)MEM_ALLOC(sizeof(MENU_ITEM));
+ if (item == NULL) return item;
+ item->Action = action;
+ item->Context = actionContext;
+ StrCat(item->Text, text);
+ item->Select = select;
+ if (menu != NULL) {
+ menu->Next = item;
+ }
+ return item;
+}
+
+VOID
+DcsMenuPrint(
+ IN PMENU_ITEM head
+ )
+{
+ PMENU_ITEM menu;
+ UINTN i = 0;
+ menu = head;
+ while (menu != NULL) {
+ OUT_PRINT(L"%H%c%N) %s\n", menu->Select, &menu->Text);
+ i++;
+ if (i == 22) {
+ ConsoleShowTip(L"Pause 60s", 60000000);
+ i = 0;
+ }
+ menu = menu->Next;
+ }
+ OUT_PRINT(L"[");
+ menu = head;
+ while (menu != NULL) {
+ OUT_PRINT(L"%H%c%N", menu->Select);
+ menu = menu->Next;
+ }
+ OUT_PRINT(L"]:");
+}
//////////////////////////////////////////////////////////////////////////
diff --git a/Library/DcsCfgLib/DcsCfgLib.inf b/Library/DcsCfgLib/DcsCfgLib.inf
index 8607cb4..d199bb1 100644
--- a/Library/DcsCfgLib/DcsCfgLib.inf
+++ b/Library/DcsCfgLib/DcsCfgLib.inf
@@ -36,11 +36,14 @@ DcsRandom.c
[Packages]
MdePkg/MdePkg.dec
DcsPkg/DcsPkg.dec
+ CryptoPkg/CryptoPkg.dec
[LibraryClasses]
MemoryAllocationLib
UefiLib
RngLib
+ BaseCryptLib
+ DcsTpmLib
[Protocols]
diff --git a/Library/DcsCfgLib/DcsRandom.c b/Library/DcsCfgLib/DcsRandom.c
index a269a46..084a8cf 100644
--- a/Library/DcsCfgLib/DcsRandom.c
+++ b/Library/DcsCfgLib/DcsRandom.c
@@ -18,9 +18,11 @@ https://opensource.org/licenses/LGPL-3.0
#include <Library/CommonLib.h>
#include <Library/RngLib.h>
#include <Library/DcsCfgLib.h>
+#include <Library/BaseCryptLib.h>
#include <common/Pkcs5.h>
#include <crypto/sha2.h>
+#include "../../Include/Library/DcsTpmLib.h"
DCS_RND* gRnd = NULL;
@@ -61,7 +63,8 @@ RndFileGetBytes(
EFI_STATUS
RndFileInit(
IN DCS_RND* rnd,
- IN VOID* Context
+ IN VOID* Context,
+ IN UINTN ContextSize
)
{
EFI_STATUS res = EFI_NOT_FOUND;
@@ -70,10 +73,8 @@ RndFileInit(
rnd->GetBytes = RndFileGetBytes;
rnd->Prepare = RndFilePrepare;
if (Context != NULL) {
- res = FileLoad(NULL, (CHAR16*)Context, &rnd->State.File.Data, &rnd->State.File.Size);
- if (!EFI_ERROR(res)) {
- return rnd->Prepare(rnd);
- }
+ rnd->State.File.Data = Context;
+ rnd->State.File.Size = ContextSize;
}
return res;
}
@@ -121,7 +122,8 @@ RndRDRandGetBytes(
EFI_STATUS
RndRDRandInit(
IN DCS_RND* rnd,
- IN VOID* Context
+ IN VOID* Context,
+ IN UINTN ContextSize
)
{
ZeroMem(rnd, sizeof(DCS_RND));
@@ -321,8 +323,8 @@ RndDtrmHmacSha512GetBytes(
EFI_STATUS
RndDtrmHmacSha512Init(
IN DCS_RND* rnd,
- IN VOID* Context
- )
+ IN VOID* Context,
+ IN UINTN ContextSize)
{
EFI_STATUS res = EFI_SUCCESS;
ZeroMem(rnd, sizeof(DCS_RND));
@@ -331,31 +333,115 @@ RndDtrmHmacSha512Init(
rnd->Prepare = RndDtrmHmacSha512Prepare;
if (Context != NULL) {
- CHAR16* type = (CHAR16*)Context;
- if (*type == '_') {
- UINT8* data;
- UINTN size;
- type++;
- res = FileLoad(NULL, (CHAR16*)type, &data, &size);
- if (EFI_ERROR(res)) {
- rnd->Type = RndTypeNone;
- }
- res = RndDtrmHmacSha512Update(&rnd->State.HMacSha512, data, size, 0);
- if (EFI_ERROR(res)) {
- rnd->Type = RndTypeNone;
- }
+ res = RndDtrmHmacSha512Update(&rnd->State.HMacSha512, (UINT8*)Context, ContextSize, 0);
+ if (EFI_ERROR(res)) {
+ rnd->Type = RndTypeNone;
}
}
return rnd->Prepare(rnd);
}
//////////////////////////////////////////////////////////////////////////
+// OpenSSL random
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+RndOpenSSLPrepare(
+ IN DCS_RND* rnd
+ )
+{
+ UINT64 rndTmp;
+ if (rnd != NULL && rnd->Type == RndTypeOpenSSL) {
+ if (RandomBytes((UINT8*)&rndTmp, 8)) {
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndOpenSSLGetBytes(
+ IN DCS_RND *rnd,
+ OUT UINT8 *buf,
+ IN UINTN len)
+{
+ if (rnd != NULL && rnd->Type == RndTypeOpenSSL) {
+ if (RandomBytes(buf, len)) {
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndOpenSSLInit(
+ IN DCS_RND* rnd,
+ IN VOID* Context,
+ IN UINTN ContextSize
+ )
+{
+ int res;
+ ZeroMem(rnd, sizeof(DCS_RND));
+ rnd->Type = RndTypeOpenSSL;
+ rnd->GetBytes = RndOpenSSLGetBytes;
+ rnd->Prepare = RndOpenSSLPrepare;
+ res = RandomSeed(Context, ContextSize);
+ if (!res) {
+ return EFI_NOT_READY;
+ }
+ return rnd->Prepare(rnd);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// TPM random
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+RndTpmPrepare(
+ IN DCS_RND* rnd
+ )
+{
+ UINT64 rndTmp;
+ UINT32 sz = sizeof(rndTmp);
+ if (rnd != NULL && rnd->Type == RndTypeTpm) {
+ return Tpm12GetRandom(&sz, (UINT8*)&rndTmp);
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndTpmGetBytes(
+ IN DCS_RND *rnd,
+ OUT UINT8 *buf,
+ IN UINTN len)
+{
+ UINT32 sz = (UINT32)len;
+ if (rnd != NULL && rnd->Type == RndTypeTpm) {
+ return Tpm12GetRandom(&sz, buf);
+ }
+ return EFI_NOT_READY;
+}
+
+EFI_STATUS
+RndTpmInit(
+ IN DCS_RND* rnd,
+ IN VOID* Context,
+ IN UINTN ContextSize
+ )
+{
+ ZeroMem(rnd, sizeof(DCS_RND));
+ rnd->Type = RndTypeTpm;
+ rnd->GetBytes = RndTpmGetBytes;
+ rnd->Prepare = RndTpmPrepare;
+ return rnd->Prepare(rnd);
+}
+
+//////////////////////////////////////////////////////////////////////////
// Random API
//////////////////////////////////////////////////////////////////////////
EFI_STATUS
RndInit(
IN UINTN rndType,
IN VOID* Context,
+ IN UINTN ContextSize,
OUT DCS_RND **rnd)
{
if (rnd != NULL) {
@@ -366,13 +452,19 @@ RndInit(
rndTemp->Type = (UINT32)rndType;
switch (rndType) {
case RndTypeFile:
- res = RndFileInit(rndTemp, Context);
+ res = RndFileInit(rndTemp, Context, ContextSize);
break;
case RndTypeRDRand:
- res = RndRDRandInit(rndTemp, Context);
+ res = RndRDRandInit(rndTemp, Context, ContextSize);
break;
case RndTypeDtrmHmacSha512:
- res = RndDtrmHmacSha512Init(rndTemp, Context);
+ res = RndDtrmHmacSha512Init(rndTemp, Context, ContextSize);
+ break;
+ case RndTypeOpenSSL:
+ res = RndOpenSSLInit(rndTemp, Context, ContextSize);
+ break;
+ case RndTypeTpm:
+ res = RndTpmInit(rndTemp, Context, ContextSize);
break;
}
if (EFI_ERROR(res)) {
@@ -417,7 +509,7 @@ RndSave(
EFI_STATUS res = EFI_NOT_READY;
DCS_RND_SAVED *RndSaved;
UINT32 crc;
- if (rnd != NULL && rndSaved != NULL && rnd->Type != RndTypeFile) {
+ if (rnd != NULL && rndSaved != NULL && rnd->Type != RndTypeFile && rnd->Type != RndTypeOpenSSL) {
RndSaved = MEM_ALLOC(sizeof(DCS_RND_SAVED));
if (RndSaved != NULL) {
RndSaved->Size = sizeof(DCS_RND_SAVED);
@@ -452,7 +544,7 @@ RndLoad(
if (EFI_ERROR(res) || crc != crcSaved || rndSaved->Sign != gRndHeaderSign) {
return EFI_CRC_ERROR;
}
- res = RndInit(rndSaved->Type, NULL, rndOut);
+ res = RndInit(rndSaved->Type, NULL, 0, rndOut);
if (!EFI_ERROR(res)) {
CopyMem(&((*rndOut)->State), &rndSaved->State, sizeof(DCS_RND_STATE));
}
diff --git a/Library/DcsTpmLib/DcsTpmLib.inf b/Library/DcsTpmLib/DcsTpmLib.inf
new file mode 100644
index 0000000..79ea0f7
--- /dev/null
+++ b/Library/DcsTpmLib/DcsTpmLib.inf
@@ -0,0 +1,48 @@
+## @file
+# TPM library
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = DcsTpmLib
+ MODULE_UNI_FILE = DcsTpmLib.uni
+ FILE_GUID = D920E43F-730D-4C48-9BF6-5FA81C5F7697
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DcsTpmLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ Tpm12.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+ SecurityPkg/SecurityPkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+ Tpm12DeviceLib
+ BaseCryptLib
+
+[Protocols]
+ gEfiTcgProtocolGuid
+
+# [Guids]
+
diff --git a/Library/DcsTpmLib/Tpm12.c b/Library/DcsTpmLib/Tpm12.c
new file mode 100644
index 0000000..502677b
--- /dev/null
+++ b/Library/DcsTpmLib/Tpm12.c
@@ -0,0 +1,1344 @@
+/** @file
+EFI TPM12 helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DcsTpmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseCryptLib.h>
+
+#include <IndustryStandard/Tpm12.h>
+#include <IndustryStandard/TcpaAcpi.h>
+#include <Library/Tpm12DeviceLib.h>
+#include <Protocol/TcgService.h>
+#include "Library/DcsCfgLib.h"
+
+
+#define TPM_PREPARE Tpm12RequestUseTpm
+#define TPM_TRANSMIT Tpm12SubmitCommand
+
+//#pragma warning(disable: 4706)
+
+extern EFI_TCG_PROTOCOL *mTcgProtocol;
+
+EFI_STATUS
+InitTpm12() {
+ EFI_STATUS res = EFI_SUCCESS;
+ if (mTcgProtocol == NULL) {
+ return TPM_PREPARE();
+ }
+ return res;
+}
+
+typedef struct {
+ UINT8 *Cmd;
+ UINTN CmdPos;
+ UINTN CmdSize;
+ UINT8 *Resp;
+ UINTN RespPos;
+ UINTN RespSize;
+ UINT8 *Hash;
+} DCS_TPM12IO;
+
+EFI_STATUS
+Sha1Hash(
+ IN VOID *data,
+ IN UINTN dataSize,
+ OUT UINT8 *hash
+ )
+{
+ UINTN ctxSize;
+ VOID *ctx;
+ ctxSize = Sha1GetContextSize();
+ ctx = MEM_ALLOC(ctxSize);
+ if (ctx == NULL) return EFI_BUFFER_TOO_SMALL;
+ Sha1Init(ctx);
+ Sha1Update(ctx, data, dataSize);
+ if (!Sha1Final(ctx, hash)) return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// TPM IO Create/ Free
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12IOCreate(
+ DCS_TPM12IO **tpmio,
+ UINTN cmdSize,
+ UINTN respSize)
+{
+ DCS_TPM12IO *io;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ io = *tpmio;
+ if (io == NULL) {
+ io = MEM_ALLOC(sizeof(*io));
+ if (io == NULL) return EFI_BUFFER_TOO_SMALL;
+ }
+ if (io->CmdSize < cmdSize) {
+ MEM_FREE(io->Cmd);
+ io->Cmd = MEM_ALLOC(cmdSize);
+ if (io->Cmd == NULL) goto err;
+ }
+ io->CmdPos = 0;
+ io->CmdSize = cmdSize;
+ if (io->RespSize < respSize) {
+ MEM_FREE(io->Resp);
+ io->Resp = MEM_ALLOC(respSize);
+ if (io->Resp == NULL) goto err;
+ }
+ io->RespPos = 0;
+ io->RespSize = respSize;
+ if (io->Hash == NULL) {
+ UINTN sha1ctxsize;
+ sha1ctxsize = Sha1GetContextSize();
+ io->Hash = MEM_ALLOC(sha1ctxsize);
+ if (io->Hash == NULL) goto err;
+ }
+ if(!Sha1Init(io->Hash)) goto err;
+ *tpmio = io;
+ return EFI_SUCCESS;
+err:
+ MEM_FREE(io->Cmd);
+ MEM_FREE(io->Resp);
+ MEM_FREE(io->Hash);
+ MEM_FREE(io);
+ *tpmio = NULL;
+ return EFI_BUFFER_TOO_SMALL;
+}
+
+VOID
+Tpm12IOFree(
+ DCS_TPM12IO **tpmio)
+{
+ DCS_TPM12IO *io;
+ if (tpmio == NULL) return;
+ io = *tpmio;
+ if (io == NULL) return;
+ MEM_FREE(io->Cmd);
+ MEM_FREE(io->Resp);
+ MEM_FREE(io->Hash);
+ MEM_FREE(io);
+ *tpmio = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Cmd init and write
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12IOUpdateCmdSize(
+ DCS_TPM12IO *tpmio)
+{
+ UINT32 *data;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ data = (UINT32*)&tpmio->Cmd[2];
+ *data = SwapBytes32((UINT32)tpmio->CmdPos);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Tpm12IOWrite16(
+ DCS_TPM12IO *tpmio,
+ UINT16 prm,
+ BOOLEAN hashIt)
+{
+ UINT16 *data;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->CmdPos + 2 >= tpmio->CmdSize) {
+ tpmio->CmdPos = tpmio->CmdSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ data = (UINT16*)&tpmio->Cmd[tpmio->CmdPos];
+ *data = SwapBytes16(prm);
+ if(hashIt) {
+ Sha1Update(tpmio->Hash, data, 2);
+ }
+ tpmio->CmdPos += 2;
+ return Tpm12IOUpdateCmdSize(tpmio);
+}
+
+EFI_STATUS
+Tpm12IOWrite32(
+ DCS_TPM12IO *tpmio,
+ UINT32 prm,
+ BOOLEAN hashIt)
+{
+ UINT32 *data;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->CmdPos + 4 >= tpmio->CmdSize){
+ tpmio->CmdPos = tpmio->CmdSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ data = (UINT32*)&tpmio->Cmd[tpmio->CmdPos];
+ *data = SwapBytes32(prm);
+ if (hashIt) {
+ Sha1Update(tpmio->Hash, data, 4);
+ }
+ tpmio->CmdPos += 4;
+ return Tpm12IOUpdateCmdSize(tpmio);
+}
+
+EFI_STATUS
+Tpm12IOWriteBytes(
+ DCS_TPM12IO *tpmio,
+ VOID *prm,
+ UINTN prmSize,
+ BOOLEAN hashIt)
+{
+ UINT8 *data;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->CmdPos + prmSize >= tpmio->CmdSize) {
+ tpmio->CmdPos = tpmio->CmdSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ data = &tpmio->Cmd[tpmio->CmdPos];
+ CopyMem(data, prm, prmSize);
+ if (hashIt) {
+ Sha1Update(tpmio->Hash, data, prmSize);
+ }
+ tpmio->CmdPos += prmSize;
+ return Tpm12IOUpdateCmdSize(tpmio);
+}
+
+EFI_STATUS
+Tpm12IOWrite8(
+ DCS_TPM12IO *tpmio,
+ UINT8 prm,
+ BOOLEAN hashIt)
+{
+ return Tpm12IOWriteBytes(tpmio, &prm, 1, hashIt);
+}
+
+EFI_STATUS
+Tpm12IOInit(
+ DCS_TPM12IO *tpmio,
+ UINT16 tag,
+ UINT32 ord)
+{
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ tpmio->CmdPos = 0;
+ ZeroMem(tpmio->Cmd, tpmio->CmdSize);
+ tpmio->RespPos = 0;
+ ZeroMem(tpmio->Resp, tpmio->RespSize);
+ Sha1Init(tpmio->Hash);
+ Tpm12IOWrite16(tpmio, tag, FALSE);
+ Tpm12IOWrite32(tpmio, 0, FALSE);
+ return Tpm12IOWrite32(tpmio, ord, TRUE);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Read / Parse responces
+//////////////////////////////////////////////////////////////////////////
+UINT16
+Tpm12RespTag(
+ DCS_TPM12IO *tpmio)
+{
+ UINT16 *tag;
+ if (tpmio == NULL) return 0;
+ tag = (UINT16*)tpmio->Resp;
+ return SwapBytes16(*tag);
+}
+
+UINT32
+Tpm12RespCode(
+ IN DCS_TPM12IO *tpmio
+ )
+{
+ UINT32 *code;
+ if (tpmio == NULL) return 0;
+ code = (UINT32*)&tpmio->Resp[6];
+ return SwapBytes32(*code);
+}
+
+UINT32
+Tpm12RespSize(
+ IN DCS_TPM12IO *tpmio
+ )
+{
+ UINT32 *size;
+ if (tpmio == NULL) return 0;
+ size = (UINT32*)&tpmio->Resp[2];
+ return SwapBytes32(*size);
+}
+
+UINT8*
+Tpm12RespData(
+ IN DCS_TPM12IO *tpmio
+ )
+{
+ if (tpmio == NULL) return NULL;
+ return &tpmio->Resp[10];
+}
+
+EFI_STATUS
+Tpm12RespRead16(
+ IN DCS_TPM12IO *tpmio,
+ OUT UINT16 *data,
+ IN BOOLEAN hashIt
+ )
+{
+ UINT16 *tmp;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if(tpmio->RespPos + 2 > tpmio->RespSize) return EFI_BUFFER_TOO_SMALL;
+ tmp = (UINT16 *)&tpmio->Resp[tpmio->RespPos];
+ if (data != NULL) {
+ *data = SwapBytes16(*tmp);
+ }
+ if (hashIt) {
+ Sha1Update(tpmio->Hash, tmp, 2);
+ }
+ tpmio->RespPos += 2;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Tpm12RespRead32(
+ IN DCS_TPM12IO *tpmio,
+ OUT UINT32 *data,
+ IN BOOLEAN hashIt
+ )
+{
+ UINT32 *tmp;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->RespPos + 4 > tpmio->RespSize) return EFI_BUFFER_TOO_SMALL;
+ tmp = (UINT32 *)&tpmio->Resp[tpmio->RespPos];
+ if (data != NULL) {
+ *data = SwapBytes32(*tmp);
+ }
+ if (hashIt) {
+ Sha1Update(tpmio->Hash, tmp, 4);
+ }
+ tpmio->RespPos += 4;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Tpm12RespReadBytes(
+ IN DCS_TPM12IO *tpmio,
+ OUT VOID *data,
+ IN UINT32 dataSize,
+ IN BOOLEAN hashIt
+ )
+{
+ UINT8 *tmp;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->RespPos + dataSize > tpmio->RespSize) return EFI_BUFFER_TOO_SMALL;
+ tmp = &tpmio->Resp[tpmio->RespPos];
+ if (data != NULL) {
+ CopyMem(data, tmp, dataSize);
+ }
+ if (hashIt) {
+ Sha1Update(tpmio->Hash, tmp, dataSize);
+ }
+ tpmio->RespPos += dataSize;
+ return EFI_SUCCESS;
+}
+
+VOID
+Tpm12Parse16(UINT8** pos, UINT16 *data) {
+ if (data == NULL) {
+ data = (UINT16*)(*pos);
+ }
+ *data = SwapBytes16(*((UINT16*)(*pos)));
+ (*pos) += 2;
+}
+
+VOID
+Tpm12Parse32(UINT8** pos, UINT32 *data) {
+ if (data == NULL) {
+ data = (UINT32*)(*pos);
+ }
+ *data = SwapBytes32(*((UINT32*)(*pos)));
+ (*pos) += 4;
+}
+
+VOID
+Tpm12ParsePcrInfoShort(UINT8** pos, TPM_PCR_INFO_SHORT*data) {
+ if (data == NULL) {
+ data = (TPM_PCR_INFO_SHORT*)(*pos);
+ }
+ data->pcrSelection.sizeOfSelect = SwapBytes16(*((UINT16*)(*pos)));
+ (*pos) += data->pcrSelection.sizeOfSelect + 2 + 1 + 20;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Transmit command
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12Transmit(
+ DCS_TPM12IO *tpmio)
+{
+ UINT32 TpmRecvSize;
+ EFI_STATUS res;
+ if (tpmio == NULL) return EFI_INVALID_PARAMETER;
+ if (tpmio->CmdPos >= tpmio->CmdSize) return EFI_BUFFER_TOO_SMALL;
+ TpmRecvSize = (UINT32)tpmio->RespSize;
+ res = TPM_TRANSMIT((UINT32)tpmio->CmdPos, tpmio->Cmd, &TpmRecvSize, tpmio->Resp);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ if (Tpm12RespCode(tpmio) != TPM_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ Sha1Init(tpmio->Hash); // Init hash
+ tpmio->RespPos = 6; // Skip tag and size
+ Tpm12RespRead32(tpmio, NULL, TRUE); // Hash return code
+ Sha1Update(tpmio->Hash, tpmio->Cmd + 2, 4); // Hash ordinal
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Global TPM12 I/O
+//////////////////////////////////////////////////////////////////////////
+DCS_TPM12IO *gTpm12Io = NULL;
+EFI_STATUS
+GetTpm12Io()
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ if (gTpm12Io == NULL) {
+ res = Tpm12IOCreate(&gTpm12Io, 1024, 1024);
+ }
+ if (mTcgProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PCRs
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12Cmd_PcrRead(
+ DCS_TPM12IO *tpmio,
+ IN UINT32 PcrIndex
+ )
+{
+ Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_PcrRead);
+ return Tpm12IOWrite32(tpmio, PcrIndex, TRUE);
+}
+
+/**
+Send PCR Read command to TPM1.2.
+
+@param PcrIndex The index of the PCR to read.
+@param PcrValue The PCR value.
+
+@retval EFI_SUCCESS Operation completed successfully.
+@retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+Tpm12PcrRead(
+ IN UINT32 PcrIndex,
+ OUT void *PcrValue
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Cmd_PcrRead(gTpm12Io, PcrIndex);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ Tpm12RespReadBytes(gTpm12Io, PcrValue, sizeof(TPM_PCRVALUE), TRUE);
+ return res;
+}
+
+EFI_STATUS
+Tpm12Cmd_PcrExtend(
+ DCS_TPM12IO *tpmio,
+ IN UINT32 PcrIndex,
+ IN UINTN dataSz,
+ IN VOID *data
+ )
+{
+ TPM_DIGEST digest;
+ Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_Extend);
+ Sha1Hash(data, dataSz, (UINT8*)&digest);
+ Tpm12IOWrite32(tpmio, PcrIndex, TRUE);
+ return Tpm12IOWriteBytes(tpmio, &digest, sizeof(digest), TRUE);
+}
+
+/**
+Send PCR Extend command to TPM1.2.
+
+@param PcrIndex The index of the PCR to read.
+@param dataSz size of data
+@param data data. Extend PCR with Sha1(data)
+
+@retval EFI_SUCCESS Operation completed successfully.
+@retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+Tpm12PcrExtend(
+ IN UINT32 PcrIndex,
+ IN UINTN dataSz,
+ IN VOID *data
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Cmd_PcrExtend(gTpm12Io, PcrIndex, dataSz, data);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return res;
+}
+
+EFI_STATUS
+Tpm12PcrExtendAndLog(
+ IN UINT32 PcrIndex,
+ IN UINTN dataSz,
+ IN VOID *data
+ )
+{
+ EFI_STATUS res = EFI_NOT_FOUND;
+
+ /*TCG_PCR_EVENT_HDR TcgEvent;
+ TcgEvent->PCRIndex = PcrIndex;
+ TcgEvent->EventType = EventType;
+ TcgEvent->EventSize = LogLen;
+ CopyMem(&TcgEvent->Event[0], EventLog, LogLen);
+ EventNumber = 1;
+ Status = TcgProtocol->HashLogExtendEvent(
+ TcgProtocol,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
+ HashDataLen,
+ TPM_ALG_SHA,
+ TcgEvent,
+ &EventNumber,
+ &EventLogLastEntry
+ );
+// TcgEvent.PCRIndex = PcrIndex;
+// TcgEvent.EventType = EV_EFI_VARIABLE_DRIVER_CONFIG;
+// res = TpmMeasureAndLogData(PcrIndex, EV_EFI_VARIABLE_DRIVER_CONFIG, &TcgEvent, sizeof(TcgEvent), data, dataSz);
+*/
+
+ return res;
+}
+
+EFI_STATUS
+Tpm12PcrsSave(
+ IN UINTN sPcr,
+ IN UINTN ePcr,
+ TPM_DIGEST *Pcrs
+ ) {
+ UINT32 i;
+ EFI_STATUS Status = EFI_SUCCESS;
+ for (i = (UINT32)sPcr; i <= (UINT32)ePcr; ++i) {
+ Status = Tpm12PcrRead(i, &Pcrs[i].digest);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ return Status;
+}
+
+EFI_STATUS
+Tpm12PrintPCR(
+ IN UINT32 PcrIndex)
+{
+ TPM_PCRVALUE PcrValue;
+ EFI_STATUS Status;
+ OUT_PRINT(L"%HPCR%02d%N ", PcrIndex);
+ Status = Tpm12PcrRead(PcrIndex, &PcrValue);
+ if (EFI_ERROR(Status)) {
+ ERR_PRINT(L"%r(%x)\n", Status, Tpm12RespCode(gTpm12Io));
+ return Status;
+ }
+ PrintBytes(PcrValue.digest, sizeof(PcrValue));
+ OUT_PRINT(L"\n");
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Tpm12DumpPcrs(
+ IN UINT32 sPcr,
+ IN UINT32 ePcr)
+{
+ UINT32 i;
+ EFI_STATUS Status = EFI_SUCCESS;
+ for (i = sPcr; i <= ePcr; ++i) {
+ Status = Tpm12PrintPCR(i);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ return Status;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Get Capability
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12Cmd_GetCapability(
+ DCS_TPM12IO *tpmio,
+ IN UINT32 capArea,
+ IN UINT32 subCapSize,
+ IN UINT8 *subCap
+ )
+{
+ EFI_STATUS res;
+ Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_GetCapability);
+ Tpm12IOWrite32(tpmio, capArea, TRUE);
+ res = Tpm12IOWrite32(tpmio, subCapSize, TRUE);
+ if (subCapSize > 0) {
+ res = Tpm12IOWriteBytes(tpmio, subCap, subCapSize, TRUE);
+ }
+ return res;
+}
+
+/**
+Send GetCapability command to TPM1.2.
+
+@param capArea The index of the Capability
+@param subCapSize The size of details.
+@param subCap Details
+
+@retval EFI_SUCCESS Operation completed successfully.
+@retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12GetCapability(
+ IN UINT32 capArea,
+ IN UINT32 subCapSize,
+ IN UINT8 *subCap,
+ OUT UINT32 *respSize,
+ OUT UINT8 *resp
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Cmd_GetCapability(gTpm12Io, capArea, subCapSize, subCap);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = Tpm12RespRead32(gTpm12Io, respSize, TRUE);
+ if (!EFI_ERROR(res)) {
+ res = Tpm12RespReadBytes(gTpm12Io, resp, *respSize, TRUE);
+ }
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// NV
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12GetNvList(
+ OUT UINT32 *respSize,
+ OUT UINT32 *resp
+ ) {
+ return Tpm12GetCapability(TPM_CAP_NV_LIST, 0, NULL, respSize, (UINT8*)resp);
+}
+
+EFI_STATUS
+Tpm12PcrsDigest(
+ IN UINT16 sizeOfSelect,
+ IN UINT8 *pcrSelect,
+ IN TPM_DIGEST *Pcrs,
+ OUT TPM_DIGEST *digest
+ )
+{
+ UINTN Sha1CtxSize;
+ UINTN i;
+ UINTN j;
+ UINTN k;
+ VOID* Sha1Ctx;
+ UINT16 tmp16;
+ UINT32 tmp32;
+
+ k = 0;
+ for (i = 0; i < sizeOfSelect; ++i) {
+ UINT8 tmp = pcrSelect[i];
+ for (j = 0; j < 8; ++j) {
+ if ((tmp & 1) == 1) {
+ k++;
+ }
+ tmp >>= 1;
+ }
+ }
+ if (k == 0) return EFI_SUCCESS;
+ Sha1CtxSize = Sha1GetContextSize();
+ Sha1Ctx = MEM_ALLOC(Sha1CtxSize);
+ if (Sha1Ctx == NULL) return EFI_BUFFER_TOO_SMALL;
+ Sha1Init(Sha1Ctx);
+ tmp16 = SwapBytes16(sizeOfSelect);
+ Sha1Update(Sha1Ctx, &tmp16, sizeof(tmp16));
+ Sha1Update(Sha1Ctx, pcrSelect, sizeOfSelect);
+
+ tmp32 = SwapBytes32((UINT32)(k * sizeof(TPM_DIGEST)));
+ Sha1Update(Sha1Ctx, &tmp32, sizeof(tmp32));
+ k = 0;
+ for (i = 0; i < sizeOfSelect; ++i) {
+ UINT8 tmp = pcrSelect[i];
+ for (j = 0; j < 8; ++j) {
+ if ((tmp & 1) == 1) {
+ Sha1Update(Sha1Ctx, &Pcrs[k], sizeof(TPM_DIGEST));
+ }
+ tmp >>= 1;
+ k++;
+ }
+ }
+ if (Sha1Final(Sha1Ctx, digest->digest)) return EFI_SUCCESS;
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+Tpm12NvDetails(
+ IN UINT32 index,
+ OUT UINT32 *attr,
+ OUT UINT32 *dataSz,
+ OUT UINT32 *pcrR,
+ OUT UINT32 *pcrW
+ )
+{
+ EFI_STATUS res;
+ TPM_PCR_INFO_SHORT* pcrRead;
+ TPM_PCR_INFO_SHORT* pcrWrite;
+ UINT8 nvdata[sizeof(TPM_NV_DATA_PUBLIC) + 256];
+ UINT8* pos = nvdata;
+ UINT32 sz = sizeof(nvdata);
+ UINT32 swapindex = SwapBytes32(index);
+ res = Tpm12GetCapability(TPM_CAP_NV_INDEX, 4, (UINT8*)&swapindex, &sz, nvdata);
+ if(EFI_ERROR(res)) return res;
+ Tpm12Parse16(&pos, NULL);
+ Tpm12Parse32(&pos, &index);
+ pcrRead = (TPM_PCR_INFO_SHORT*)pos;
+ Tpm12ParsePcrInfoShort(&pos, NULL);
+ pcrWrite = (TPM_PCR_INFO_SHORT*)pos;
+ Tpm12ParsePcrInfoShort(&pos, NULL);
+ Tpm12Parse16(&pos, NULL);
+ Tpm12Parse32(&pos, attr);
+ pos += 3;
+ Tpm12Parse32(&pos, dataSz);
+ if (pcrR != NULL) {
+ *pcrR = pcrRead->pcrSelection.pcrSelect[0];
+ *pcrR |= pcrRead->pcrSelection.sizeOfSelect > 1 ? pcrRead->pcrSelection.pcrSelect[1] << 8 : 0;
+ *pcrR |= pcrRead->pcrSelection.sizeOfSelect > 2 ? pcrRead->pcrSelection.pcrSelect[2] << 16 : 0;
+ *pcrR |= pcrRead->pcrSelection.sizeOfSelect > 3 ? pcrRead->pcrSelection.pcrSelect[3] << 24 : 0;
+ }
+ if (pcrW != NULL) {
+ *pcrW = pcrWrite->pcrSelection.pcrSelect[0];
+ *pcrW |= pcrWrite->pcrSelection.sizeOfSelect > 1 ? pcrWrite->pcrSelection.pcrSelect[1] << 8 : 0;
+ *pcrW |= pcrWrite->pcrSelection.sizeOfSelect > 2 ? pcrWrite->pcrSelection.pcrSelect[2] << 16 : 0;
+ *pcrW |= pcrWrite->pcrSelection.sizeOfSelect > 3 ? pcrWrite->pcrSelection.pcrSelect[3] << 24 : 0;
+ }
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// OSAP
+//////////////////////////////////////////////////////////////////////////
+#pragma pack(1)
+typedef struct {
+ TPM_NONCE nonceOdd;
+ TPM_NONCE nonceOddOSAP;
+ TPM_NONCE nonceEven;
+ TPM_NONCE nonceEvenOSAP;
+ TPM_DIGEST SharedSecret;
+ TPM_AUTHHANDLE authHandle;
+} TPM12_OSAP;
+#pragma pack()
+
+EFI_STATUS
+Tpm12Cmd_OSAP(
+ IN DCS_TPM12IO *tpmio,
+ IN TPM12_OSAP *osap,
+ IN UINT16 entityType,
+ IN UINT32 entityValue
+ )
+{
+ EFI_STATUS res;
+ Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
+ res = Tpm12IOWrite16(tpmio, entityType, TRUE);
+ res = Tpm12IOWrite32(tpmio, entityValue, TRUE);
+ res = Tpm12IOWriteBytes(tpmio, &osap->nonceOddOSAP, sizeof(osap->nonceOddOSAP), TRUE);
+ return res;
+}
+
+TPM12_OSAP *gTpm12Osap;
+
+EFI_STATUS
+Tpm12OSAPStart(
+ IN UINT16 entityType,
+ IN UINT32 entityValue,
+ IN CHAR16 *ownerPass
+ )
+{
+ EFI_STATUS res;
+ TPM_DIGEST ownerKey;
+ UINTN CtxSize;
+ VOID* HmacCtx;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ if (gTpm12Osap == NULL) {
+ gTpm12Osap = MEM_ALLOC(sizeof(TPM12_OSAP));
+ }
+ res = Tpm12Cmd_OSAP(gTpm12Io, gTpm12Osap, entityType, entityValue);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ Tpm12RespRead32(gTpm12Io, &gTpm12Osap->authHandle, FALSE);
+ Tpm12RespReadBytes(gTpm12Io, &gTpm12Osap->nonceEven, sizeof(TPM_NONCE), FALSE);
+ res = Tpm12RespReadBytes(gTpm12Io, &gTpm12Osap->nonceEvenOSAP, sizeof(TPM_NONCE), FALSE);
+ if (EFI_ERROR(res)) return res;
+ Sha1Hash(ownerPass, StrLen(ownerPass) * 2, (UINT8*)&ownerKey);
+ CtxSize = HmacSha1GetContextSize();
+ HmacCtx = MEM_ALLOC(CtxSize);
+ HmacSha1Init(HmacCtx, (UINT8*)&ownerKey, sizeof(ownerKey));
+ HmacSha1Update(HmacCtx, &gTpm12Osap->nonceEvenOSAP, sizeof(gTpm12Osap->nonceEvenOSAP));
+ HmacSha1Update(HmacCtx, &gTpm12Osap->nonceOddOSAP, sizeof(gTpm12Osap->nonceOddOSAP));
+ HmacSha1Final(HmacCtx, (UINT8*)&gTpm12Osap->SharedSecret);
+ MEM_FREE(HmacCtx);
+ return res;
+}
+
+EFI_STATUS
+Tpm12OSAPAppend(
+ IN UINT8 continueSession
+ )
+{
+ EFI_STATUS res;
+ UINTN CtxSize;
+ VOID* HmacCtx;
+ TPM_DIGEST hashCmd;
+ TPM_DIGEST auth;
+
+ Tpm12IOWrite32(gTpm12Io, gTpm12Osap->authHandle, FALSE);
+ Tpm12IOWriteBytes(gTpm12Io, &gTpm12Osap->nonceOdd, sizeof(gTpm12Osap->nonceOdd), FALSE);
+ res = Tpm12IOWrite8(gTpm12Io, continueSession, FALSE);
+ *((UINT16*)gTpm12Io->Cmd) = SwapBytes16(TPM_TAG_RQU_AUTH1_COMMAND); // Update Tag
+ Sha1Final(gTpm12Io->Hash, (UINT8*)&hashCmd);
+ CtxSize = HmacSha1GetContextSize();
+ HmacCtx = MEM_ALLOC(CtxSize);
+ if (HmacCtx == NULL) return EFI_BUFFER_TOO_SMALL;
+ HmacSha1Init(HmacCtx, (UINT8*)&gTpm12Osap->SharedSecret, sizeof(gTpm12Osap->SharedSecret));
+ HmacSha1Update(HmacCtx, &hashCmd, sizeof(hashCmd));
+ HmacSha1Update(HmacCtx, &gTpm12Osap->nonceEven, sizeof(gTpm12Osap->nonceEven));
+ HmacSha1Update(HmacCtx, &gTpm12Osap->nonceOdd, sizeof(gTpm12Osap->nonceOdd));
+ HmacSha1Update(HmacCtx, &continueSession, sizeof(continueSession));
+ HmacSha1Final(HmacCtx, (UINT8*)&auth);
+ MEM_FREE(HmacCtx);
+ res = Tpm12IOWriteBytes(gTpm12Io, &auth, sizeof(auth), FALSE);
+ return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// NV
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12WritePcrInfo(
+ IN DCS_TPM12IO *tpmio,
+ IN UINT16 sizeOfSelect,
+ IN UINT8 *pcrSelect,
+ IN UINT8 localityAtRelease,
+ IN TPM_DIGEST* pcrs)
+{
+ TPM_DIGEST digestAtRelease;
+ ZeroMem(&digestAtRelease, sizeof(digestAtRelease));
+ Tpm12IOWrite16 (tpmio, sizeOfSelect, TRUE);
+ Tpm12IOWriteBytes(tpmio, pcrSelect, sizeOfSelect, TRUE);
+ Tpm12IOWrite8(tpmio, localityAtRelease, TRUE);
+ Tpm12PcrsDigest(sizeOfSelect, pcrSelect, pcrs, &digestAtRelease);
+ return Tpm12IOWriteBytes(tpmio, &digestAtRelease, sizeof(TPM_DIGEST), TRUE);
+}
+
+TPM_DIGEST gTpm12Pcrs[24];
+TPM_DIGEST gTpm12OwnerPass;
+
+VOID
+PcrUpdateMask(
+ UINT32 mask,
+ UINT8 *pcr)
+{
+ pcr[0] = (UINT8)(mask & 0xFF);
+ pcr[1] = (UINT8)((mask >> 8) & 0xFF);
+ pcr[2] = (UINT8)((mask >> 16) & 0xFF);
+}
+
+EFI_STATUS
+Tpm12NvSpace(
+ IN UINT32 index,
+ IN UINT32 size,
+ IN CHAR16 *ownerPass,
+ TPM_DIGEST *pcrs,
+ IN UINT32 pcrReadMask,
+ IN UINT32 pcrWriteMask,
+ IN UINT32 Attributes,
+ IN UINT8 bReadSTClear,
+ IN UINT8 bWriteSTClear,
+ IN UINT8 bWriteDefine
+ ) {
+ EFI_STATUS res;
+ TPM_DIGEST encAuth;
+ UINT8 pcrRead[3];
+ UINT8 pcrWrite[3];
+
+ PcrUpdateMask(pcrReadMask, pcrRead);
+ PcrUpdateMask(pcrWriteMask, pcrWrite);
+ SetMem(&encAuth, sizeof(encAuth), 0xEA); // No Auth
+
+ res = Tpm12OSAPStart(TPM_ET_OWNER, TPM_KH_OWNER, ownerPass);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ Tpm12IOInit(gTpm12Io, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_NV_DefineSpace);
+ // NV_DATA_PUBLIC
+ Tpm12IOWrite16(gTpm12Io, TPM_TAG_NV_DATA_PUBLIC, TRUE);
+ Tpm12IOWrite32(gTpm12Io, index, TRUE);
+ Tpm12WritePcrInfo(gTpm12Io, sizeof(pcrRead) , pcrRead, 0x1F, pcrs);
+ Tpm12WritePcrInfo(gTpm12Io, sizeof(pcrWrite), pcrWrite, 0x1F, pcrs);
+ Tpm12IOWrite16(gTpm12Io, TPM_TAG_NV_ATTRIBUTES, TRUE);
+ Tpm12IOWrite32(gTpm12Io, Attributes, TRUE);
+ Tpm12IOWrite8(gTpm12Io, bReadSTClear, TRUE);
+ Tpm12IOWrite8(gTpm12Io, bWriteSTClear, TRUE);
+ Tpm12IOWrite8(gTpm12Io, bWriteDefine, TRUE);
+ Tpm12IOWrite32(gTpm12Io, size, TRUE);
+ //
+ Tpm12IOWriteBytes(gTpm12Io, &encAuth, sizeof(encAuth), TRUE);
+ // OSAP
+ Tpm12OSAPAppend(0);
+
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return res;
+}
+
+EFI_STATUS
+Tpm12Cmd_NvRead(
+ IN DCS_TPM12IO *tpmio,
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN UINT32 DataSize
+ )
+{
+ EFI_STATUS res;
+ CE(Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_NV_ReadValue));
+ CE(Tpm12IOWrite32(tpmio, NvIndex, TRUE));
+ CE(Tpm12IOWrite32(tpmio, Offset, TRUE));
+ CE(Tpm12IOWrite32(tpmio, DataSize, TRUE));
+err:
+ return res;
+}
+
+/**
+Send NV ReadValue command to TPM1.2.
+
+@param NvIndex The index of the area to set.
+@param Offset The offset into the area.
+@param DataSize The size of the data area.
+@param Data The data to set the area to.
+
+@retval EFI_SUCCESS Operation completed successfully.
+@retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+Tpm12NvRead(
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN OUT UINT32 *DataSize,
+ OUT UINT8 *Data
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Cmd_NvRead(gTpm12Io, NvIndex,Offset,*DataSize);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = Tpm12RespRead32(gTpm12Io, DataSize, TRUE);
+ if (!EFI_ERROR(res)) {
+ res = Tpm12RespReadBytes(gTpm12Io, Data, *DataSize, TRUE);
+ }
+ return res;
+}
+
+EFI_STATUS
+Tpm12Cmd_NvWrite(
+ IN DCS_TPM12IO *tpmio,
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN UINT32 DataSize,
+ IN UINT8 *Data
+ )
+{
+ EFI_STATUS res;
+ CE(Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_NV_WriteValue));
+ CE(Tpm12IOWrite32(tpmio, NvIndex, TRUE));
+ CE(Tpm12IOWrite32(tpmio, Offset, TRUE));
+ CE(Tpm12IOWrite32(tpmio, DataSize, TRUE));
+ CE(Tpm12IOWriteBytes(tpmio, Data, DataSize, TRUE));
+err:
+ return res;
+}
+
+/**
+Send NV WriteValue command to TPM1.2.
+
+@param NvIndex The index of the area to set.
+@param Offset The offset into the NV Area.
+@param DataSize The size of the data parameter.
+@param Data The data to set the area to.
+
+@retval EFI_SUCCESS Operation completed successfully.
+@retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12NvWrite(
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN UINT32 DataSize,
+ IN UINT8 *Data,
+ CHAR16 *ownerPass
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12OSAPStart(TPM_ET_OWNER, TPM_KH_OWNER, ownerPass);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = Tpm12Cmd_NvWrite(gTpm12Io, NvIndex, Offset, DataSize, Data);
+ if (EFI_ERROR(res)) return res;
+ // OSAP
+ Tpm12OSAPAppend(0);
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return res;
+}
+
+/*
+EFI_STATUS
+Tpm12NvDefine(
+ IN UINT32 index,
+ IN UINT32 size,
+ IN CHAR16 *ownerPass) {
+ EFI_STATUS res;
+// UINT32 sz = 20;
+// UINT8 data[20];
+// UINT8 dataR[20];
+// SetMem(data, 20, 1);
+//
+// CE(Tpm12PcrsSave(0, 23, gTpm12Pcrs));
+// CE(Tpm12NvSpace(index, size, ownerPass, gTpm12Pcrs, 0x100, 0, 0x2, 0, 0, 0));
+// CE(Tpm12NvWrite(index,0,size, data, ownerPass));
+// CE(Tpm12NvRead(index, 0, &sz, dataR));
+ CE(GetTpm());
+ if (gRnd == NULL) {
+ RndInit()
+ }
+ return res;
+err:
+ ERR_PRINT(L"%r(%x),line %d\n", res, Tpm12RespCode(gTpm12Io), gCELine);
+ return res;
+}*/
+
+//////////////////////////////////////////////////////////////////////////
+// Random
+//////////////////////////////////////////////////////////////////////////
+EFI_STATUS
+Tpm12Cmd_GetRandom(
+ IN DCS_TPM12IO *tpmio,
+ IN UINT32 DataSize
+ )
+{
+ EFI_STATUS res;
+ CE(Tpm12IOInit(tpmio, TPM_TAG_RQU_COMMAND, TPM_ORD_GetRandom));
+ CE(Tpm12IOWrite32(tpmio, DataSize, TRUE));
+err:
+ return res;
+}
+
+EFI_STATUS
+Tpm12GetRandom(
+ IN OUT UINT32 *DataSize,
+ OUT UINT8 *Data
+ )
+{
+ EFI_STATUS res;
+ res = GetTpm12Io();
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Cmd_GetRandom(gTpm12Io, *DataSize);
+ if (EFI_ERROR(res)) return res;
+ res = Tpm12Transmit(gTpm12Io);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = Tpm12RespRead32(gTpm12Io, DataSize, TRUE);
+ if (!EFI_ERROR(res)) {
+ res = Tpm12RespReadBytes(gTpm12Io, Data, *DataSize, TRUE);
+ }
+ return res;
+}
+//////////////////////////////////////////////////////////////////////////
+// Protocol
+//////////////////////////////////////////////////////////////////////////
+#define DCS_TPM_NV_INDEX 0x0DC5B
+#define DCS_TPM_NV_SIZE 128
+#define DCS_TPM_PCR_LOCK 8
+
+typedef struct _Password Password;
+
+extern VOID
+ApplyKeyFile(
+ IN OUT Password* password,
+ IN CHAR8* keyfileData,
+ IN UINTN keyfileDataSize
+ );
+
+EFI_STATUS
+DcsTpm12Lock(
+ DCS_TPM_PROTOCOL *tpm
+ )
+{
+ UINT32 lock = 1;
+ return Tpm12PcrExtend(DCS_TPM_PCR_LOCK, sizeof(lock), &lock);
+}
+
+EFI_STATUS
+DcsTpm12Apply(
+ DCS_TPM_PROTOCOL *tpm,
+ OUT VOID* pwd
+ )
+{
+ EFI_STATUS res;
+ UINT32 sz = DCS_TPM_NV_SIZE;
+ CHAR8 data[DCS_TPM_NV_SIZE];
+ res = Tpm12NvRead(DCS_TPM_NV_INDEX, 0, &sz, data);
+ if (EFI_ERROR(res)) return res;
+ ApplyKeyFile(pwd, data, DCS_TPM_NV_SIZE);
+ ZeroMem(data, DCS_TPM_NV_SIZE);
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+DcsTpm12IsOpen(
+ DCS_TPM_PROTOCOL *tpm
+ )
+{
+ EFI_STATUS res;
+ UINT32 sz = DCS_TPM_NV_SIZE;
+ UINT8 data[DCS_TPM_NV_SIZE];
+ res = Tpm12NvRead(DCS_TPM_NV_INDEX, 0, &sz, data);
+ if (EFI_ERROR(res)) return FALSE;
+ ZeroMem(data, DCS_TPM_NV_SIZE);
+ return TRUE;
+}
+
+BOOLEAN
+DcsTpm12IsConfigured(
+ DCS_TPM_PROTOCOL *tpm
+ )
+{
+ EFI_STATUS res;
+ UINT32 dataSz;
+ UINT32 attr;
+ UINT32 pcrR;
+ UINT32 pcrW;
+ res = Tpm12NvDetails(DCS_TPM_NV_INDEX, &attr, &dataSz, &pcrR, &pcrW);
+ if (EFI_ERROR(res)) return FALSE;
+ if (dataSz != DCS_TPM_NV_SIZE) return FALSE;
+ return TRUE;
+}
+
+#define TPM_OWNER_PWD_MAX 64
+VOID
+AskTpmOwnerPwd(
+ OUT CHAR16* ownerPass
+ ) {
+ UINTN ownerPassLen;
+ OUT_PRINT(L"TPM owner password:");
+ ZeroMem(ownerPass, TPM_OWNER_PWD_MAX * 2);
+ GetLine(&ownerPassLen, ownerPass, NULL, TPM_OWNER_PWD_MAX - 1, FALSE);
+}
+
+UINT32
+AskPcrsMask(
+ IN UINT32 def
+ )
+{
+ OUT_PRINT(L"PCR selection bits(hex):\n\
+ 1 BIOS 2 BIOS data 4 EFI drivers\n\
+ 8 EFI variables 10 EFI boot loader 20 EFI boot loader data\n\
+40 Boot event 80 Manufacture 100 DcsProp\n");
+ return (UINT32)AskHexUINT64("PCRs mask:", def);
+}
+
+EFI_STATUS
+ActionTpm12Update(
+ IN VOID *ctx
+ )
+{
+ EFI_STATUS res;
+ CHAR16 ownerPass[TPM_OWNER_PWD_MAX];
+ UINT32 pcrMask;
+ UINT8 data[DCS_TPM_NV_SIZE];
+ ZeroMem(data, DCS_TPM_NV_SIZE);
+ CE(Tpm12PcrsSave(0, 23, gTpm12Pcrs));
+ AskTpmOwnerPwd(ownerPass);
+ pcrMask = AskPcrsMask(0x137);
+ CE(Tpm12NvSpace(DCS_TPM_NV_INDEX, DCS_TPM_NV_SIZE, ownerPass, gTpm12Pcrs, pcrMask, 0, 0x2, 0, 0, 0));
+ CE(gRnd == NULL ? EFI_NOT_READY : EFI_SUCCESS);
+ CE(gRnd->GetBytes(gRnd, data, sizeof(data)));
+ CE(Tpm12NvWrite(DCS_TPM_NV_INDEX, 0, DCS_TPM_NV_SIZE, data, ownerPass));
+err:
+ return res;
+}
+
+EFI_STATUS
+ActionTpm12Clean(
+ IN VOID *ctx
+ )
+{
+ EFI_STATUS res;
+ CHAR16 ownerPass[TPM_OWNER_PWD_MAX];
+ AskTpmOwnerPwd(ownerPass);
+ CE(Tpm12NvSpace(DCS_TPM_NV_INDEX, 0, ownerPass, gTpm12Pcrs, 0, 0, 0x2, 0, 0, 0));
+err:
+ return res;
+}
+
+EFI_STATUS
+ActionTpm12PrintPcrs(
+ IN VOID *ctx
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN i;
+ UINT32 pcrMask = 0x1FF;
+ UINT32 tmp;
+ Tpm12NvDetails(DCS_TPM_NV_INDEX, NULL, NULL, &pcrMask, NULL);
+ pcrMask = AskPcrsMask(pcrMask);
+ tmp = pcrMask;
+ for (i = 0; i < 32; ++i) {
+ if ((tmp & 1) == 1) {
+ Tpm12PrintPCR((UINT32)i);
+ }
+ tmp >>= 1;
+ }
+ return res;
+}
+
+PMENU_ITEM gTpmMenu = NULL;
+BOOLEAN gTpmMenuContinue = TRUE;
+
+EFI_STATUS
+ActionTpmExit(
+ IN VOID *ctx
+ )
+{
+ gTpmMenuContinue = FALSE;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+DcsTpm12Configure(
+ IN DCS_TPM_PROTOCOL* tpm
+ ) {
+ PMENU_ITEM item = NULL;
+ EFI_STATUS res;
+ item = DcsMenuAppend(item, L"Update TPM secret", 'u', ActionTpm12Update, NULL);
+ gTpmMenu = item;
+ item = DcsMenuAppend(item, L"Delete TPM secret", 'd', ActionTpm12Clean, NULL);
+ item = DcsMenuAppend(item, L"Print PCRs", 'p', ActionTpm12PrintPcrs, NULL);
+ item = DcsMenuAppend(item, L"Exit", 'e', ActionTpmExit, NULL);
+ do {
+ EFI_INPUT_KEY key;
+ OUT_PRINT(L"TPM ");
+ if (tpm->IsConfigured(tpm)) {
+ OUT_PRINT(L"%Vconfigured%N, ");
+ if (tpm->IsOpen(tpm)) {
+ OUT_PRINT(L"%Vopen%N");
+ }
+ else {
+ ERR_PRINT(L"locked");
+ }
+ }
+ else {
+ ERR_PRINT(L"not configured");
+ }
+ OUT_PRINT(L"\n");
+ DcsMenuPrint(gTpmMenu);
+ item = NULL;
+ key.UnicodeChar = 0;
+ while (item == NULL) {
+ item = gTpmMenu;
+ key = GetKey();
+ while (item != NULL) {
+ if (item->Select == key.UnicodeChar) break;
+ item = item->Next;
+ }
+ }
+ OUT_PRINT(L"%c\n", key.UnicodeChar);
+ res = item->Action(item->Context);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r(%x),line %d\n", res, Tpm12RespCode(gTpm12Io), gCELine);
+ }
+ } while (gTpmMenuContinue);
+ return EFI_SUCCESS;
+}
+
+DCS_TPM_PROTOCOL* gTpm = (DCS_TPM_PROTOCOL*)NULL;
+
+EFI_STATUS
+GetTpm() {
+ EFI_STATUS res;
+ res = InitTpm12();
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ gTpm = (DCS_TPM_PROTOCOL*)MEM_ALLOC(sizeof(DCS_TPM_PROTOCOL));
+ if (gTpm == NULL) return EFI_BUFFER_TOO_SMALL;
+ gTpm->IsConfigured = DcsTpm12IsConfigured;
+ gTpm->IsOpen = DcsTpm12IsOpen;
+ gTpm->Configure = DcsTpm12Configure;
+ gTpm->Apply = DcsTpm12Apply;
+ gTpm->Lock = DcsTpm12Lock;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+TpmMeasure(
+ IN VOID* data,
+ IN UINTN dataSz
+ ) {
+ EFI_STATUS res;
+ TPM_DIGEST hash;
+ CE(Sha1Hash(data, dataSz, (UINT8*)&hash));
+ CE(Tpm12PcrExtend(DCS_TPM_PCR_LOCK, sizeof(hash), &hash));
+
+err:
+ return res;
+}
diff --git a/Library/VeraCryptLib/DcsVeraCrypt.c b/Library/VeraCryptLib/DcsVeraCrypt.c
index 1b6cd35..02128df 100644
--- a/Library/VeraCryptLib/DcsVeraCrypt.c
+++ b/Library/VeraCryptLib/DcsVeraCrypt.c
@@ -26,24 +26,25 @@ https://opensource.org/licenses/Apache-2.0
#include "common/Xml.h"
#include "common/Crc.h"
#include "BootCommon.h"
+#include "Library/DcsTpmLib.h"
//////////////////////////////////////////////////////////////////////////
// Config
//////////////////////////////////////////////////////////////////////////
-char *ConfigBuffer = NULL;
-UINTN ConfigBufferSize = 0;
+char *gConfigBuffer = NULL;
+UINTN gConfigBufferSize = 0;
BOOL ConfigRead(char *configKey, char *configValue, int maxValueSize)
{
char *xml;
- if (ConfigBuffer == NULL) {
- if (FileLoad(NULL, L"\\EFI\\VeraCrypt\\DcsProp", &ConfigBuffer, &ConfigBufferSize) != EFI_SUCCESS) {
- return FALSE;
- }
- }
+ if (gConfigBuffer == NULL) {
+ if (FileLoad(NULL, L"\\EFI\\VeraCrypt\\DcsProp", &gConfigBuffer, &gConfigBufferSize) != EFI_SUCCESS) {
+ return FALSE;
+ }
+ }
- xml = ConfigBuffer;
+ xml = gConfigBuffer;
if (xml != NULL)
{
xml = XmlFindElementByAttributeValue(xml, "config", "key", configKey);
@@ -246,48 +247,145 @@ VCAuthLoadConfig()
}
+//////////////////////////////////////////////////////////////////////////
+// Configuration menu
+//////////////////////////////////////////////////////////////////////////
+PMENU_ITEM gCfgMenu = NULL;
+BOOLEAN gCfgMenuContinue = TRUE;
+
+EFI_STATUS
+ActionCfgReboot(IN VOID *ctx) {
+ gST->RuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+ActionCfgTpm(IN VOID *ctx) {
+ return gTpm->Configure(gTpm);
+}
+
+EFI_STATUS
+ActionBoot(IN VOID *ctx) {
+ gCfgMenuContinue = FALSE;
+ gAuthPwdCode = AskPwdRetCancel;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ActionNewPassword(IN VOID *ctx) {
+ gCfgMenuContinue = FALSE;
+ gAuthPwdCode = AskPwdRetLogin;
+ return EFI_SUCCESS;
+}
+
+VOID
+CfgMenuCreate() {
+ PMENU_ITEM item = NULL;
+ item = DcsMenuAppend(item, L"Boot", 'b', ActionBoot, NULL);
+ gCfgMenu = item;
+ item = DcsMenuAppend(item, L"Hard reset", 'r', ActionCfgReboot, NULL);
+ item = DcsMenuAppend(item, L"New password", 'n', ActionNewPassword, NULL);
+ if (gTpm != NULL) {
+ item = DcsMenuAppend(item, L"Configure TPM", 't', ActionCfgTpm, NULL);
+ }
+}
+
VOID
VCAskPwd(
IN UINTN pwdType,
OUT Password* vcPwd) {
+ BOOL pwdReady;
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;
+ do {
+ pwdReady = TRUE;
+ if (pwdType == AskPwdNew) {
+ EFI_INPUT_KEY key;
+ key = KeyWait(L"Press 'c' to configure, others to skip %1d\r", 9, 0, 0);
+ if (key.UnicodeChar == 'c') {
+ PMENU_ITEM item = NULL;
+ EFI_STATUS res;
+ OUT_PRINT(L"\n%V%a %a configuration%N\n", TC_APP_NAME, VERSION_STRING);
+ if (gCfgMenu == NULL) CfgMenuCreate();
+ do {
+ DcsMenuPrint(gCfgMenu);
+ item = NULL;
+ key.UnicodeChar = 0;
+ while (item == NULL) {
+ item = gCfgMenu;
+ key = GetKey();
+ while (item != NULL) {
+ if (item->Select == key.UnicodeChar) break;
+ item = item->Next;
+ }
+ }
+ OUT_PRINT(L"%c\n", key.UnicodeChar);
+ res = item->Action(item->Context);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"%r\n", res);
+ }
+ } while (gCfgMenuContinue);
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return;
+ }
+ }
}
- AskConsolePwdInt(&vcPwd->Length, vcPwd->Text, &gAuthPwdCode, sizeof(vcPwd->Text), gPasswordVisible);
- }
- if (gAuthPwdCode == AskPwdRetCancel) {
- return;
- }
+ 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 (gPlatformLocked) {
- if (gPlatformKeyFile == NULL) {
- ERR_PRINT(L"Platform key file absent\n");
- } else {
- ApplyKeyFile(vcPwd, gPlatformKeyFile, gPlatformKeyFileSize);
+ if (gAuthPwdCode == AskPwdRetCancel) {
+ return;
}
- }
- if (gTPMLocked) {
- // TO DO
- ERR_PRINT(L"TPM lock is not implemented\n");
- }
+ if (gSCLocked) {
+ ERR_PRINT(L"Smart card is not configured\n");
+ }
+
+ if (gPlatformLocked) {
+ if (gPlatformKeyFile == NULL) {
+ ERR_PRINT(L"Platform key file is absent\n");
+ }
+ else {
+ ApplyKeyFile(vcPwd, gPlatformKeyFile, gPlatformKeyFileSize);
+ }
+ }
+
+ if (gTPMLocked) {
+ if (gTpm != NULL) {
+ pwdReady = !EFI_ERROR(gTpm->Apply(gTpm, vcPwd));
+ if (!pwdReady) {
+ ERR_PRINT(L"TPM error: DCS configuration ");
+ if (!gTpm->IsConfigured(gTpm)) {
+ ERR_PRINT(L"absent\n");
+ }
+ else {
+ ERR_PRINT(L"locked\n");
+ }
+ }
+ } else {
+ ERR_PRINT(L"No TPM found\n");
+ }
+ }
+ } while (!pwdReady);
}
VOID
diff --git a/Library/VeraCryptLib/DcsVeraCrypt.h b/Library/VeraCryptLib/DcsVeraCrypt.h
index aae0152..fffe67c 100644
--- a/Library/VeraCryptLib/DcsVeraCrypt.h
+++ b/Library/VeraCryptLib/DcsVeraCrypt.h
@@ -19,6 +19,9 @@ https://opensource.org/licenses/Apache-2.0
#include <common/Tcdefs.h>
#include <common/Password.h>
+extern char *gConfigBuffer;
+extern UINTN gConfigBufferSize;
+
//////////////////////////////////////////////////////////////////////////
// Auth
//////////////////////////////////////////////////////////////////////////
diff --git a/Library/VeraCryptLib/VeraCryptLib.inf b/Library/VeraCryptLib/VeraCryptLib.inf
index 04eedf5..529043f 100644
--- a/Library/VeraCryptLib/VeraCryptLib.inf
+++ b/Library/VeraCryptLib/VeraCryptLib.inf
@@ -79,11 +79,13 @@ LIB|Twofish_x64.obj|*
[Packages]
MdePkg/MdePkg.dec
DcsPkg/DcsPkg.dec
+ CryptoPkg/CryptoPkg.dec
[LibraryClasses]
MemoryAllocationLib
UefiLib
RngLib
+ BaseCryptLib
[Protocols]
diff --git a/Library/VeraCryptLib/llmath.c b/Library/VeraCryptLib/llmath.c
index 6b4360c..7d79657 100644
--- a/Library/VeraCryptLib/llmath.c
+++ b/Library/VeraCryptLib/llmath.c
@@ -227,7 +227,7 @@ __declspec(naked) void __cdecl _aulldiv()
//////////////////////////////////////////////////////////////////////////
// Shifts
//////////////////////////////////////////////////////////////////////////
-__declspec(naked) void __cdecl _aullshr() {
+__declspec(naked) void __cdecl _aullshr1() {
_asm {
;
; Checking: Only handle 64bit shifting or more
@@ -264,7 +264,7 @@ _Exit:
}
}
-__declspec(naked) void __cdecl _allshl() {
+__declspec(naked) void __cdecl _allshl1() {
_asm {
;
; Handle shifting of 64 or more bits (return 0)