VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/Library/PasswordLib
diff options
context:
space:
mode:
authorAlex <kavsrf@gmail.com>2016-08-15 17:11:31 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2016-08-15 17:14:26 +0200
commitb87fc6b140772ba3017de311c7063c259424264c (patch)
tree41ad139e7469380704361ae757a155464e8b68e3 /Library/PasswordLib
parent68ea2f72cfe6a9b34212ced97882e488c73c8f1d (diff)
downloadVeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.tar.gz
VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.zip
First public release. Used by VeraCrypt 1.18.VeraCrypt_1.18_PreRelease
Diffstat (limited to 'Library/PasswordLib')
-rw-r--r--Library/PasswordLib/ConsolePassword.c128
-rw-r--r--Library/PasswordLib/PasswordLib.inf46
-rw-r--r--Library/PasswordLib/PicturePassword.c629
-rw-r--r--Library/PasswordLib/PlatformID.c266
4 files changed, 1069 insertions, 0 deletions
diff --git a/Library/PasswordLib/ConsolePassword.c b/Library/PasswordLib/ConsolePassword.c
new file mode 100644
index 0000000..c195b48
--- /dev/null
+++ b/Library/PasswordLib/ConsolePassword.c
@@ -0,0 +1,128 @@
+/** @file
+Ask password from console
+
+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 <Uefi.h>
+#include "Library/CommonLib.h"
+#include "Library/PasswordLib.h"
+#include <Library/UefiBootServicesTableLib.h>
+
+VOID
+AskConsolePwdInt(
+ OUT UINT32 *length,
+ OUT CHAR8 *asciiLine,
+ OUT INT32 *retCode,
+ IN UINTN line_max,
+ IN UINT8 show
+ )
+{
+ EFI_INPUT_KEY key;
+ UINT32 count = 0;
+ UINTN i;
+
+ gST->ConOut->EnableCursor(gST->ConOut, TRUE);
+
+ do {
+ key = GetKey();
+ // Remove dirty chars 0.1s
+ FlushInputDelay(100000);
+
+ if (key.ScanCode == SCAN_ESC) {
+ *retCode = AskPwdRetCancel;
+ break;
+ }
+
+ if (key.ScanCode == SCAN_F2) {
+ *retCode = AskPwdRetChange;
+ break;
+ }
+
+ if (key.ScanCode == SCAN_F5) {
+ show = show ? 0 : 1;
+ if (show) {
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b");
+ }
+ OUT_PRINT(L"%a", asciiLine);
+ }
+ else {
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b");
+ }
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"*");
+ }
+ }
+ }
+
+ if (key.ScanCode == SCAN_F7) {
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ ConsoleShowTip(gPlatformLocked ? L" Platform locked!" : L" Platform unlocked!", 10000000);
+ }
+
+ if (key.ScanCode == SCAN_F8) {
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ ConsoleShowTip(gTPMLocked ? L" TPM locked!" : L" TPM unlocked!", 10000000);
+ }
+
+
+ if (key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ *retCode = AskPwdRetLogin;
+ break;
+ }
+
+ if ((count >= line_max &&
+ key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED ||
+ key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ }
+ else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ OUT_PRINT(L"\b \b");
+ if (asciiLine != NULL) asciiLine[--count] = '\0';
+ continue;
+ }
+
+ // check size of line
+ if (count < line_max - 1) {
+ if (show) {
+ OUT_PRINT(L"%c", key.UnicodeChar);
+ }
+ else {
+ OUT_PRINT(L"*");
+ }
+ // save char
+ if (asciiLine != NULL) {
+ asciiLine[count++] = (CHAR8)key.UnicodeChar;
+ asciiLine[count] = 0;
+ }
+ }
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ if (length != NULL) *length = count;
+ // Set end of line
+ if (asciiLine != NULL) {
+ asciiLine[count] = '\0';
+ for (i = 0; i < count; i++) {
+ OUT_PRINT(L"\b \b");
+ }
+ OUT_PRINT(L"*");
+ }
+ OUT_PRINT(L"\n");
+}
diff --git a/Library/PasswordLib/PasswordLib.inf b/Library/PasswordLib/PasswordLib.inf
new file mode 100644
index 0000000..6b30c0c
--- /dev/null
+++ b/Library/PasswordLib/PasswordLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Password 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 = GraphLib
+ MODULE_UNI_FILE = GraphLib.uni
+ FILE_GUID = A73BC841-498A-41E5-87B1-A0CED9933756
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = GraphLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ PicturePassword.c
+ ConsolePassword.c
+ PlatformID.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid
+
+[Guids]
+ gEfiSmbiosTableGuid
diff --git a/Library/PasswordLib/PicturePassword.c b/Library/PasswordLib/PicturePassword.c
new file mode 100644
index 0000000..f917899
--- /dev/null
+++ b/Library/PasswordLib/PicturePassword.c
@@ -0,0 +1,629 @@
+/** @file
+Picture password
+
+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 <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/CommonLib.h>
+#include <Library/GraphLib.h>
+#include <Library/PasswordLib.h>
+
+CHAR16* gPasswordPictureFileName = NULL;
+
+CHAR8* gPasswordPictureChars = NULL;
+CHAR8* gPasswordPictureCharsDefault = "MN/[aQ-eyPr}GT: |V^UqiI_gbdA9YwZ%f8t6S@D\"7uXl\\30R#+zH*,W4J?=&BLFv]hx~E;$<.o'sp1`(>C)O{!5j2nmkcK";
+//CHAR8* gPicturePasswordCharsDefault = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+UINTN gPasswordPictureCharsLen = 95;
+
+UINT8 gPasswordVisible = 0;
+int gPasswordShowMark = 1;
+
+int gPlatformLocked = 0;
+int gTPMLocked = 0;
+int gSCLocked = 0;
+
+
+//////////////////////////////////////////////////////////////////////////
+// Picture password
+//////////////////////////////////////////////////////////////////////////
+CONST CHAR16* BmpName = L"Test.bmp";
+VOID* Bmp = NULL;
+UINTN BmpSize = 0;
+BLT_HEADER* bltPwd = NULL;
+UINTN posPictX, posPictY;
+BLT_HEADER* bltScrn = NULL;
+UINTN* cellSelected = NULL;
+UINTN picPwdIdx = 0;
+UINTN sHeight;
+UINTN sWidth;
+UINTN step;
+
+DRAW_CONTEXT ctxCursor;
+DRAW_CONTEXT ctxCell;
+DRAW_CONTEXT ctxMark;
+DRAW_CONTEXT ctxSet;
+
+VOID
+CellUpdate(
+ IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y,
+ IN BOOLEAN selected) {
+ if (selected && gPasswordShowMark) {
+ BltCircle(blt, &ctxMark, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 3), TRUE);
+ BltCircle(blt, &ctxCell, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 9), TRUE);
+ }
+ else {
+ CHAR8 ch[2] = { 0,0 };
+ BltCircle(blt, &ctxCell, (INT32)(x * step + step / 2), (INT32)(y * step + step / 2), (INT32)(step / 3), FALSE);
+ if (gPasswordVisible) {
+ ch[0] = gPasswordPictureChars[(x + blt->Width / step * y) % gPasswordPictureCharsLen];
+ BltText(blt, &ctxCell, (INT32)(x * step + step / 2 - 12), (INT32)(y * step + step / 2 - 12), 256, ch);
+ }
+ }
+}
+
+BOOLEAN
+CellGetSelected(
+ IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y,
+ OUT UINTN* cellX,
+ OUT UINTN* cellY) {
+ RECT reg;
+ UINTN sen;
+ if (x > blt->Width || y > blt->Height) return FALSE;
+ *cellX = x / step;
+ *cellY = y / step;
+ sen = step / 5; // zone sensible
+ reg.left = (UINT32)(*cellX * step + step / 2 - sen);
+ reg.right = (UINT32)(*cellX * step + step / 2 + sen);
+ reg.top = (UINT32)(*cellY * step + step / 2 - sen);
+ reg.bottom = (UINT32)(*cellY * step + step / 2 + sen);
+ return (x > reg.left && x < reg.right && y > reg.top && y < reg.bottom);
+}
+
+VOID
+DrawCursor(IN OUT BLT_HEADER* blt,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ BltLine(blt, &ctxCursor, (INT32)(x - 10), (INT32)y, (INT32)(x + 10), (INT32)y);
+ BltLine(blt, &ctxCursor, (INT32)x, (INT32)(y - 10), (INT32)x, (INT32)(y + 10));
+}
+
+typedef struct _TOUCH_ZONE {
+ UINTN Zone;
+ CHAR8* Message;
+ UINTN RetCode;
+ INT32 TextScale;
+} TOUCH_ZONE, *PTOUCH_ZONE;
+
+enum TouchZoneIds {
+ tznLogin = 1,
+ tznBeep,
+ tznShow,
+ tznChange
+};
+
+CHAR8* msgLogin = "LOGIN";
+CHAR8* msgBeepOn = "Beep\non";
+CHAR8* msgBeepOff = "Beep\noff";
+CHAR8* msgChg = "Change\npwd";
+CHAR8* msgShowPwd = "Show\npwd";
+CHAR8* msgHidePwd = "Hide\npwd";
+CHAR8* msgNewPwd = "New\npwd";
+CHAR8* msgConfirmPwd = "Confirm\npwd";
+CHAR8* msgPlatformLocked = "PLT\nlkd";
+CHAR8* msgPlatformUnLocked = "PLT\nunlkd";
+CHAR8* msgTpmLocked = "TPM\nlkd";
+CHAR8* msgTpmUnLocked = "TPM\nunlkd";
+
+TOUCH_ZONE TZN_Login = { 0, NULL, tznLogin, 128 };
+TOUCH_ZONE TZN_Speaker = { 2, NULL, tznBeep, 64 };
+TOUCH_ZONE TZN_Show = { 3, NULL, tznShow, 64 };
+TOUCH_ZONE TZN_Change = { 5, NULL, tznChange, 32 };
+TOUCH_ZONE TZN_Platform = { 6, NULL, 0, 32 };
+TOUCH_ZONE TZN_Tpm = { 7, NULL, 0, 32 };
+
+VOID
+DrawTouchZone(
+ IN PTOUCH_ZONE zone
+ ) {
+ BltFill(bltScrn, gColorBlack, (INT32)(sWidth - step), (INT32)(2 + zone->Zone * step), (INT32)(INT32)(sWidth - 2), (INT32)(step + zone->Zone * step));
+ BltBox(bltScrn, &ctxCell, (INT32)(sWidth - step), (INT32)(2 + zone->Zone * step), (INT32)(INT32)(sWidth - 2), (INT32)(step + zone->Zone * step));
+ BltText(bltScrn, &ctxCell, (INT32)(sWidth - step * 3 / 4), (INT32)(step * 1 / 3 + zone->Zone * step), 128, zone->Message);
+}
+
+BOOLEAN
+IsTouchZone(
+ IN PTOUCH_ZONE zone,
+ IN UINTN x,
+ IN UINTN y
+ ) {
+ if (x > sWidth - step &&
+ (y > (zone->Zone * step)) &&
+ (y < (step + zone->Zone * step))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+VOID
+DrawPwdZone(
+ IN CHAR8* pwd,
+ IN UINT32 pwdMax)
+{
+ INT32 pwdGrphMaxLen = (INT32)(sWidth - 2 * step);
+ BltFill(bltScrn, gColorBlack, 0, 0, (INT32)(sWidth - 2 * step), (INT32)(posPictY));
+ if (gPasswordVisible) {
+ BltText(bltScrn, &ctxCell, 0, 0, 256, pwd);
+ }
+ else {
+ INT32 pwdGrphLen = (INT32)(pwdGrphMaxLen * picPwdIdx / pwdMax);
+ INT32 pwdGrphHeight = (INT32)(posPictY) / 2;
+ INT32 pwdGrphTop = (INT32)(posPictY) / 4;
+ BltFill(bltScrn, gColorGreen, 0, pwdGrphTop, pwdGrphLen, pwdGrphHeight + pwdGrphTop);
+ BltFill(bltScrn, gColorBlack, pwdGrphLen, pwdGrphTop, pwdGrphMaxLen, pwdGrphHeight + pwdGrphTop);
+ }
+}
+
+EFI_STATUS
+DrawPwdPicture()
+{
+ EFI_STATUS res;
+ UINTN idx;
+ UINTN cellX, cellY;
+
+ if (bltPwd != NULL) MEM_FREE(bltPwd);
+
+ res = BmpToBlt(Bmp, BmpSize, &bltPwd);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ cellY = 0;
+ do {
+ cellX = 0;
+ do {
+ CellUpdate(bltPwd, cellX, cellY, FALSE);
+ cellX++;
+ } while ((cellX + 1) * step <= (bltPwd->Width));
+ cellY++;
+ } while ((cellY + 1)* step <= (bltPwd->Height));
+
+ // Update selected
+ for (idx = 0; idx < picPwdIdx; ++idx) {
+ if (cellSelected[idx * 2] != MAX_INTN) {
+ CellUpdate(bltPwd, cellSelected[idx * 2], cellSelected[idx * 2 + 1], TRUE);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+VOID
+CreateDraws() {
+ // Set
+ ctxSet.Color = gColorGray;
+ ctxSet.DashLine = 0xFFFFFFFF;
+ ctxSet.Op = DrawOpSet;
+ ctxSet.Brush = NULL;
+
+ // Cursor
+ ctxCursor.Color = gColorWhite;
+ ctxCursor.DashLine = 0xFFFFFFFF;
+ ctxCursor.Op = DrawOpXor;
+ ctxCursor.Brush = NULL;
+
+ // Cell
+ ctxCell.Color = gColorGreen;
+ ctxCell.DashLine = 0xFFFFFFFF;
+ ctxCell.Op = DrawOpSet;
+ ctxCell.Brush = gBrush3;
+
+ // Shade (close to black)
+ ctxMark.AlphaColor = gColorWhite;
+ ctxMark.Alpha = 128;
+ ctxMark.Op = DrawOpAlpha;
+ ctxMark.Brush = NULL;
+}
+
+enum PictPwdAction {
+ PwdActNone = 0,
+ PwdActLogin,
+ PwdActCancel,
+ PwdActChange,
+ PwdActShow,
+ PwdActBeep,
+ PwdActNewChar,
+ PwdActUpdateZones,
+};
+
+VOID
+AskPictPwdInt(
+ IN UINTN pwdType,
+ IN UINTN pwdMax,
+ OUT CHAR8* pwd,
+ OUT UINT32* pwdLen,
+ OUT INT32* retCode
+ ) {
+ EFI_STATUS res;
+ UINTN cellX, cellY;
+ UINTN cellPrevX, cellPrevY;
+ UINTN curX, curY;
+ UINTN curPrevX, curPrevY;
+ EFI_INPUT_KEY key;
+ EFI_EVENT UpdateEvent;
+ EFI_EVENT BeepOffEvent;
+ EFI_EVENT InputEvents[3];
+ UINTN EventIndex = 0;
+ UINTN eventsCount = 2;
+ EFI_ABSOLUTE_POINTER_STATE aps = {0};
+ BOOLEAN showCursor = FALSE;
+ BOOLEAN beepOn = FALSE;
+ UINTN pwdAction = PwdActNone;
+ CHAR8 pwdNewChar = 0;
+
+ InitConsoleControl();
+ if (gBeepEnabled) {
+ InitSpeaker();
+ }
+
+ if (Bmp == NULL) {
+ if (gPasswordPictureFileName != NULL) {
+ res = FileLoad(NULL, (CHAR16*)gPasswordPictureFileName, &Bmp, &BmpSize);
+ if (EFI_ERROR(res)) {
+ ERR_PRINT(L"File load - %r\n", res);
+ return;
+ }
+ } else {
+ ERR_PRINT(L"Picture file name undefined\n");
+ return;
+ }
+ }
+ // Init draws
+ CreateDraws();
+
+ // Init screen
+ if (bltScrn != NULL) MEM_FREE(bltScrn);
+ ScreenSaveBlt(&bltScrn);
+ sWidth = bltScrn->Width;
+ sHeight = bltScrn->Height;
+ step = sWidth >> 4;
+
+ // Init picture password
+ picPwdIdx = 0;
+ res = DrawPwdPicture();
+ if (EFI_ERROR(res)) {
+ MEM_FREE(bltScrn);
+ ERR_PRINT(L"BmpToBlt - %r", res);
+ return;
+ }
+
+ // Touch zones
+ switch (pwdType) {
+ case AskPwdConfirm:
+ TZN_Login.Message = msgConfirmPwd;
+ break;
+ case AskPwdNew:
+ TZN_Login.Message = msgNewPwd;
+ break;
+ case AskPwdLogin:
+ default:
+ TZN_Login.Message = msgLogin;
+ }
+ DrawTouchZone(&TZN_Login);
+
+ if (pwdType == AskPwdLogin) {
+ TZN_Change.Message = msgChg;
+ DrawTouchZone(&TZN_Change);
+ }
+
+ if (gBeepControlEnabled) {
+ TZN_Speaker.Message = gBeepEnabled ? msgBeepOff : msgBeepOn;
+ DrawTouchZone(&TZN_Speaker);
+ }
+
+ TZN_Platform.Message = gPlatformLocked? msgPlatformLocked : msgPlatformUnLocked;
+ DrawTouchZone(&TZN_Platform);
+
+ TZN_Tpm.Message = gTPMLocked ? msgTpmLocked : msgTpmUnLocked;
+ DrawTouchZone(&TZN_Tpm);
+
+ TZN_Show.Message = gPasswordVisible ? msgHidePwd : msgShowPwd;
+ DrawTouchZone(&TZN_Show);
+ cellSelected = MEM_ALLOC(sizeof(UINTN) * 2 * (pwdMax + 1));
+
+ ScreenUpdateDirty(bltScrn);
+
+ // Prepare cursors
+ posPictX = (sWidth - bltPwd->Width) >> 1;
+ posPictY = (sHeight - bltPwd->Height) >> 1;
+ cellPrevX = MAX_INTN;
+ cellPrevY = MAX_INTN;
+ curX = sWidth / 2;
+ curY = posPictY / 2;
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+
+ // Prepare events
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &BeepOffEvent);
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &UpdateEvent);
+ gBS->SetTimer(UpdateEvent, TimerRelative, 500000); // 20 times per second to update
+ gBS->SetTimer(BeepOffEvent, TimerRelative, gBeepDurationDefault * 10);
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+
+ if (gTouchPointer != NULL) {
+ eventsCount = 3;
+ InputEvents[2] = gTouchPointer->WaitForInput;
+ while (gBS->CheckEvent(InputEvents[2]) == EFI_SUCCESS) {
+ gTouchPointer->GetState(gTouchPointer, &aps);
+ }
+ }
+ while (gBS->CheckEvent(InputEvents[0]) == EFI_SUCCESS) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+ do
+ {
+ curPrevX = curX;
+ curPrevY = curY;
+ res = gBS->WaitForEvent(eventsCount, InputEvents, &EventIndex);
+ // OUT_PRINT(L" \r%05d %05d", (UINT32)curX, (UINT32)curY, );
+ // recharge timeout event and stop beep
+ if (gBeepControlEnabled && gBeepEnabled && beepOn) {
+ if (gBS->CheckEvent(BeepOffEvent) == EFI_SUCCESS) {
+ beepOn = FALSE;
+ SpeakerBeep((UINT16)gBeepToneDefault, 0, 0, 0);
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+ }
+ }
+ else {
+ gBS->SetTimer(InputEvents[1], TimerRelative, 5000000);
+ }
+
+ // hide cursor
+ if (showCursor && EventIndex != 1) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = FALSE;
+ }
+
+ // Blink cursor
+ if (EventIndex == 1) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = !showCursor;
+ }
+
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ // OUT_PRINT(L" %04x, %04x\r", key.ScanCode, key.UnicodeChar);
+
+ // Remove dirty chars 0.1s
+ FlushInputDelay(100000);
+ switch (key.ScanCode)
+ {
+ case SCAN_HOME:
+ curX -= gTouchSimulateStep;
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_LEFT:
+ curX -= gTouchSimulateStep;
+ break;
+ case SCAN_END:
+ curX -= gTouchSimulateStep;
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_DOWN:
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_PAGE_DOWN:
+ curX += gTouchSimulateStep;
+ curY += gTouchSimulateStep;
+ break;
+ case SCAN_RIGHT:
+ curX += gTouchSimulateStep;
+ break;
+ case SCAN_PAGE_UP:
+ curX += gTouchSimulateStep;
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_UP:
+ curY -= gTouchSimulateStep;
+ break;
+ case SCAN_F11:
+ if (gTouchSimulateStep > 1)
+ gTouchSimulateStep--;
+ break;
+ case SCAN_F12:
+ gTouchSimulateStep++;
+ break;
+ case SCAN_ESC:
+ pwdAction = PwdActCancel;
+ break;
+ case SCAN_F2:
+ if (pwdType == AskPwdLogin) {
+ pwdAction = PwdActChange;
+ }
+ break;
+ case SCAN_F4:
+ if (gBeepControlEnabled) {
+ pwdAction = PwdActBeep;
+ }
+ break;
+ case SCAN_F5:
+ pwdAction = PwdActShow;
+ break;
+ case SCAN_F7:
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ break;
+ case SCAN_F8:
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ break;
+ default:
+ ;
+ }
+
+ if (key.UnicodeChar != 0) {
+ if (key.UnicodeChar == 0x0d) {
+ pwdAction = PwdActLogin;
+ }
+ else {
+ pwdNewChar = (CHAR8)key.UnicodeChar;
+ pwdAction = PwdActNewChar;
+ cellSelected[picPwdIdx * 2] = MAX_INTN;
+ }
+ }
+
+ }
+
+ if (EventIndex == 2) {
+ res = gTouchPointer->GetState(gTouchPointer, &aps);
+ if (!EFI_ERROR(res)) {
+ curX = (UINTN)(aps.CurrentX * sWidth / (gTouchPointer->Mode->AbsoluteMaxX - gTouchPointer->Mode->AbsoluteMinX));
+ curY = (UINTN)(aps.CurrentY * sHeight / (gTouchPointer->Mode->AbsoluteMaxY - gTouchPointer->Mode->AbsoluteMinY));
+ }
+ }
+
+ if (curX > sWidth) curX = sWidth;
+ if (curY > sHeight) curY = sHeight;
+
+ // Cell check
+ if (CellGetSelected(bltPwd, curX - posPictX, curY - posPictY, &cellX, &cellY) && picPwdIdx < pwdMax) {
+ if (cellPrevX != cellX || cellPrevY != cellY) {
+ cellPrevX = cellX;
+ cellPrevY = cellY;
+ cellSelected[picPwdIdx * 2] = cellX;
+ cellSelected[picPwdIdx * 2 + 1] = cellY;
+ CellUpdate(bltPwd, cellX, cellY, TRUE);
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+ pwdAction = PwdActNewChar;
+ pwdNewChar = gPasswordPictureChars[(cellX + bltPwd->Width / step * cellY) % gPasswordPictureCharsLen];
+ }
+ else if (EventIndex == 2 && aps.ActiveButtons == 0) {
+ cellPrevX = MAX_INTN;
+ cellPrevY = MAX_INTN;
+ curX = posPictX + cellX * step;
+ curY = posPictY + cellY * step;
+ while (gBS->CheckEvent(InputEvents[2]) == EFI_SUCCESS) {
+ gTouchPointer->GetState(gTouchPointer, &aps);
+ }
+ }
+ }
+
+ if (pwdAction == PwdActNone) {
+ if (IsTouchZone(&TZN_Login, curX, curY)) {
+ pwdAction = PwdActLogin;
+ }
+
+ if (pwdType == AskPwdLogin && IsTouchZone(&TZN_Change, curX, curY)) {
+ pwdAction = PwdActChange;
+ }
+
+ if (curPrevX != curX || curPrevY != curY) {
+ if (gSpeakerCount > 0 && IsTouchZone(&TZN_Speaker, curX, curY)) {
+ pwdAction = PwdActBeep;
+ }
+ if (IsTouchZone(&TZN_Show, curX, curY)) {
+ pwdAction = PwdActShow;
+ }
+ if (IsTouchZone(&TZN_Tpm, curX, curY)) {
+ gTPMLocked = gTPMLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ }
+ if (IsTouchZone(&TZN_Platform, curX, curY)) {
+ gPlatformLocked = gPlatformLocked ? 0 : 1;
+ pwdAction = PwdActUpdateZones;
+ }
+ }
+ }
+
+ if (PwdActNewChar == pwdAction) {
+ BOOLEAN bUpdPwdZone = FALSE;
+ if (pwdNewChar == '\b' && picPwdIdx > 0) {
+ picPwdIdx--;
+ pwd[picPwdIdx] = 0;
+ bUpdPwdZone = TRUE;
+ } else if ((picPwdIdx < pwdMax - 1) && (pwdNewChar >= 32)) {
+ pwd[picPwdIdx++] = pwdNewChar;
+ pwd[picPwdIdx] = 0;
+ bUpdPwdZone = TRUE;
+ }
+ if(bUpdPwdZone) {
+ *pwdLen = (int)picPwdIdx;
+ DrawPwdZone(pwd, (INT32)pwdMax);
+ if (gBeepControlEnabled && gBeepEnabled) {
+ SpeakerBeep((UINT16)gBeepToneDefault, gBeepNumberDefault, 0, 0);
+ gBS->SetTimer(BeepOffEvent, TimerRelative, gBeepDurationDefault * 10);
+ gBS->SetTimer(InputEvents[1], TimerRelative, gBeepDurationDefault * 10);
+ beepOn = TRUE;
+ }
+ }
+ }
+ else if (PwdActBeep == pwdAction && gBeepControlEnabled) {
+ if (gBeepEnabled && beepOn) {
+ beepOn = FALSE;
+ SpeakerBeep((UINT16)gBeepToneDefault, 0, 0, 0);
+ }
+ gBeepEnabled = gBeepEnabled ? 0 : 1;
+ TZN_Speaker.Message = gBeepEnabled ? msgBeepOff : msgBeepOn;
+ DrawTouchZone(&TZN_Speaker);
+ }
+ else if (PwdActShow == pwdAction) {
+ gPasswordVisible = gPasswordVisible ? 0 : 1;
+ DrawPwdZone(pwd, (INT32)pwdMax);
+ DrawPwdPicture();
+ BltDrawBlt(bltScrn, bltPwd, posPictX, posPictY);
+ TZN_Show.Message = gPasswordVisible ? msgHidePwd : msgShowPwd;
+ DrawTouchZone(&TZN_Show);
+ }
+ else if (PwdActLogin == pwdAction) {
+ *retCode = AskPwdRetLogin;
+ break;
+ }
+ else if (pwdType == AskPwdLogin && PwdActChange == pwdAction) {
+ *retCode = AskPwdRetChange;
+ break;
+ }
+ else if (PwdActCancel == pwdAction){
+ *retCode = AskPwdRetCancel;
+ break;
+ }
+ else if (PwdActUpdateZones == pwdAction) {
+ TZN_Platform.Message = gPlatformLocked ? msgPlatformLocked : msgPlatformUnLocked;
+ DrawTouchZone(&TZN_Platform);
+
+ TZN_Tpm.Message = gTPMLocked ? msgTpmLocked : msgTpmUnLocked;
+ DrawTouchZone(&TZN_Tpm);
+ }
+
+ if (curPrevX != curX || curPrevY != curY) {
+ DrawCursor(bltScrn, curX, curY);
+ showCursor = TRUE;
+ }
+ // Time to update screen?
+ if (gBS->CheckEvent(UpdateEvent) == EFI_SUCCESS) {
+ ScreenUpdateDirty(bltScrn);
+ gBS->SetTimer(UpdateEvent, TimerRelative, 500000); // 20 times per second to update
+ }
+
+ pwdAction = PwdActNone;
+ } while (TRUE);
+ gBS->CloseEvent(InputEvents[1]);
+ gBS->CloseEvent(UpdateEvent);
+ gBS->CloseEvent(BeepOffEvent);
+ ScreenFillRect(&gColorBlack, 0, 0, sWidth, sHeight);
+ gBS->Stall(500000);
+}
diff --git a/Library/PasswordLib/PlatformID.c b/Library/PasswordLib/PlatformID.c
new file mode 100644
index 0000000..351503e
--- /dev/null
+++ b/Library/PasswordLib/PlatformID.c
@@ -0,0 +1,266 @@
+/** @file
+Platform Id based on SMBIOS structures
+
+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 <Uefi.h>
+#include <Guid/SmBios.h>
+#include <IndustryStandard\SmBios.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "Library/CommonLib.h"
+
+SMBIOS_TABLE_ENTRY_POINT* gSmbTable = NULL;
+EFI_GUID* gSmbSystemUUID = NULL; // Universal unique ID
+CHAR8* gSmbSystemSerial = NULL; // System serial
+CHAR8* gSmbSystemSKU = NULL; // SKU number
+CHAR8* gSmbBaseBoardSerial = NULL; // Base board serial
+UINT64* gSmbProcessorID = NULL; // Processor ID
+
+UINTN gBioIndexAuth = 0;
+typedef struct _DCS_AUTH_DATA_MARK {
+ UINT32 HeaderCrc;
+ UINT32 PlatformCrc;
+ UINT32 AuthDataSize;
+ UINT32 Reserved;
+} DCS_AUTH_DATA_MARK;
+
+CHAR8* SMBIOSGetString(UINTN StringNumber, SMBIOS_STRUCTURE* smbtbl, CHAR8* lastAddr) {
+ CHAR8* String;
+ UINTN Index;
+ String = ((UINT8*)smbtbl) + smbtbl->Length;
+ for (Index = 1; Index <= StringNumber; Index++) {
+ if (StringNumber == Index) {
+ return String;
+ }
+ //
+ // Skip string
+ //
+ while (*String != 0) {
+ String++;
+ if (String > lastAddr) {
+ return NULL;
+ }
+ }
+ String++;
+// if (*String == 0) {
+// return NULL;
+// }
+ }
+ return NULL;
+}
+
+/**
+* Get SMBIOS serial data
+*/
+EFI_STATUS
+SMBIOSGetSerials()
+{
+ EFI_STATUS res;
+ SMBIOS_STRUCTURE_POINTER pSMBIOS;
+ CHAR8* pos = NULL;
+ CHAR8* endOfTable;
+
+ // Get SMBIOS tables pointer from System Configure table
+ res = EfiGetSystemConfigurationTable(&gEfiSmbiosTableGuid, (VOID**)&gSmbTable);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ pSMBIOS.Raw = (UINT8 *)(UINTN)(gSmbTable->TableAddress);
+ pos = pSMBIOS.Raw;
+ endOfTable = pSMBIOS.Raw + gSmbTable->TableLength;
+ do {
+ SMBIOS_STRUCTURE* smbtbl = (SMBIOS_STRUCTURE*)pos;
+ // System info
+ if (smbtbl->Type == 1) {
+ gSmbSystemUUID = (EFI_GUID*)&pos[8];
+ gSmbSystemSerial = SMBIOSGetString(4, smbtbl, endOfTable);
+ gSmbSystemSKU = SMBIOSGetString(5, smbtbl, endOfTable);
+ }
+ // Base board
+ if (smbtbl->Type == 2) {
+ gSmbBaseBoardSerial = SMBIOSGetString(4, smbtbl, endOfTable);
+ }
+ // Processor
+ if (smbtbl->Type == 4) {
+ gSmbProcessorID = (UINT64*)&pos[8];
+ }
+ pos += smbtbl->Length;
+ while (((pos[0] != 0) || (pos[1] != 0)) && (pos < endOfTable)) pos++;
+ pos += 2;
+ } while (pos < endOfTable);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PlatformGetID(
+ IN EFI_HANDLE handle,
+ OUT CHAR8 **id,
+ OUT UINTN *idlength
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINTN idLen = 0;
+ CHAR8* idBuf = NULL;
+ CHAR8* handleSerial = NULL;
+
+ UsbGetId(handle, &handleSerial);
+ if (gSmbSystemUUID == NULL) SMBIOSGetSerials();
+ idLen += (gSmbSystemUUID == NULL) ? 0 : sizeof(*gSmbSystemUUID);
+ idLen += (gSmbSystemSerial == NULL) ? 0 : AsciiStrLen((char*)gSmbSystemSerial) + 1;
+ idLen += (gSmbSystemSKU == NULL) ? 0 : AsciiStrLen((char*)gSmbSystemSKU) + 1;
+ idLen += (gSmbBaseBoardSerial == NULL) ? 0 : AsciiStrLen((char*)gSmbBaseBoardSerial) + 1;
+ idLen += (gSmbProcessorID == NULL) ? 0 : sizeof(*gSmbProcessorID);
+ idLen += (handleSerial == NULL) ? 0 : AsciiStrLen((char*)handleSerial) + 1;
+
+ idBuf = MEM_ALLOC(idLen);
+ if (idBuf == NULL) {
+ res = EFI_BUFFER_TOO_SMALL;
+ goto error;
+ }
+
+ *id = idBuf;
+ *idlength = idLen;
+
+ if (gSmbSystemUUID != NULL) {
+ CopyMem(idBuf, gSmbSystemUUID, sizeof(*gSmbSystemUUID));
+ idBuf += sizeof(*gSmbSystemUUID);
+ }
+
+ if (gSmbSystemSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbSystemSerial) + 1;
+ CopyMem(idBuf, gSmbSystemSerial, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbSystemSKU != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbSystemSKU) + 1;
+ CopyMem(idBuf, gSmbSystemSKU, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbBaseBoardSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)gSmbBaseBoardSerial) + 1;
+ CopyMem(idBuf, gSmbBaseBoardSerial, ssz);
+ idBuf += ssz;
+ }
+
+ if (gSmbProcessorID != NULL) {
+ CopyMem(idBuf, gSmbProcessorID, sizeof(*gSmbProcessorID));
+ idBuf += sizeof(*gSmbProcessorID);
+ }
+
+ if (handleSerial != NULL) {
+ UINTN ssz;
+ ssz = AsciiStrLen((char*)handleSerial) + 1;
+ CopyMem(idBuf, handleSerial, ssz);
+ idBuf += ssz;
+ MEM_FREE(handleSerial);
+ }
+
+ return res;
+
+error:
+ MEM_FREE(handleSerial);
+ MEM_FREE(idBuf);
+ return res;
+}
+
+
+EFI_STATUS
+PlatformGetIDCRC(
+ IN EFI_HANDLE handle,
+ OUT UINT32 *crc32
+ )
+{
+ EFI_STATUS res;
+ UINTN crcLen;
+ CHAR8* crcBuf = NULL;
+ res = PlatformGetID(handle, &crcBuf, &crcLen);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = gBS->CalculateCrc32(crcBuf, crcLen, crc32);
+ MEM_FREE(crcBuf);
+ return res;
+}
+
+EFI_STATUS
+PlatformGetAuthDataByType(
+ OUT UINT8 **data,
+ OUT UINTN *len,
+ OUT EFI_HANDLE *secRegionHandle,
+ IN BOOLEAN RemovableMedia)
+{
+ EFI_STATUS res;
+ UINT32 crc;
+ CHAR8* buf = NULL;
+ EFI_BLOCK_IO_PROTOCOL* bio;
+ DCS_AUTH_DATA_MARK* mark = NULL;
+ mark = (DCS_AUTH_DATA_MARK*)MEM_ALLOC(512);
+ for (; gBioIndexAuth < gBIOCount; ++gBioIndexAuth) {
+ bio = EfiGetBlockIO(gBIOHandles[gBioIndexAuth]);
+ if (bio == NULL) continue;
+ if(bio->Media->RemovableMedia != RemovableMedia) continue;
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 61, 512, mark);
+ if (EFI_ERROR(res)) continue;
+
+ res = gBS->CalculateCrc32(&mark->PlatformCrc, sizeof(*mark) - 4, &crc);
+ if (EFI_ERROR(res)) continue;
+ if( crc != mark->HeaderCrc) continue;
+
+ res = PlatformGetIDCRC(gBIOHandles[gBioIndexAuth], &crc);
+ if (EFI_ERROR(res)) continue;
+ if (crc != mark->PlatformCrc) continue;
+
+ buf = MEM_ALLOC(mark->AuthDataSize * 1024 * 128);
+ if (buf == NULL) continue;
+
+ res = bio->ReadBlocks(bio, bio->Media->MediaId, 62, mark->AuthDataSize * 1024 * 128, buf);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(buf);
+ continue;
+ }
+ *data = buf;
+ *len = mark->AuthDataSize * 1024 * 128;
+ *secRegionHandle = gBIOHandles[gBioIndexAuth];
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_FOUND;
+}
+
+BOOLEAN gBioIndexAuthOnRemovable = TRUE;
+
+EFI_STATUS
+PlatformGetAuthData(
+ OUT UINT8 **data,
+ OUT UINTN *len,
+ OUT EFI_HANDLE *secRegionHandle
+ )
+{
+ EFI_STATUS res;
+ res = PlatformGetAuthDataByType(data, len, secRegionHandle, gBioIndexAuthOnRemovable);
+ if (EFI_ERROR(res)) {
+ if (gBioIndexAuthOnRemovable) {
+ gBioIndexAuthOnRemovable = FALSE;
+ gBioIndexAuth = 0;
+ res = PlatformGetAuthDataByType(data, len, secRegionHandle, FALSE);
+ }
+ }
+ return res;
+}
+