https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ab43f8698085764deaca85...
commit ab43f8698085764deaca857c831afde40a084d35 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Sun Sep 13 19:58:06 2020 +0200 Commit: Timo Kreuzer timo.kreuzer@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); }