ReactOS 0.4.17-dev-116-ga4b6fe9
crypt.c File Reference
#include "ksecdd.h"
Include dependency graph for crypt.c:

Go to the source code of this file.

Classes

struct  _KSEC_PROCESS_DATA
 
struct  _KSEC_LOGON_DATA
 

Typedefs

typedef struct _KSEC_PROCESS_DATA KSEC_PROCESS_DATA
 
typedef struct _KSEC_PROCESS_DATAPKSEC_PROCESS_DATA
 
typedef struct _KSEC_LOGON_DATA KSEC_LOGON_DATA
 
typedef struct _KSEC_LOGON_DATAPKSEC_LOGON_DATA
 

Functions

VOID NTAPI KsecInitializeEncryptionSupport (VOID)
 
static VOID KsecGetKeyData (_Out_ UCHAR KeyData[32], _In_ ULONG OptionFlags)
 
static VOID KsecGetDes3Key (_Out_ PDES3_KEY Des3Key, _In_ ULONG OptionFlags)
 
static VOID KsecGetAesKey (_Out_ PAES_KEY AesKey, _In_ ULONG OptionFlags)
 
static VOID KsecEncryptMemoryDes3 (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 
static VOID KsecDecryptMemoryDes3 (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 
static VOID KsecEncryptMemoryAes (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 
static VOID KsecDecryptMemoryAes (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 
NTSTATUS NTAPI KsecEncryptMemory (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 
NTSTATUS NTAPI KsecDecryptMemory (_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
 

Variables

MD5_CTX KsecLoadTimeStartMd5s [2]
 
DES3_KEY KsecGlobalDes3Key
 
AES_KEY KsecGlobalAesKey
 

Typedef Documentation

◆ KSEC_LOGON_DATA

◆ KSEC_PROCESS_DATA

◆ PKSEC_LOGON_DATA

◆ PKSEC_PROCESS_DATA

Function Documentation

◆ KsecDecryptMemory()

NTSTATUS NTAPI KsecDecryptMemory ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)

Definition at line 327 of file crypt.c.

331{
332 /* Validate parameter */
333 if (OptionFlags > RTL_ENCRYPT_OPTION_SAME_LOGON)
334 {
336 }
337
338 /* Check if the length is not 16 bytes aligned */
339 if (Length & 15)
340 {
341 /* Is it at least 8 bytes aligned? */
342 if (Length & 7)
343 {
344 /* No, we can't deal with it! */
346 }
347
348 /* Use triple DES encryption */
349 KsecDecryptMemoryDes3(Buffer, Length, OptionFlags);
350 }
351 else
352 {
353 /* Use AES encryption */
354 KsecDecryptMemoryAes(Buffer, Length, OptionFlags);
355 }
356
357 return STATUS_SUCCESS;
358}
Definition: bufpool.h:45
static VOID KsecDecryptMemoryAes(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:266
static VOID KsecDecryptMemoryDes3(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:214
#define RTL_ENCRYPT_OPTION_SAME_LOGON
Definition: ksecdd.h:27
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by KsecDeviceControl().

◆ KsecDecryptMemoryAes()

static VOID KsecDecryptMemoryAes ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)
static

Definition at line 266 of file crypt.c.

270{
271 UCHAR BlockData[16];
272 AES_KEY AesKey;
273
274 /* Get they AES key */
275 KsecGetAesKey(&AesKey, OptionFlags);
276
277 /* Do the AES decryption */
278 while (Length >= sizeof(BlockData))
279 {
280 aes_ecb_decrypt(Buffer, BlockData, &AesKey);
281 RtlCopyMemory(Buffer, BlockData, sizeof(BlockData));
282 Buffer = (PUCHAR)Buffer + sizeof(BlockData);
283 Length -= sizeof(BlockData);
284 }
285
286 /* Erase the key data */
287 RtlSecureZeroMemory(&AesKey, sizeof(AesKey));
288}
void aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, aes_key *skey)
Definition: aes.c:1165
static VOID KsecGetAesKey(_Out_ PAES_KEY AesKey, _In_ ULONG OptionFlags)
Definition: crypt.c:163
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
FORCEINLINE PVOID RtlSecureZeroMemory(_Out_writes_bytes_all_(Size) PVOID Pointer, _In_ SIZE_T Size)
Definition: rtlfuncs.h:3142

Referenced by KsecDecryptMemory().

◆ KsecDecryptMemoryDes3()

static VOID KsecDecryptMemoryDes3 ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)
static

Definition at line 214 of file crypt.c.

218{
219 UCHAR BlockData[8];
220 DES3_KEY Des3Key;
221
222 /* Get they triple DES key */
223 KsecGetDes3Key(&Des3Key, OptionFlags);
224
225 /* Do the triple DES decryption */
226 while (Length >= sizeof(BlockData))
227 {
228 des3_ecb_decrypt(Buffer, BlockData, &Des3Key);
229 RtlCopyMemory(Buffer, BlockData, sizeof(BlockData));
230 Buffer = (PUCHAR)Buffer + sizeof(BlockData);
231 Length -= sizeof(BlockData);
232 }
233
234 /* Erase the key data */
235 RtlSecureZeroMemory(&Des3Key, sizeof(Des3Key));
236}
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const des3_key *des3)
Definition: des.c:1485
static VOID KsecGetDes3Key(_Out_ PDES3_KEY Des3Key, _In_ ULONG OptionFlags)
Definition: crypt.c:138

Referenced by KsecDecryptMemory().

◆ KsecEncryptMemory()

NTSTATUS NTAPI KsecEncryptMemory ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)

Definition at line 292 of file crypt.c.

296{
297 /* Validate parameter */
298 if (OptionFlags > RTL_ENCRYPT_OPTION_SAME_LOGON)
299 {
301 }
302
303 /* Check if the length is not 16 bytes aligned */
304 if (Length & 15)
305 {
306 /* Is it at least 8 bytes aligned? */
307 if (Length & 7)
308 {
309 /* No, we can't deal with it! */
311 }
312
313 /* Use triple DES encryption */
314 KsecEncryptMemoryDes3(Buffer, Length, OptionFlags);
315 }
316 else
317 {
318 /* Use AES encryption */
319 KsecEncryptMemoryAes(Buffer, Length, OptionFlags);
320 }
321
322 return STATUS_SUCCESS;
323}
static VOID KsecEncryptMemoryDes3(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:188
static VOID KsecEncryptMemoryAes(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:240

Referenced by KsecDeviceControl().

◆ KsecEncryptMemoryAes()

static VOID KsecEncryptMemoryAes ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)
static

Definition at line 240 of file crypt.c.

244{
245 UCHAR EncryptedBlockData[16];
246 AES_KEY AesKey;
247
248 /* Get they AES key */
249 KsecGetAesKey(&AesKey, OptionFlags);
250
251 /* Do the AES encryption */
252 while (Length >= sizeof(EncryptedBlockData))
253 {
254 aes_ecb_encrypt(Buffer, EncryptedBlockData, &AesKey);
255 RtlCopyMemory(Buffer, EncryptedBlockData, sizeof(EncryptedBlockData));
256 Buffer = (PUCHAR)Buffer + sizeof(EncryptedBlockData);
257 Length -= sizeof(EncryptedBlockData);
258 }
259
260 /* Erase the key data */
261 RtlSecureZeroMemory(&AesKey, sizeof(AesKey));
262}
void aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, aes_key *skey)
Definition: aes.c:1064

Referenced by KsecEncryptMemory().

◆ KsecEncryptMemoryDes3()

static VOID KsecEncryptMemoryDes3 ( _Inout_ PVOID  Buffer,
_In_ ULONG  Length,
_In_ ULONG  OptionFlags 
)
static

Definition at line 188 of file crypt.c.

192{
193 UCHAR EncryptedBlockData[8];
194 DES3_KEY Des3Key;
195
196 /* Get they triple DES key */
197 KsecGetDes3Key(&Des3Key, OptionFlags);
198
199 /* Do the triple DES encryption */
200 while (Length >= sizeof(EncryptedBlockData))
201 {
202 des3_ecb_encrypt(Buffer, EncryptedBlockData, &Des3Key);
203 RtlCopyMemory(Buffer, EncryptedBlockData, sizeof(EncryptedBlockData));
204 Buffer = (PUCHAR)Buffer + sizeof(EncryptedBlockData);
205 Length -= sizeof(EncryptedBlockData);
206 }
207
208 /* Erase the key data */
209 RtlSecureZeroMemory(&Des3Key, sizeof(Des3Key));
210}
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const des3_key *des3)
Definition: des.c:1473

Referenced by KsecEncryptMemory().

◆ KsecGetAesKey()

static VOID KsecGetAesKey ( _Out_ PAES_KEY  AesKey,
_In_ ULONG  OptionFlags 
)
static

Definition at line 163 of file crypt.c.

166{
167 UCHAR KeyDataBuffer[32];
168
169 /* Check if the caller allows cross process encryption */
170 if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
171 {
172 /* Return our global cached AES key */
173 *AesKey = KsecGlobalAesKey;
174 }
175 else
176 {
177 /* Setup the key */
178 KsecGetKeyData(KeyDataBuffer, OptionFlags);
179 aes_setup(KeyDataBuffer, 32, 0, AesKey);
180
181 /* Erase the temp data */
182 RtlSecureZeroMemory(KeyDataBuffer, sizeof(KeyDataBuffer));
183 }
184}
int aes_setup(const unsigned char *key, int keylen, int rounds, aes_key *skey)
Definition: aes.c:937
AES_KEY KsecGlobalAesKey
Definition: crypt.c:14
static VOID KsecGetKeyData(_Out_ UCHAR KeyData[32], _In_ ULONG OptionFlags)
Definition: crypt.c:75
#define RTL_ENCRYPT_OPTION_CROSS_PROCESS
Definition: ksecdd.h:26

Referenced by KsecDecryptMemoryAes(), and KsecEncryptMemoryAes().

◆ KsecGetDes3Key()

static VOID KsecGetDes3Key ( _Out_ PDES3_KEY  Des3Key,
_In_ ULONG  OptionFlags 
)
static

Definition at line 138 of file crypt.c.

141{
142 UCHAR KeyDataBuffer[32];
143
144 /* Check if the caller allows cross process encryption */
145 if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
146 {
147 /* Return our global cached DES3 key */
148 *Des3Key = KsecGlobalDes3Key;
149 }
150 else
151 {
152 /* Setup the key */
153 KsecGetKeyData(KeyDataBuffer, OptionFlags);
154 des3_setup(KeyDataBuffer, 24, 0, Des3Key);
155
156 /* Erase the temp data */
157 RtlSecureZeroMemory(KeyDataBuffer, sizeof(KeyDataBuffer));
158 }
159}
int des3_setup(const unsigned char *key, int keylen, int num_rounds, des3_key *des3)
Definition: des.c:1432
DES3_KEY KsecGlobalDes3Key
Definition: crypt.c:13

Referenced by KsecDecryptMemoryDes3(), and KsecEncryptMemoryDes3().

◆ KsecGetKeyData()

static VOID KsecGetKeyData ( _Out_ UCHAR  KeyData[32],
_In_ ULONG  OptionFlags 
)
static

Definition at line 75 of file crypt.c.

78{
79 MD5_CTX Md5Contexts[2];
80 KSEC_PROCESS_DATA ProcessData;
81 KSEC_LOGON_DATA LogonData;
82 PEPROCESS CurrentProcess;
84
85 /* We need to generate the key, start with our load MD5s */
86 Md5Contexts[0] = KsecLoadTimeStartMd5s[0];
87 Md5Contexts[1] = KsecLoadTimeStartMd5s[1];
88
89 /* Get the current process */
90 CurrentProcess = PsGetCurrentProcess();
91
92 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
93 {
94 /* Hash some process specific data to generate the key */
95 RtlZeroMemory(&ProcessData, sizeof(ProcessData));
96 ProcessData.Process = CurrentProcess;
97 ProcessData.ProcessId = CurrentProcess->UniqueProcessId;
98 ProcessData.CreateTime = PsGetProcessCreateTimeQuadPart(CurrentProcess);
99 ProcessData.DirectoryTableBase = CurrentProcess->Pcb.DirectoryTableBase[0];
100 MD5Update(&Md5Contexts[0], (PVOID)&ProcessData, sizeof(ProcessData));
101 MD5Update(&Md5Contexts[1], (PVOID)&ProcessData, sizeof(ProcessData));
102 }
103 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
104 {
105 /* Hash the logon id to generate the key */
106 RtlZeroMemory(&LogonData, sizeof(LogonData));
107 Token = PsReferencePrimaryToken(CurrentProcess);
110 MD5Update(&Md5Contexts[0], (PVOID)&LogonData, sizeof(LogonData));
111 MD5Update(&Md5Contexts[1], (PVOID)&LogonData, sizeof(LogonData));
112 }
113 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
114 {
115 /* Use the original MD5s to generate the global key */
116 NOTHING;
117 }
118 else
119 {
120 /* Must not pass anything else */
121 ASSERT(FALSE);
122 }
123
124 /* Finalize the MD5s */
125 MD5Final(&Md5Contexts[0]);
126 MD5Final(&Md5Contexts[1]);
127
128 /* Copy the md5 data */
129 RtlCopyMemory(KeyData, &Md5Contexts[0].digest, 16);
130 RtlCopyMemory((PUCHAR)KeyData + 16, &Md5Contexts[1].digest, 16);
131
132 /* Erase the temp data */
133 RtlSecureZeroMemory(&Md5Contexts, sizeof(Md5Contexts));
134}
#define FALSE
Definition: types.h:117
void WINAPI MD5Update(struct md5_ctx *, const unsigned char *, unsigned int)
void WINAPI MD5Final(struct md5_ctx *)
MD5_CTX KsecLoadTimeStartMd5s[2]
Definition: crypt.c:12
#define NOTHING
Definition: input_list.c:10
#define RTL_ENCRYPT_OPTION_SAME_PROCESS
Definition: ksecdd.h:25
#define ASSERT(a)
Definition: mode.c:44
#define PsDereferencePrimaryToken(T)
Definition: imports.h:301
LONGLONG NTAPI PsGetProcessCreateTimeQuadPart(PEPROCESS Process)
Definition: process.c:1023
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2037
KPROCESS Pcb
Definition: pstypes.h:1351
HANDLE UniqueProcessId
Definition: pstypes.h:1356
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:2215
LUID LogonId
Definition: crypt.c:26
ULONG_PTR DirectoryTableBase
Definition: crypt.c:21
HANDLE ProcessId
Definition: crypt.c:19
PEPROCESS Process
Definition: crypt.c:18
LONGLONG CreateTime
Definition: crypt.c:20
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by KsecGetAesKey(), and KsecGetDes3Key().

◆ KsecInitializeEncryptionSupport()

VOID NTAPI KsecInitializeEncryptionSupport ( VOID  )

Definition at line 43 of file crypt.c.

45{
46 KSEC_ENTROPY_DATA EntropyData;
47 MD5_CTX Md5Context;
48 UCHAR KeyDataBuffer[32];
49
50 KsecGatherEntropyData(&EntropyData);
51 MD5Init(&Md5Context);
52 MD5Update(&Md5Context, (PVOID)&EntropyData, sizeof(EntropyData));
53 KsecLoadTimeStartMd5s[0] = Md5Context;
54 MD5Final(&Md5Context);
55 RtlCopyMemory(KeyDataBuffer, &Md5Context.digest, 16);
56
57 KsecGatherEntropyData(&EntropyData);
58 Md5Context = KsecLoadTimeStartMd5s[0];
59 MD5Update(&Md5Context, (PVOID)&EntropyData, sizeof(EntropyData));
60 KsecLoadTimeStartMd5s[1] = Md5Context;
61 MD5Final(&Md5Context);
62 RtlCopyMemory(&KeyDataBuffer[16], &Md5Context.digest, 16);
63
64 /* Create the global keys */
65 aes_setup(KeyDataBuffer, 32, 0, &KsecGlobalAesKey);
66 des3_setup(KeyDataBuffer, 24, 0, &KsecGlobalDes3Key);
67
68 /* Erase the temp data */
69 RtlSecureZeroMemory(KeyDataBuffer, sizeof(KeyDataBuffer));
70 RtlSecureZeroMemory(&Md5Context, sizeof(Md5Context));
71}
void WINAPI MD5Init(struct md5_ctx *)
NTSTATUS NTAPI KsecGatherEntropyData(PKSEC_ENTROPY_DATA EntropyData)
Definition: random.c:91
unsigned char digest[16]
Definition: hmac_md5.h:32

Referenced by DriverEntry().

Variable Documentation

◆ KsecGlobalAesKey

AES_KEY KsecGlobalAesKey

Definition at line 14 of file crypt.c.

Referenced by KsecGetAesKey(), and KsecInitializeEncryptionSupport().

◆ KsecGlobalDes3Key

DES3_KEY KsecGlobalDes3Key

Definition at line 13 of file crypt.c.

Referenced by KsecGetDes3Key(), and KsecInitializeEncryptionSupport().

◆ KsecLoadTimeStartMd5s

MD5_CTX KsecLoadTimeStartMd5s[2]

Definition at line 12 of file crypt.c.

Referenced by KsecGetKeyData(), and KsecInitializeEncryptionSupport().