1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for RtlEncrypt/DecryptMemory
5  * PROGRAMMER:      Timo Kreuzer <timo.kreuzer@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 #include <ntsecapi.h>
11 
12 static const CHAR TestData[32] = "This is some test Message!!!";
13 
14 void TestEncrypt(ULONG OptionFlags)
15 {
16     CHAR DECLSPEC_ALIGN(8) Buffer[32];
17     NTSTATUS Status;
18 
19     /* Size must be aligned to 8 bytes (aka RTL_ENCRYPT_MEMORY_SIZE) */
20     RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
21     Status = RtlEncryptMemory(Buffer, 7, OptionFlags);
22     ok_ntstatus(Status, STATUS_INVALID_PARAMETER);
23 
24     /* Buffer can be unaligned */
25     RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
26     Status = RtlEncryptMemory(&Buffer[1], 8, OptionFlags);
27     ok_ntstatus(Status, STATUS_SUCCESS);
28     Status = RtlDecryptMemory(&Buffer[1], 8, OptionFlags);
29     ok_ntstatus(Status, STATUS_SUCCESS);
30     ok(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)) == 1,
31        "OptionFlags=%lu, Buffer='%s', TestData='%s'\n",
32        OptionFlags, Buffer, TestData);
33 
34     RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
35     Status = RtlEncryptMemory(Buffer, sizeof(Buffer), OptionFlags);
36     ok_ntstatus(Status, STATUS_SUCCESS);
37     ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 0);
38     Status = RtlDecryptMemory(Buffer, sizeof(Buffer), OptionFlags);
39     ok_ntstatus(Status, STATUS_SUCCESS);
40     ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 1);
41 }
42 
43 void TestCrossProcessDecrypt(PSTR Param)
44 {
45     UCHAR Buffer[32] = { 0 };
46     ULONG OptionFlags;
47     PSTR StrData;
48     ULONG i;
49     NTSTATUS Status;
50 
51     OptionFlags = Param[3] == '1' ? RTL_ENCRYPT_OPTION_CROSS_PROCESS : RTL_ENCRYPT_OPTION_SAME_LOGON;
52 
53     /* Convert the HEX string to binary ('-cp<1|2>:<data>') */
54     StrData = Param + 5;
55     for (i = 0; i < sizeof(Buffer); i++)
56     {
57         UINT x;
58         sscanf(&StrData[2 * i], "%02X", &x);
59         Buffer[i] = (UCHAR)x;
60     }
61 
62     /* Decrypt the data */
63     Status = RtlDecryptMemory(Buffer, sizeof(Buffer), OptionFlags);
64     ok_ntstatus(Status, STATUS_SUCCESS);
65     ok_int(RtlEqualMemory(Buffer, TestData, sizeof(Buffer)), 1);
66 }
67 
68 void TestCrossProcessEncrypt(ULONG OptionFlags)
69 {
70     UCHAR Buffer[32];
71     CHAR CmdLine[MAX_PATH];
72     PSTR StrBuffer;
73     NTSTATUS Status;
74     ULONG i;
75     INT result;
76 
77     /* Encrypt the test string */
78     RtlCopyMemory(Buffer, TestData, sizeof(Buffer));
79     Status = RtlEncryptMemory(Buffer, sizeof(Buffer), OptionFlags);
80     ok_ntstatus(Status, STATUS_SUCCESS);
81 
82     /* Start building a command line */
83     sprintf(CmdLine, "advapi32_apitest.exe RtlEncryptMemory -cp%lu:", OptionFlags);
84     StrBuffer = CmdLine + strlen(CmdLine);
85 
86     /* Convert encrypted data into a hex string */
87     for (i = 0; i < sizeof(Buffer); i++)
88     {
89         sprintf(&StrBuffer[2 * i], "%02X", Buffer[i]);
90     }
91 
92     result = system(CmdLine);
93     ok_int(result, 0);
94 }
95 
96 START_TEST(RtlEncryptMemory)
97 {
98     CHAR Buffer[8] = { 0 };
99     PSTR CommandLine, Param;
100     NTSTATUS Status;
101 
102     /* Check recursive call */
103     CommandLine = GetCommandLineA();
104     Param = strstr(CommandLine, "-cp");
105     if (Param != NULL)
106     {
107         TestCrossProcessDecrypt(Param);
108         return;
109     }
110 
111     TestEncrypt(RTL_ENCRYPT_OPTION_SAME_PROCESS);
112     TestEncrypt(RTL_ENCRYPT_OPTION_CROSS_PROCESS);
113     TestEncrypt(RTL_ENCRYPT_OPTION_SAME_LOGON);
114 
115     Status = RtlEncryptMemory(Buffer, sizeof(Buffer), 4);
116     ok_ntstatus(Status, STATUS_INVALID_PARAMETER);
117 
118     TestCrossProcessEncrypt(RTL_ENCRYPT_OPTION_CROSS_PROCESS);
119     TestCrossProcessEncrypt(RTL_ENCRYPT_OPTION_SAME_LOGON);
120 }
121