VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/Library
diff options
context:
space:
mode:
authorkavsrf <kavsrf@gmail.com>2016-12-04 13:46:48 +0300
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2017-06-05 17:36:42 +0200
commit6701b862aa96775609a7d42662ae4a98e43071bb (patch)
tree3900fcd874625898d9ab921ec6f2e3f5f8ef4b97 /Library
parentebe8c240166ef25ed0ca8898f8bfd34b415a75d0 (diff)
downloadVeraCrypt-DCS-6701b862aa96775609a7d42662ae4a98e43071bb.tar.gz
VeraCrypt-DCS-6701b862aa96775609a7d42662ae4a98e43071bb.zip
TPM12 support
Diffstat (limited to 'Library')
-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
9 files changed, 1724 insertions, 67 deletions
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)