From 1921b89c48680ec0a180adeaab26a23c3e5a3f72 Mon Sep 17 00:00:00 2001
From: Mounir IDRASSI <mounir.idrassi@idrix.fr>
Date: Thu, 28 Nov 2019 18:36:36 +0100
Subject: Fix F5 showing previous password after failed authentication attempt.
 Ensure that even wrong password value are cleared from memory.

---
 DcsInt/DcsInt.c                       | 48 ++++++++++++++++++++++-------------
 Library/PasswordLib/ConsolePassword.c | 26 +++++++++++--------
 Library/VeraCryptLib/DcsVeraCrypt.c   |  2 ++
 3 files changed, 47 insertions(+), 29 deletions(-)

diff --git a/DcsInt/DcsInt.c b/DcsInt/DcsInt.c
index 7dd98ec..b7e392f 100644
--- a/DcsInt/DcsInt.c
+++ b/DcsInt/DcsInt.c
@@ -160,29 +160,33 @@ PrepareBootParams(
 	IN PCRYPTO_INFO   cryptoInfo)
 {
 	BootArguments           *bootArgs;
-	if (bootParams == NULL) return EFI_UNSUPPORTED;
-	bootArgs = &bootParams->BootArgs;
-	TC_SET_BOOT_ARGUMENTS_SIGNATURE(bootArgs->Signature);
-	bootArgs->BootLoaderVersion = VERSION_NUM;
-	bootArgs->CryptoInfoOffset = (uint16)(FIELD_OFFSET(BOOT_PARAMS, BootCryptoInfo));
-	bootArgs->CryptoInfoLength = (uint16)(sizeof(BOOT_CRYPTO_HEADER) + 2 + sizeof(SECREGION_BOOT_PARAMS));
-	bootArgs->HeaderSaltCrc32 = gHeaderSaltCrc32;
-	CopyMem(&bootArgs->BootPassword, &gAuthPassword, sizeof(gAuthPassword));
-	bootArgs->HiddenSystemPartitionStart = 0;
-	bootArgs->DecoySystemPartitionStart = 0;
-	bootArgs->BootDriveSignature = bootDriveSignature;
-	bootArgs->Flags = (uint32)(gAuthPim << 16);
-	bootArgs->BootArgumentsCrc32 = GetCrc32((byte *)bootArgs, (int)((byte *)&bootArgs->BootArgumentsCrc32 - (byte *)bootArgs));
-	bootParams->BootCryptoInfo.ea = (uint16)cryptoInfo->ea;
-	bootParams->BootCryptoInfo.mode = (uint16)cryptoInfo->mode;
-	bootParams->BootCryptoInfo.pkcs5 = (uint16)cryptoInfo->pkcs5;
-	SetSecRegionParamsMemory();
+	EFI_STATUS              status;
+	if (bootParams == NULL) status = EFI_UNSUPPORTED;
+	else {
+		bootArgs = &bootParams->BootArgs;
+		TC_SET_BOOT_ARGUMENTS_SIGNATURE(bootArgs->Signature);
+		bootArgs->BootLoaderVersion = VERSION_NUM;
+		bootArgs->CryptoInfoOffset = (uint16)(FIELD_OFFSET(BOOT_PARAMS, BootCryptoInfo));
+		bootArgs->CryptoInfoLength = (uint16)(sizeof(BOOT_CRYPTO_HEADER) + 2 + sizeof(SECREGION_BOOT_PARAMS));
+		bootArgs->HeaderSaltCrc32 = gHeaderSaltCrc32;
+		CopyMem(&bootArgs->BootPassword, &gAuthPassword, sizeof(gAuthPassword));
+		bootArgs->HiddenSystemPartitionStart = 0;
+		bootArgs->DecoySystemPartitionStart = 0;
+		bootArgs->BootDriveSignature = bootDriveSignature;
+		bootArgs->Flags = (uint32)(gAuthPim << 16);
+		bootArgs->BootArgumentsCrc32 = GetCrc32((byte *)bootArgs, (int)((byte *)&bootArgs->BootArgumentsCrc32 - (byte *)bootArgs));
+		bootParams->BootCryptoInfo.ea = (uint16)cryptoInfo->ea;
+		bootParams->BootCryptoInfo.mode = (uint16)cryptoInfo->mode;
+		bootParams->BootCryptoInfo.pkcs5 = (uint16)cryptoInfo->pkcs5;
+		SetSecRegionParamsMemory();
+		status = EFI_SUCCESS;
+	}
 
 	// Clean auth data
 	MEM_BURN(&gAuthPassword, sizeof(gAuthPassword));
 	MEM_BURN(&gAuthPim, sizeof(gAuthPim));
 
-	return EFI_SUCCESS;
+	return status;
 }
 
 void GetIntersection(uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength)
