ReactOS 0.4.16-dev-297-gc569aee
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 328 of file crypt.c.

332{
333 /* Validate parameter */
334 if (OptionFlags > RTL_ENCRYPT_OPTION_SAME_LOGON)
335 {
337 }
338
339 /* Check if the length is not 16 bytes aligned */
340 if (Length & 15)
341 {
342 /* Is it at least 8 bytes aligned? */
343 if (Length & 7)
344 {
345 /* No, we can't deal with it! */
347 }
348
349 /* Use triple DES encryption */
350 KsecDecryptMemoryDes3(Buffer, Length, OptionFlags);
351 }
352 else
353 {
354 /* Use AES encryption */
355 KsecDecryptMemoryAes(Buffer, Length, OptionFlags);
356 }
357
358 return STATUS_SUCCESS;
359}
Definition: bufpool.h:45
static VOID KsecDecryptMemoryAes(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:267
static VOID KsecDecryptMemoryDes3(_Inout_ PVOID Buffer, _In_ ULONG Length, _In_ ULONG OptionFlags)
Definition: crypt.c:215
#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 267 of file crypt.c.

271{
272 UCHAR BlockData[16];
273 AES_KEY AesKey;
274
275 /* Get they AES key */
276 KsecGetAesKey(&AesKey, OptionFlags);
277
278 /* Do the AES decryption */
279 while (Length >= sizeof(BlockData))
280 {
281 aes_ecb_decrypt(Buffer, BlockData, &AesKey);
282 RtlCopyMemory(Buffer, BlockData, sizeof(BlockData));
283 Buffer = (PUCHAR)Buffer + sizeof(BlockData);
284 Length -= sizeof(BlockData);
285 }
286
287 /* Erase the key data */
288 RtlSecureZeroMemory(&AesKey, sizeof(AesKey));
289}
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:164
#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
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by KsecDecryptMemory().

◆ KsecDecryptMemoryDes3()

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

Definition at line 215 of file crypt.c.

219{
220 UCHAR BlockData[8];
221 DES3_KEY Des3Key;
222
223 /* Get they triple DES key */
224 KsecGetDes3Key(&Des3Key, OptionFlags);
225
226 /* Do the triple DES decryption */
227 while (Length >= sizeof(BlockData))
228 {
229 des3_ecb_decrypt(Buffer, BlockData, &Des3Key);
230 RtlCopyMemory(Buffer, BlockData, sizeof(BlockData));
231 Buffer = (PUCHAR)Buffer + sizeof(BlockData);
232 Length -= sizeof(BlockData);
233 }
234
235 /* Erase the key data */
236 RtlSecureZeroMemory(&Des3Key, sizeof(Des3Key));
237}
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:139

Referenced by KsecDecryptMemory().

◆ KsecEncryptMemory()

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

Definition at line 293 of file crypt.c.

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

Referenced by KsecDeviceControl().

◆ KsecEncryptMemoryAes()

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

Definition at line 241 of file crypt.c.

245{
246 UCHAR EncryptedBlockData[16];
247 AES_KEY AesKey;
248
249 /* Get they AES key */
250 KsecGetAesKey(&AesKey, OptionFlags);
251
252 /* Do the AES encryption */
253 while (Length >= sizeof(EncryptedBlockData))
254 {
255 aes_ecb_encrypt(Buffer, EncryptedBlockData, &AesKey);
256 RtlCopyMemory(Buffer, EncryptedBlockData, sizeof(EncryptedBlockData));
257 Buffer = (PUCHAR)Buffer + sizeof(EncryptedBlockData);
258 Length -= sizeof(EncryptedBlockData);
259 }
260
261 /* Erase the key data */
262 RtlSecureZeroMemory(&AesKey, sizeof(AesKey));
263}
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 189 of file crypt.c.

193{
194 UCHAR EncryptedBlockData[8];
195 DES3_KEY Des3Key;
196
197 /* Get they triple DES key */
198 KsecGetDes3Key(&Des3Key, OptionFlags);
199
200 /* Do the triple DES encryption */
201 while (Length >= sizeof(EncryptedBlockData))
202 {
203 des3_ecb_encrypt(Buffer, EncryptedBlockData, &Des3Key);
204 RtlCopyMemory(Buffer, EncryptedBlockData, sizeof(EncryptedBlockData));
205 Buffer = (PUCHAR)Buffer + sizeof(EncryptedBlockData);
206 Length -= sizeof(EncryptedBlockData);
207 }
208
209 /* Erase the key data */
210 RtlSecureZeroMemory(&Des3Key, sizeof(Des3Key));
211}
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 164 of file crypt.c.

167{
168 UCHAR KeyDataBuffer[32];
169
170 /* Check if the caller allows cross process encryption */
171 if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
172 {
173 /* Return our global cached AES key */
174 *AesKey = KsecGlobalAesKey;
175 }
176 else
177 {
178 /* Setup the key */
179 KsecGetKeyData(KeyDataBuffer, OptionFlags);
180 aes_setup(KeyDataBuffer, 32, 0, AesKey);
181
182 /* Erase the temp data */
183 RtlSecureZeroMemory(KeyDataBuffer, sizeof(KeyDataBuffer));
184 }
185}
int aes_setup(const unsigned char *key, int keylen, int rounds, aes_key *skey)
Definition: aes.c:937
AES_KEY KsecGlobalAesKey
Definition: crypt.c:15
static VOID KsecGetKeyData(_Out_ UCHAR KeyData[32], _In_ ULONG OptionFlags)
Definition: crypt.c:76
#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 139 of file crypt.c.

142{
143 UCHAR KeyDataBuffer[32];
144
145 /* Check if the caller allows cross process encryption */
146 if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
147 {
148 /* Return our global cached DES3 key */
149 *Des3Key = KsecGlobalDes3Key;
150 }
151 else
152 {
153 /* Setup the key */
154 KsecGetKeyData(KeyDataBuffer, OptionFlags);
155 des3_setup(KeyDataBuffer, 24, 0, Des3Key);
156
157 /* Erase the temp data */
158 RtlSecureZeroMemory(KeyDataBuffer, sizeof(KeyDataBuffer));
159 }
160}
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:14

Referenced by KsecDecryptMemoryDes3(), and KsecEncryptMemoryDes3().

◆ KsecGetKeyData()

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

Definition at line 76 of file crypt.c.

79{
80 MD5_CTX Md5Contexts[2];
81 KSEC_PROCESS_DATA ProcessData;
82 KSEC_LOGON_DATA LogonData;
83 PEPROCESS CurrentProcess;
85
86 /* We need to generate the key, start with our load MD5s */
87 Md5Contexts[0] = KsecLoadTimeStartMd5s[0];
88 Md5Contexts[1] = KsecLoadTimeStartMd5s[1];
89
90 /* Get the current process */
91 CurrentProcess = PsGetCurrentProcess();
92
93 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
94 {
95 /* Hash some process specific data to generate the key */
96 RtlZeroMemory(&ProcessData, sizeof(ProcessData));
97 ProcessData.Process = CurrentProcess;
98 ProcessData.ProcessId = CurrentProcess->UniqueProcessId;
99 ProcessData.CreateTime = PsGetProcessCreateTimeQuadPart(CurrentProcess);
100 ProcessData.DirectoryTableBase = CurrentProcess->Pcb.DirectoryTableBase[0];
101 MD5Update(&Md5Contexts[0], (PVOID)&ProcessData, sizeof(ProcessData));
102 MD5Update(&Md5Contexts[1], (PVOID)&ProcessData, sizeof(ProcessData));
103 }
104 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
105 {
106 /* Hash the logon id to generate the key */
107 RtlZeroMemory(&LogonData, sizeof(LogonData));
108 Token = PsReferencePrimaryToken(CurrentProcess);
111 MD5Update(&Md5Contexts[0], (PVOID)&LogonData, sizeof(LogonData));
112 MD5Update(&Md5Contexts[1], (PVOID)&LogonData, sizeof(LogonData));
113 }
114 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
115 {
116 /* Use the original MD5s to generate the global key */
117 NOTHING;
118 }
119 else
120 {
121 /* Must not pass anything else */
122 ASSERT(FALSE);
123 }
124
125 /* Finalize the MD5s */
126 MD5Final(&Md5Contexts[0]);
127 MD5Final(&Md5Contexts[1]);
128
129 /* Copy the md5 data */
130 RtlCopyMemory(KeyData, &Md5Contexts[0].digest, 16);
131 RtlCopyMemory((PUCHAR)KeyData + 16, &Md5Contexts[1].digest, 16);
132
133 /* Erase the temp data */
134 RtlSecureZeroMemory(&Md5Contexts, sizeof(Md5Contexts));
135}
#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:13
#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:2036
KPROCESS Pcb
Definition: pstypes.h:1263
HANDLE UniqueProcessId
Definition: pstypes.h:1268
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:2087
LUID LogonId
Definition: crypt.c:27
ULONG_PTR DirectoryTableBase
Definition: crypt.c:22
HANDLE ProcessId
Definition: crypt.c:20
PEPROCESS Process
Definition: crypt.c:19
LONGLONG CreateTime
Definition: crypt.c:21
#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 44 of file crypt.c.

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

Referenced by DriverEntry().

Variable Documentation

◆ KsecGlobalAesKey

AES_KEY KsecGlobalAesKey

Definition at line 15 of file crypt.c.

Referenced by KsecGetAesKey(), and KsecInitializeEncryptionSupport().

◆ KsecGlobalDes3Key

DES3_KEY KsecGlobalDes3Key

Definition at line 14 of file crypt.c.

Referenced by KsecGetDes3Key(), and KsecInitializeEncryptionSupport().

◆ KsecLoadTimeStartMd5s

MD5_CTX KsecLoadTimeStartMd5s[2]

Definition at line 13 of file crypt.c.

Referenced by KsecGetKeyData(), and KsecInitializeEncryptionSupport().