https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ab43f8698085764deaca8…
commit ab43f8698085764deaca857c831afde40a084d35
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Sep 13 19:58:06 2020 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Fri Sep 25 09:39:51 2020 +0200
[KSECDD] Fix RtlEncryptMemory and improve test
---
drivers/crypto/ksecdd/crypt.c | 28 +++++-
.../rostests/apitests/advapi32/RtlEncryptMemory.c | 104 +++++++++++++++++++--
2 files changed, 122 insertions(+), 10 deletions(-)
diff --git a/drivers/crypto/ksecdd/crypt.c b/drivers/crypto/ksecdd/crypt.c
index ab639346b45..0a2a41e991f 100644
--- a/drivers/crypto/ksecdd/crypt.c
+++ b/drivers/crypto/ksecdd/crypt.c
@@ -27,6 +27,18 @@ typedef struct _KSEC_LOGON_DATA
LUID LogonId;
} KSEC_LOGON_DATA, *PKSEC_LOGON_DATA;
+#if 0
+void PrintKeyData(PUCHAR KeyData)
+{
+ ULONG i;
+ for (i = 0; i < 32; i++)
+ {
+ DbgPrint("%02X", KeyData[i]);
+ }
+ DbgPrint("\n");
+}
+#endif
+
VOID
NTAPI
KsecInitializeEncryptionSupport (
@@ -80,6 +92,8 @@ KsecGetKeyData (
if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
{
+ /* Hash some process specific data to generate the key */
+ RtlZeroMemory(&ProcessData, sizeof(ProcessData));
ProcessData.Process = CurrentProcess;
ProcessData.ProcessId = CurrentProcess->UniqueProcessId;
ProcessData.CreateTime = PsGetProcessCreateTimeQuadPart(CurrentProcess);
@@ -87,14 +101,26 @@ KsecGetKeyData (
MD5Update(&Md5Contexts[0], (PVOID)&ProcessData, sizeof(ProcessData));
MD5Update(&Md5Contexts[1], (PVOID)&ProcessData, sizeof(ProcessData));
}
- else // if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
+ else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
{
+ /* Hash the logon id to generate the key */
+ RtlZeroMemory(&LogonData, sizeof(LogonData));
Token = PsReferencePrimaryToken(CurrentProcess);
SeQueryAuthenticationIdToken(Token, &LogonData.LogonId);
PsDereferencePrimaryToken(Token);
MD5Update(&Md5Contexts[0], (PVOID)&LogonData, sizeof(LogonData));
MD5Update(&Md5Contexts[1], (PVOID)&LogonData, sizeof(LogonData));
}
+ else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
+ {
+ /* Use the original MD5s to generate the global key */
+ NOTHING;
+ }
+ else
+ {
+ /* Must not pass anything else */
+ ASSERT(FALSE);
+ }
/* Finalize the MD5s */
MD5Final(&Md5Contexts[0]);
diff --git a/modules/rostests/apitests/advapi32/RtlEncryptMemory.c
b/modules/rostests/apitests/advapi32/RtlEncryptMemory.c
index 8cc5036962a..81f27bb5185 100644
--- a/modules/rostests/apitests/advapi32/RtlEncryptMemory.c
+++ b/modules/rostests/apitests/advapi32/RtlEncryptMemory.c
@@ -9,26 +9,112 @@
#include <ntsecapi.h>
-START_TEST(RtlEncryptMemory)
+static const CHAR TestData[32] = "This is some test Message!!!";
+
+void TestEncrypt(ULONG OptionFlags)
{
- static const CHAR TestData[32] = "This is some test Message!!!";
- CHAR Buffer[32];
+ CHAR DECLSPEC_ALIGN(8) Buffer[32];
NTSTATUS Status;
- /* Size must be aligned to 8 bytes */
- Status = RtlEncryptMemory(Buffer, 7, RTL_ENCRYPT_OPTION_SAME_PROCESS);
+ /* Size must be aligned to 8 bytes (aka RTL_ENCRYPT_MEMORY_SIZE) */
+ RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
+ Status = RtlEncryptMemory(Buffer, 7, OptionFlags);
ok_ntstatus(Status, STATUS_INVALID_PARAMETER);
- /* Buffer must not be aligned to 8 bytes */
- Status = RtlEncryptMemory(&Buffer[1], 8, RTL_ENCRYPT_OPTION_SAME_PROCESS);
+ /* Buffer can be unaligned */
+ RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
+ Status = RtlEncryptMemory(&Buffer[1], 8, OptionFlags);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = RtlDecryptMemory(&Buffer[1], 8, OptionFlags);
ok_ntstatus(Status, STATUS_SUCCESS);
+ ok(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)) == 1,
+ "OptionFlags=%lu, Buffer='%s', TestData='%s'\n",
+ OptionFlags, Buffer, TestData);
RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
- Status = RtlEncryptMemory(Buffer, sizeof(Buffer), RTL_ENCRYPT_OPTION_SAME_PROCESS);
+ Status = RtlEncryptMemory(Buffer, sizeof(Buffer), OptionFlags);
ok_ntstatus(Status, STATUS_SUCCESS);
ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 0);
- Status = RtlDecryptMemory(Buffer, sizeof(Buffer), RTL_ENCRYPT_OPTION_SAME_PROCESS);
+ Status = RtlDecryptMemory(Buffer, sizeof(Buffer), OptionFlags);
ok_ntstatus(Status, STATUS_SUCCESS);
ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 1);
+}
+
+void TestCrossProcessDecrypt(PSTR Param)
+{
+ UCHAR Buffer[32] = { 0 };
+ ULONG OptionFlags;
+ PSTR StrData;
+ ULONG i;
+ NTSTATUS Status;
+
+ OptionFlags = Param[3] == '1' ? RTL_ENCRYPT_OPTION_CROSS_PROCESS :
RTL_ENCRYPT_OPTION_SAME_LOGON;
+
+ /* Convert the HEX string to binary ('-cp<1|2>:<data>') */
+ StrData = Param + 5;
+ for (i = 0; i < sizeof(Buffer); i++)
+ {
+ UINT x;
+ sscanf(&StrData[2 * i], "%02X", &x);
+ Buffer[i] = (UCHAR)x;
+ }
+
+ /* Decrypt the data */
+ Status = RtlDecryptMemory(Buffer, sizeof(Buffer), OptionFlags);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 1);
+}
+
+void TestCrossProcessEncrypt(ULONG OptionFlags)
+{
+ UCHAR Buffer[32];
+ CHAR CmdLine[MAX_PATH];
+ PSTR StrBuffer;
+ NTSTATUS Status;
+ ULONG i;
+ INT result;
+
+ /* Encrypt the test string */
+ RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
+ Status = RtlEncryptMemory(Buffer, sizeof(Buffer), OptionFlags);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ /* Start building a command line */
+ sprintf(CmdLine, "advapi32_apitest.exe RtlEncryptMemory -cp%lu:",
OptionFlags);
+ StrBuffer = CmdLine + strlen(CmdLine);
+
+ /* Convert encrypted data into a hex string */
+ for (i = 0; i < sizeof(Buffer); i++)
+ {
+ sprintf(&StrBuffer[2 * i], "%02X", Buffer[i]);
+ }
+
+ result = system(CmdLine);
+ ok_int(result, 0);
+}
+
+START_TEST(RtlEncryptMemory)
+{
+ CHAR Buffer[8] = { 0 };
+ PSTR CommandLine, Param;
+ NTSTATUS Status;
+
+ /* Check recursive call */
+ CommandLine = GetCommandLineA();
+ Param = strstr(CommandLine, "-cp");
+ if (Param != NULL)
+ {
+ TestCrossProcessDecrypt(Param);
+ return;
+ }
+
+ TestEncrypt(RTL_ENCRYPT_OPTION_SAME_PROCESS);
+ TestEncrypt(RTL_ENCRYPT_OPTION_CROSS_PROCESS);
+ TestEncrypt(RTL_ENCRYPT_OPTION_SAME_LOGON);
+
+ Status = RtlEncryptMemory(Buffer, sizeof(Buffer), 4);
+ ok_ntstatus(Status, STATUS_INVALID_PARAMETER);
+ TestCrossProcessEncrypt(RTL_ENCRYPT_OPTION_CROSS_PROCESS);
+ TestCrossProcessEncrypt(RTL_ENCRYPT_OPTION_SAME_LOGON);
}