@@ -708,6 +712,10 @@ SecRegionTryDecrypt()
 			break;
 		}	else {
 			ERR_PRINT(L"%a", gAuthErrorMsg);
+			// clear previous failed authentication information
+			MEM_BURN(&gAuthPassword, sizeof(gAuthPassword));
+			if (gAuthPimRqt)
+				MEM_BURN(&gAuthPim, sizeof(gAuthPim));
 		}
 		retry--;
 	} while (vcres != 0 && retry > 0);
@@ -1186,6 +1194,10 @@ UefiMain(
 	gST->ConIn->Reset(gST->ConIn, FALSE);
 
 	if (EFI_ERROR(res)) {
+		// clear buffers with potential authentication data
+		MEM_BURN(&gAuthPassword, sizeof(gAuthPassword));
+		MEM_BURN(&gAuthPim, sizeof(gAuthPim));
+
 		if (res == EFI_TIMEOUT)
 			return OnExit(gOnExitTimeout, OnExitAuthTimeout, res);
 		else if (res == EFI_DCS_USER_CANCELED)
diff --git a/Library/PasswordLib/ConsolePassword.c b/Library/PasswordLib/ConsolePassword.c
index 0b2d3c6..8588a19 100644
--- a/Library/PasswordLib/ConsolePassword.c
+++ b/Library/PasswordLib/ConsolePassword.c
@@ -29,6 +29,8 @@ AskConsolePwdInt(
 	EFI_INPUT_KEY key;
 	UINT32 count = 0;
 	UINTN i;
+	
+	if ((asciiLine != NULL) && (line_max >= 1)) asciiLine[0] = '\0';
 
 	gST->ConOut->EnableCursor(gST->ConOut, TRUE);
 	if (gPasswordTimeout) {
@@ -63,19 +65,21 @@ AskConsolePwdInt(
 
 		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");
+			if (count > 0) {
+				if (show) {
+					for (i = 0; i < count; i++) {
+						OUT_PRINT(L"\b");
+					}
+					OUT_PRINT(L"%a", asciiLine);
 				}
-				if (gPasswordProgress) {
+				else {
 					for (i = 0; i < count; i++) {
-						OUT_PRINT(L"*");
+						OUT_PRINT(L"\b");
+					}
+					if (gPasswordProgress) {
+						for (i = 0; i < count; i++) {
+							OUT_PRINT(L"*");
+						}
 					}
 				}
 			}
diff --git a/Library/VeraCryptLib/DcsVeraCrypt.c b/Library/VeraCryptLib/DcsVeraCrypt.c
index c3e8a39..b99ed0b 100644
--- a/Library/VeraCryptLib/DcsVeraCrypt.c
+++ b/Library/VeraCryptLib/DcsVeraCrypt.c
@@ -400,9 +400,11 @@ VCAskPwd(
 VOID
 VCAuthAsk() 
 {
+	MEM_BURN(&gAuthPassword, sizeof(gAuthPassword));
 	VCAskPwd(AskPwdLogin, &gAuthPassword);
 
 	if ((gAuthPwdCode == AskPwdRetCancel) || (gAuthPwdCode == AskPwdRetTimeout)) {
+		MEM_BURN(&gAuthPassword, sizeof(gAuthPassword));
 		return;
 	}
 
-- 
cgit v1.2.3