From b87fc6b140772ba3017de311c7063c259424264c Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Aug 2016 17:11:31 +0200 Subject: First public release. Used by VeraCrypt 1.18. --- Library/PasswordLib/ConsolePassword.c | 128 +++++++ Library/PasswordLib/PasswordLib.inf | 46 +++ Library/PasswordLib/PicturePassword.c | 629 ++++++++++++++++++++++++++++++++++ Library/PasswordLib/PlatformID.c | 266 ++++++++++++++ 4 files changed, 1069 insertions(+) create mode 100644 Library/PasswordLib/ConsolePassword.c create mode 100644 Library/PasswordLib/PasswordLib.inf create mode 100644 Library/PasswordLib/PicturePassword.c create mode 100644 Library/PasswordLib/PlatformID.c (limited to 'Library/PasswordLib') 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 +#include "Library/CommonLib.h" +#include "Library/PasswordLib.h" +#include + +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 +#include +#include + +#include +#include +#include + +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 +#include +#include +#include +#include + +#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; +} + -- cgit v1.2.3