2 * PROJECT: ReactOS Drivers
3 * COPYRIGHT: See COPYING in the top level directory
4 * PURPOSE: Kernel Security Support Provider Interface Driver
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
9 /* INCLUDES *******************************************************************/
13 MD5_CTX KsecLoadTimeStartMd5s
[2];
14 DES3_KEY KsecGlobalDes3Key
;
15 AES_KEY KsecGlobalAesKey
;
17 typedef struct _KSEC_PROCESS_DATA
22 ULONG_PTR DirectoryTableBase
;
23 } KSEC_PROCESS_DATA
, *PKSEC_PROCESS_DATA
;
25 typedef struct _KSEC_LOGON_DATA
28 } KSEC_LOGON_DATA
, *PKSEC_LOGON_DATA
;
32 KsecInitializeEncryptionSupport (
35 KSEC_ENTROPY_DATA EntropyData
;
37 UCHAR KeyDataBuffer
[32];
39 KsecGatherEntropyData(&EntropyData
);
41 MD5Update(&Md5Context
, (PVOID
)&EntropyData
, sizeof(EntropyData
));
42 KsecLoadTimeStartMd5s
[0] = Md5Context
;
43 MD5Final(&Md5Context
);
44 RtlCopyMemory(KeyDataBuffer
, &Md5Context
.digest
, 16);
46 KsecGatherEntropyData(&EntropyData
);
47 Md5Context
= KsecLoadTimeStartMd5s
[0];
48 MD5Update(&Md5Context
, (PVOID
)&EntropyData
, sizeof(EntropyData
));
49 KsecLoadTimeStartMd5s
[1] = Md5Context
;
50 MD5Final(&Md5Context
);
51 RtlCopyMemory(&KeyDataBuffer
[16], &Md5Context
.digest
, 16);
53 /* Create the global keys */
54 aes_setup(KeyDataBuffer
, 32, 0, &KsecGlobalAesKey
);
55 des3_setup(KeyDataBuffer
, 24, 0, &KsecGlobalDes3Key
);
57 /* Erase the temp data */
58 RtlSecureZeroMemory(KeyDataBuffer
, sizeof(KeyDataBuffer
));
59 RtlSecureZeroMemory(&Md5Context
, sizeof(Md5Context
));
65 _Out_ UCHAR KeyData
[32],
66 _In_ ULONG OptionFlags
)
68 MD5_CTX Md5Contexts
[2];
69 KSEC_PROCESS_DATA ProcessData
;
70 KSEC_LOGON_DATA LogonData
;
71 PEPROCESS CurrentProcess
;
74 /* We need to generate the key, start with our load MD5s */
75 Md5Contexts
[0] = KsecLoadTimeStartMd5s
[0];
76 Md5Contexts
[1] = KsecLoadTimeStartMd5s
[1];
78 /* Get the current process */
79 CurrentProcess
= PsGetCurrentProcess();
81 if (OptionFlags
== RTL_ENCRYPT_OPTION_SAME_PROCESS
)
83 ProcessData
.Process
= CurrentProcess
;
84 ProcessData
.ProcessId
= CurrentProcess
->UniqueProcessId
;
85 ProcessData
.CreateTime
= PsGetProcessCreateTimeQuadPart(CurrentProcess
);
86 ProcessData
.DirectoryTableBase
= CurrentProcess
->Pcb
.DirectoryTableBase
[0];
87 MD5Update(&Md5Contexts
[0], (PVOID
)&ProcessData
, sizeof(ProcessData
));
88 MD5Update(&Md5Contexts
[1], (PVOID
)&ProcessData
, sizeof(ProcessData
));
90 else // if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
92 Token
= PsReferencePrimaryToken(CurrentProcess
);
93 SeQueryAuthenticationIdToken(Token
, &LogonData
.LogonId
);
94 PsDereferencePrimaryToken(Token
);
95 MD5Update(&Md5Contexts
[0], (PVOID
)&LogonData
, sizeof(LogonData
));
96 MD5Update(&Md5Contexts
[1], (PVOID
)&LogonData
, sizeof(LogonData
));
99 /* Finalize the MD5s */
100 MD5Final(&Md5Contexts
[0]);
101 MD5Final(&Md5Contexts
[1]);
103 /* Copy the md5 data */
104 RtlCopyMemory(KeyData
, &Md5Contexts
[0].digest
, 16);
105 RtlCopyMemory((PUCHAR
)KeyData
+ 16, &Md5Contexts
[1].digest
, 16);
107 /* Erase the temp data */
108 RtlSecureZeroMemory(&Md5Contexts
, sizeof(Md5Contexts
));
114 _Out_ PDES3_KEY Des3Key
,
115 _In_ ULONG OptionFlags
)
117 UCHAR KeyDataBuffer
[32];
119 /* Check if the caller allows cross process encryption */
120 if (OptionFlags
== RTL_ENCRYPT_OPTION_CROSS_PROCESS
)
122 /* Return our global cached DES3 key */
123 *Des3Key
= KsecGlobalDes3Key
;
128 KsecGetKeyData(KeyDataBuffer
, OptionFlags
);
129 des3_setup(KeyDataBuffer
, 24, 0, Des3Key
);
131 /* Erase the temp data */
132 RtlSecureZeroMemory(KeyDataBuffer
, sizeof(KeyDataBuffer
));
139 _Out_ PAES_KEY AesKey
,
140 _In_ ULONG OptionFlags
)
142 UCHAR KeyDataBuffer
[32];
144 /* Check if the caller allows cross process encryption */
145 if (OptionFlags
== RTL_ENCRYPT_OPTION_CROSS_PROCESS
)
147 /* Return our global cached AES key */
148 *AesKey
= KsecGlobalAesKey
;
153 KsecGetKeyData(KeyDataBuffer
, OptionFlags
);
154 aes_setup(KeyDataBuffer
, 32, 0, AesKey
);
156 /* Erase the temp data */
157 RtlSecureZeroMemory(KeyDataBuffer
, sizeof(KeyDataBuffer
));
163 KsecEncryptMemoryDes3 (
164 _Inout_ PVOID Buffer
,
166 _In_ ULONG OptionFlags
)
168 UCHAR EncryptedBlockData
[8];
171 /* Get they triple DES key */
172 KsecGetDes3Key(&Des3Key
, OptionFlags
);
174 /* Do the triple DES encryption */
175 while (Length
>= sizeof(EncryptedBlockData
))
177 des3_ecb_encrypt(Buffer
, EncryptedBlockData
, &Des3Key
);
178 RtlCopyMemory(Buffer
, EncryptedBlockData
, sizeof(EncryptedBlockData
));
179 Buffer
= (PUCHAR
)Buffer
+ sizeof(EncryptedBlockData
);
180 Length
-= sizeof(EncryptedBlockData
);
183 /* Erase the key data */
184 RtlSecureZeroMemory(&Des3Key
, sizeof(Des3Key
));
189 KsecDecryptMemoryDes3 (
190 _Inout_ PVOID Buffer
,
192 _In_ ULONG OptionFlags
)
197 /* Get they triple DES key */
198 KsecGetDes3Key(&Des3Key
, OptionFlags
);
200 /* Do the triple DES decryption */
201 while (Length
>= sizeof(BlockData
))
203 des3_ecb_decrypt(Buffer
, BlockData
, &Des3Key
);
204 RtlCopyMemory(Buffer
, BlockData
, sizeof(BlockData
));
205 Buffer
= (PUCHAR
)Buffer
+ sizeof(BlockData
);
206 Length
-= sizeof(BlockData
);
209 /* Erase the key data */
210 RtlSecureZeroMemory(&Des3Key
, sizeof(Des3Key
));
215 KsecEncryptMemoryAes (
216 _Inout_ PVOID Buffer
,
218 _In_ ULONG OptionFlags
)
220 UCHAR EncryptedBlockData
[16];
223 /* Get they AES key */
224 KsecGetAesKey(&AesKey
, OptionFlags
);
226 /* Do the AES encryption */
227 while (Length
>= sizeof(EncryptedBlockData
))
229 aes_ecb_encrypt(Buffer
, EncryptedBlockData
, &AesKey
);
230 RtlCopyMemory(Buffer
, EncryptedBlockData
, sizeof(EncryptedBlockData
));
231 Buffer
= (PUCHAR
)Buffer
+ sizeof(EncryptedBlockData
);
232 Length
-= sizeof(EncryptedBlockData
);
235 /* Erase the key data */
236 RtlSecureZeroMemory(&AesKey
, sizeof(AesKey
));
241 KsecDecryptMemoryAes (
242 _Inout_ PVOID Buffer
,
244 _In_ ULONG OptionFlags
)
249 /* Get they AES key */
250 KsecGetAesKey(&AesKey
, OptionFlags
);
252 /* Do the AES decryption */
253 while (Length
>= sizeof(BlockData
))
255 aes_ecb_decrypt(Buffer
, BlockData
, &AesKey
);
256 RtlCopyMemory(Buffer
, BlockData
, sizeof(BlockData
));
257 Buffer
= (PUCHAR
)Buffer
+ sizeof(BlockData
);
258 Length
-= sizeof(BlockData
);
261 /* Erase the key data */
262 RtlSecureZeroMemory(&AesKey
, sizeof(AesKey
));
268 _Inout_ PVOID Buffer
,
270 _In_ ULONG OptionFlags
)
272 /* Validate parameter */
273 if (OptionFlags
> RTL_ENCRYPT_OPTION_SAME_LOGON
)
275 return STATUS_INVALID_PARAMETER
;
278 /* Check if the length is not 16 bytes aligned */
281 /* Is it at least 8 bytes aligned? */
284 /* No, we can't deal with it! */
285 return STATUS_INVALID_PARAMETER
;
288 /* Use triple DES encryption */
289 KsecEncryptMemoryDes3(Buffer
, Length
, OptionFlags
);
293 /* Use AES encryption */
294 KsecEncryptMemoryAes(Buffer
, Length
, OptionFlags
);
297 return STATUS_SUCCESS
;
303 _Inout_ PVOID Buffer
,
305 _In_ ULONG OptionFlags
)
307 /* Validate parameter */
308 if (OptionFlags
> RTL_ENCRYPT_OPTION_SAME_LOGON
)
310 return STATUS_INVALID_PARAMETER
;
313 /* Check if the length is not 16 bytes aligned */
316 /* Is it at least 8 bytes aligned? */
319 /* No, we can't deal with it! */
320 return STATUS_INVALID_PARAMETER
;
323 /* Use triple DES encryption */
324 KsecDecryptMemoryDes3(Buffer
, Length
, OptionFlags
);
328 /* Use AES encryption */
329 KsecDecryptMemoryAes(Buffer
, Length
, OptionFlags
);
332 return STATUS_SUCCESS
;