https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ab43f8698085764deaca857c831afde40a084d35

commit ab43f8698085764deaca857c831afde40a084d35
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sun Sep 13 19:58:06 2020 +0200
Commit:     Timo Kreuzer <[email protected]>
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);
 }

Reply via email to