1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/advapi32/misc/sysfunc.c
5 * PURPOSE: advapi32.dll system functions (undocumented)
6 * PROGRAMMER: Emanuele Aliberti
7 * UPDATE HISTORY:
8 * 19990413 EA created
9 * 19990415 EA
10 * 20080424 Ported from WINE
11 */
12
13 #include <advapi32.h>
14 #include <ntsecapi.h>
15 #include <ksecioctl.h>
16 #include <md4.h>
17 #include <md5.h>
18 #include <rc4.h>
19
20 static const unsigned char CRYPT_LMhash_Magic[8] =
21 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
22 static const unsigned char DefaultSessionKey[16] =
23 {'D', 'e', 'f', 'S', 'e', 's', 's', 'i', 'o', 'n', 'K', 'e', 'y', '!', '@', '#'};
24
25 /******************************************************************************
26 * SystemFunction001 [ADVAPI32.@]
27 *
28 * Encrypts a single block of data using DES
29 *
30 * PARAMS
31 * data [I] data to encrypt (8 bytes)
32 * key [I] key data (7 bytes)
33 * output [O] the encrypted data (8 bytes)
34 *
35 * RETURNS
36 * Success: STATUS_SUCCESS
37 * Failure: STATUS_UNSUCCESSFUL
38 *
39 */
40 NTSTATUS
SystemFunction001(const BYTE * data,const BYTE * key,LPBYTE output)41 WINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output)
42 {
43 if (!data || !output)
44 return STATUS_UNSUCCESSFUL;
45 CRYPT_DEShash(output, key, data);
46 return STATUS_SUCCESS;
47 }
48
49
50 /******************************************************************************
51 * SystemFunction002 [ADVAPI32.@]
52 *
53 * Decrypts a single block of data using DES
54 *
55 * PARAMS
56 * data [I] data to decrypt (8 bytes)
57 * key [I] key data (7 bytes)
58 * output [O] the decrypted data (8 bytes)
59 *
60 * RETURNS
61 * Success: STATUS_SUCCESS
62 * Failure: STATUS_UNSUCCESSFUL
63 *
64 */
65 NTSTATUS
SystemFunction002(const BYTE * data,const BYTE * key,LPBYTE output)66 WINAPI SystemFunction002(const BYTE *data, const BYTE *key, LPBYTE output)
67 {
68 if (!data || !output)
69 return STATUS_UNSUCCESSFUL;
70 CRYPT_DESunhash(output, key, data);
71 return STATUS_SUCCESS;
72 }
73
74
75 /******************************************************************************
76 * SystemFunction003 [ADVAPI32.@]
77 *
78 * Hashes a key using DES and a fixed datablock
79 *
80 * PARAMS
81 * key [I] key data (7 bytes)
82 * output [O] hashed key (8 bytes)
83 *
84 * RETURNS
85 * Success: STATUS_SUCCESS
86 * Failure: STATUS_UNSUCCESSFUL
87 *
88 */
89 NTSTATUS
SystemFunction003(const BYTE * key,LPBYTE output)90 WINAPI SystemFunction003(const BYTE *key, LPBYTE output)
91 {
92 if (!output)
93 return STATUS_UNSUCCESSFUL;
94 CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
95 return STATUS_SUCCESS;
96 }
97
98
99 /******************************************************************************
100 * SystemFunction004 [ADVAPI32.@]
101 *
102 * Encrypts a block of data with DES in ECB mode, preserving the length
103 *
104 * PARAMS
105 * data [I] data to encrypt
106 * key [I] key data (up to 7 bytes)
107 * output [O] buffer to receive encrypted data
108 *
109 * RETURNS
110 * Success: STATUS_SUCCESS
111 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
112 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
113 *
114 * NOTES
115 * Encrypt buffer size should be input size rounded up to 8 bytes
116 * plus an extra 8 bytes.
117 */
118 NTSTATUS
SystemFunction004(const struct ustring * in,const struct ustring * key,struct ustring * out)119 WINAPI SystemFunction004(const struct ustring *in,
120 const struct ustring *key,
121 struct ustring *out)
122 {
123 union {
124 unsigned char uc[8];
125 unsigned int ui[2];
126 } data;
127 unsigned char deskey[7];
128 unsigned int crypt_len, ofs;
129
130 if (key->Length<=0)
131 return STATUS_INVALID_PARAMETER_2;
132
133 crypt_len = ((in->Length+7)&~7);
134 if (out->MaximumLength < (crypt_len+8))
135 {
136 out->Length = crypt_len + 8;
137 return STATUS_BUFFER_TOO_SMALL;
138 }
139
140 data.ui[0] = in->Length;
141 data.ui[1] = 1;
142
143 if (key->Length<sizeof deskey)
144 {
145 memset(deskey, 0, sizeof deskey);
146 memcpy(deskey, key->Buffer, key->Length);
147 }
148 else
149 memcpy(deskey, key->Buffer, sizeof deskey);
150
151 CRYPT_DEShash(out->Buffer, deskey, data.uc);
152
153 for(ofs=0; ofs<(crypt_len-8); ofs+=8)
154 CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
155
156 memset(data.uc, 0, sizeof data.uc);
157 memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len);
158 CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
159
160 out->Length = crypt_len+8;
161
162 return STATUS_SUCCESS;
163 }
164
165 /******************************************************************************
166 * SystemFunction005 [ADVAPI32.@]
167 *
168 * Decrypts a block of data with DES in ECB mode
169 *
170 * PARAMS
171 * data [I] data to decrypt
172 * key [I] key data (up to 7 bytes)
173 * output [O] buffer to receive decrypted data
174 *
175 * RETURNS
176 * Success: STATUS_SUCCESS
177 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
178 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
179 *
180 */
181 NTSTATUS
SystemFunction005(const struct ustring * in,const struct ustring * key,struct ustring * out)182 WINAPI SystemFunction005(const struct ustring *in,
183 const struct ustring *key,
184 struct ustring *out)
185 {
186 union {
187 unsigned char uc[8];
188 unsigned int ui[2];
189 } data;
190 unsigned char deskey[7];
191 unsigned int ofs, crypt_len;
192
193 if (key->Length<=0)
194 return STATUS_INVALID_PARAMETER_2;
195
196 if (key->Length<sizeof deskey)
197 {
198 memset(deskey, 0, sizeof deskey);
199 memcpy(deskey, key->Buffer, key->Length);
200 }
201 else
202 memcpy(deskey, key->Buffer, sizeof deskey);
203
204 CRYPT_DESunhash(data.uc, deskey, in->Buffer);
205
206 if (data.ui[1] != 1)
207 return STATUS_UNKNOWN_REVISION;
208
209 crypt_len = data.ui[0];
210 if (crypt_len > out->MaximumLength)
211 {
212 out->Length = crypt_len;
213 return STATUS_BUFFER_TOO_SMALL;
214 }
215
216 for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
217 CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
218
219 if (ofs<crypt_len)
220 {
221 CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8);
222 memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs);
223 }
224
225 out->Length = crypt_len;
226
227 return STATUS_SUCCESS;
228 }
229
230 /******************************************************************************
231 * SystemFunction007 [ADVAPI32.@]
232 *
233 * MD4 hash a unicode string
234 *
235 * PARAMS
236 * string [I] the string to hash
237 * output [O] the md4 hash of the string (16 bytes)
238 *
239 * RETURNS
240 * Success: STATUS_SUCCESS
241 * Failure: STATUS_UNSUCCESSFUL
242 *
243 */
244 NTSTATUS
SystemFunction007(const UNICODE_STRING * string,LPBYTE hash)245 WINAPI SystemFunction007(const UNICODE_STRING *string, LPBYTE hash)
246 {
247 MD4_CTX ctx;
248
249 MD4Init( &ctx );
250 MD4Update( &ctx, (const BYTE *)string->Buffer, string->Length );
251 MD4Final( &ctx );
252 memcpy( hash, ctx.digest, 0x10 );
253
254 return STATUS_SUCCESS;
255 }
256
257 /******************************************************************************
258 * SystemFunction008 [ADVAPI32.@]
259 *
260 * Creates a LM response from a challenge and a password hash
261 *
262 * PARAMS
263 * challenge [I] Challenge from authentication server
264 * hash [I] NTLM hash (from SystemFunction006)
265 * response [O] response to send back to the server
266 *
267 * RETURNS
268 * Success: STATUS_SUCCESS
269 * Failure: STATUS_UNSUCCESSFUL
270 *
271 * NOTES
272 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
273 *
274 */
275 NTSTATUS
SystemFunction008(const BYTE * challenge,const BYTE * hash,LPBYTE response)276 WINAPI SystemFunction008(const BYTE *challenge, const BYTE *hash, LPBYTE response)
277 {
278 BYTE key[7*3];
279
280 if (!challenge || !response)
281 return STATUS_UNSUCCESSFUL;
282
283 memset(key, 0, sizeof key);
284 memcpy(key, hash, 0x10);
285
286 CRYPT_DEShash(response, key, challenge);
287 CRYPT_DEShash(response+8, key+7, challenge);
288 CRYPT_DEShash(response+16, key+14, challenge);
289
290 return STATUS_SUCCESS;
291 }
292
293 /******************************************************************************
294 * SystemFunction009 [ADVAPI32.@]
295 *
296 * Seems to do the same as SystemFunction008...
297 */
298 NTSTATUS
SystemFunction009(const BYTE * challenge,const BYTE * hash,LPBYTE response)299 WINAPI SystemFunction009(const BYTE *challenge, const BYTE *hash, LPBYTE response)
300 {
301 return SystemFunction008(challenge, hash, response);
302 }
303
304 /******************************************************************************
305 * SystemFunction010 [ADVAPI32.@]
306 * SystemFunction011 [ADVAPI32.@]
307 *
308 * MD4 hashes 16 bytes of data
309 *
310 * PARAMS
311 * unknown [] seems to have no effect on the output
312 * data [I] pointer to data to hash (16 bytes)
313 * output [O] the md4 hash of the data (16 bytes)
314 *
315 * RETURNS
316 * Success: STATUS_SUCCESS
317 * Failure: STATUS_UNSUCCESSFUL
318 *
319 */
320 NTSTATUS
SystemFunction010(LPVOID unknown,const BYTE * data,LPBYTE hash)321 WINAPI SystemFunction010(LPVOID unknown, const BYTE *data, LPBYTE hash)
322 {
323 MD4_CTX ctx;
324
325 MD4Init( &ctx );
326 MD4Update( &ctx, data, 0x10 );
327 MD4Final( &ctx );
328 memcpy( hash, ctx.digest, 0x10 );
329
330 return STATUS_SUCCESS;
331 }
332
333 /******************************************************************************
334 * SystemFunction012 [ADVAPI32.@]
335 * SystemFunction014 [ADVAPI32.@]
336 * SystemFunction016 [ADVAPI32.@]
337 * SystemFunction018 [ADVAPI32.@]
338 * SystemFunction020 [ADVAPI32.@]
339 * SystemFunction022 [ADVAPI32.@]
340 *
341 * Encrypts two DES blocks with two keys
342 *
343 * PARAMS
344 * data [I] data to encrypt (16 bytes)
345 * key [I] key data (two lots of 7 bytes)
346 * output [O] buffer to receive encrypted data (16 bytes)
347 *
348 * RETURNS
349 * Success: STATUS_SUCCESS
350 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
351 */
352 NTSTATUS
SystemFunction012(const BYTE * in,const BYTE * key,LPBYTE out)353 WINAPI SystemFunction012(const BYTE *in, const BYTE *key, LPBYTE out)
354 {
355 if (!in || !out)
356 return STATUS_UNSUCCESSFUL;
357
358 CRYPT_DEShash(out, key, in);
359 CRYPT_DEShash(out+8, key+7, in+8);
360 return STATUS_SUCCESS;
361 }
362
363 /******************************************************************************
364 * SystemFunction013 [ADVAPI32.@]
365 * SystemFunction015 [ADVAPI32.@]
366 * SystemFunction017 [ADVAPI32.@]
367 * SystemFunction019 [ADVAPI32.@]
368 * SystemFunction021 [ADVAPI32.@]
369 * SystemFunction023 [ADVAPI32.@]
370 *
371 * Decrypts two DES blocks with two keys
372 *
373 * PARAMS
374 * data [I] data to decrypt (16 bytes)
375 * key [I] key data (two lots of 7 bytes)
376 * output [O] buffer to receive decrypted data (16 bytes)
377 *
378 * RETURNS
379 * Success: STATUS_SUCCESS
380 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
381 */
382 NTSTATUS
SystemFunction013(const BYTE * in,const BYTE * key,LPBYTE out)383 WINAPI SystemFunction013(const BYTE *in, const BYTE *key, LPBYTE out)
384 {
385 if (!in || !out)
386 return STATUS_UNSUCCESSFUL;
387 CRYPT_DESunhash(out, key, in);
388 CRYPT_DESunhash(out+8, key+7, in+8);
389 return STATUS_SUCCESS;
390 }
391
392 /******************************************************************************
393 * SystemFunction024 [ADVAPI32.@]
394 *
395 * Encrypts two DES blocks with a 32 bit key...
396 *
397 * PARAMS
398 * data [I] data to encrypt (16 bytes)
399 * key [I] key data (4 bytes)
400 * output [O] buffer to receive encrypted data (16 bytes)
401 *
402 * RETURNS
403 * Success: STATUS_SUCCESS
404 */
405 NTSTATUS
SystemFunction024(const BYTE * in,const BYTE * key,LPBYTE out)406 WINAPI SystemFunction024(const BYTE *in, const BYTE *key, LPBYTE out)
407 {
408 BYTE deskey[0x10];
409
410 memcpy(deskey, key, 4);
411 memcpy(deskey+4, key, 4);
412 memcpy(deskey+8, key, 4);
413 memcpy(deskey+12, key, 4);
414
415 CRYPT_DEShash(out, deskey, in);
416 CRYPT_DEShash(out+8, deskey+7, in+8);
417
418 return STATUS_SUCCESS;
419 }
420
421 /******************************************************************************
422 * SystemFunction025 [ADVAPI32.@]
423 *
424 * Decrypts two DES blocks with a 32 bit key...
425 *
426 * PARAMS
427 * data [I] data to encrypt (16 bytes)
428 * key [I] key data (4 bytes)
429 * output [O] buffer to receive encrypted data (16 bytes)
430 *
431 * RETURNS
432 * Success: STATUS_SUCCESS
433 */
434 NTSTATUS
SystemFunction025(const BYTE * in,const BYTE * key,LPBYTE out)435 WINAPI SystemFunction025(const BYTE *in, const BYTE *key, LPBYTE out)
436 {
437 BYTE deskey[0x10];
438
439 memcpy(deskey, key, 4);
440 memcpy(deskey+4, key, 4);
441 memcpy(deskey+8, key, 4);
442 memcpy(deskey+12, key, 4);
443
444 CRYPT_DESunhash(out, deskey, in);
445 CRYPT_DESunhash(out+8, deskey+7, in+8);
446
447 return STATUS_SUCCESS;
448 }
449
450 /**********************************************************************
451 * SystemFunction028 [ADVAPI32.@]
452 *
453 * Retrieves an encryption session key...
454 *
455 * PARAMS
456 * ContextHandle [I] RPC context handle
457 * SessionKey [O] buffer to receive the session key (16 bytes)
458 *
459 * RETURNS
460 * Success: STATUS_LOCAL_USER_SESSION_KEY
461 *
462 * @unimplemented
463 */
464 NTSTATUS
465 WINAPI
SystemFunction028(_In_ PVOID ContextHandle,_Out_ LPBYTE SessionKey)466 SystemFunction028(
467 _In_ PVOID ContextHandle,
468 _Out_ LPBYTE SessionKey)
469 {
470 /* HACK: Always return the default key */
471 memcpy(SessionKey, DefaultSessionKey, sizeof(DefaultSessionKey));
472 return STATUS_LOCAL_USER_SESSION_KEY;
473
474 #if 0
475 //NDRCContextBinding();
476 //SystemFunction034()
477 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
478 return 28;
479 #endif
480 }
481
482
483 /**********************************************************************
484 *
485 * @unimplemented
486 */
487 INT
488 WINAPI
SystemFunction029(INT a,INT b)489 SystemFunction029(INT a, INT b)
490 {
491 //I_RpcBindingIsClientLocal()
492 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
493 return 29;
494 }
495
496
497 /******************************************************************************
498 * SystemFunction030 (ADVAPI32.@)
499 *
500 * Tests if two blocks of 16 bytes are equal
501 *
502 * PARAMS
503 * b1,b2 [I] block of 16 bytes
504 *
505 * RETURNS
506 * TRUE if blocks are the same
507 * FALSE if blocks are different
508 */
509 BOOL
SystemFunction030(LPCVOID b1,LPCVOID b2)510 WINAPI SystemFunction030(LPCVOID b1, LPCVOID b2)
511 {
512 return !memcmp(b1, b2, 0x10);
513 }
514
515
516 /******************************************************************************
517 * SystemFunction032 [ADVAPI32.@]
518 *
519 * Encrypts a string data using ARC4
520 *
521 * PARAMS
522 * data [I/O] data to encrypt
523 * key [I] key data
524 *
525 * RETURNS
526 * Success: STATUS_SUCCESS
527 * Failure: STATUS_UNSUCCESSFUL
528 *
529 * NOTES
530 * see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail
531 */
532 NTSTATUS
SystemFunction032(struct ustring * data,const struct ustring * key)533 WINAPI SystemFunction032(struct ustring *data, const struct ustring *key)
534 {
535 RC4_CONTEXT a4i;
536
537 rc4_init(&a4i, key->Buffer, key->Length);
538 rc4_crypt(&a4i, data->Buffer, data->Length);
539
540 return STATUS_SUCCESS;
541 }
542
543
544 /**********************************************************************
545 *
546 * @unimplemented
547 */
548 INT
549 WINAPI
SystemFunction033(INT a,INT b)550 SystemFunction033(INT a, INT b)
551 {
552 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
553 return 33;
554 }
555
556 /**********************************************************************
557 *
558 * @unimplemented
559 */
560 INT
561 WINAPI
SystemFunction034(INT a,INT b)562 SystemFunction034(INT a, INT b)
563 {
564 //RpcBindingToStringBindingW
565 //I_RpcMapWin32Status
566 //RpcStringBindingParseW
567 //RpcStringFreeW
568 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
569 return 34;
570 }
571
572
573 /******************************************************************************
574 * SystemFunction035 (ADVAPI32.@)
575 *
576 * Described here:
577 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem
578 *
579 * NOTES
580 * Stub, always return TRUE.
581 */
SystemFunction035(LPCSTR lpszDllFilePath)582 BOOL WINAPI SystemFunction035(LPCSTR lpszDllFilePath)
583 {
584 //FIXME("%s: stub\n", debugstr_a(lpszDllFilePath));
585 return TRUE;
586 }
587
588 /******************************************************************************
589 * SystemFunction036 (ADVAPI32.@)
590 *
591 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
592 *
593 * PARAMS
594 * pbBuffer [O] Pointer to memory to receive random bytes.
595 * dwLen [I] Number of random bytes to fetch.
596 *
597 * RETURNS
598 * Always TRUE in my tests
599 */
600 BOOLEAN
601 WINAPI
SystemFunction036(PVOID pbBuffer,ULONG dwLen)602 SystemFunction036(PVOID pbBuffer, ULONG dwLen)
603 {
604 ////////////////////////////////////////////////////////////////
605 //////////////////// B I G W A R N I N G !!! ////////////////
606 // This function will output numbers based on the tick count. //
607 // It will NOT OUTPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!! //
608 ////////////////////////////////////////////////////////////////
609
610 DWORD dwSeed;
611 PBYTE pBuffer;
612 ULONG uPseudoRandom;
613 LARGE_INTEGER time;
614 static ULONG uCounter = 17;
615
616 if(!pbBuffer || !dwLen)
617 {
618 /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */
619 return TRUE;
620 }
621
622 /* Get the first seed from the performance counter */
623 QueryPerformanceCounter(&time);
624 dwSeed = time.LowPart ^ time.HighPart ^ RtlUlongByteSwap(uCounter++);
625
626 /* We will access the buffer bytewise */
627 pBuffer = (PBYTE)pbBuffer;
628
629 do
630 {
631 /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */
632 uPseudoRandom = RtlRandom(&dwSeed);
633
634 do
635 {
636 /* Get each byte from the pseudo random number and store it in the buffer */
637 *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 3) & 0xFF);
638 ++pBuffer;
639 } while(--dwLen % 3);
640 } while(dwLen);
641
642 return TRUE;
643 }
644
645 HANDLE KsecDeviceHandle;
646
647 static
648 NTSTATUS
KsecOpenDevice()649 KsecOpenDevice()
650 {
651 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KsecDD");
652 OBJECT_ATTRIBUTES ObjectAttributes;
653 IO_STATUS_BLOCK IoStatusBlock;
654 HANDLE DeviceHandle;
655 NTSTATUS Status;
656
657 InitializeObjectAttributes(&ObjectAttributes,
658 &DeviceName,
659 OBJ_CASE_INSENSITIVE,
660 NULL,
661 NULL);
662 Status = NtOpenFile(&DeviceHandle,
663 FILE_READ_DATA | SYNCHRONIZE,
664 &ObjectAttributes,
665 &IoStatusBlock,
666 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
667 FILE_SYNCHRONOUS_IO_NONALERT);
668 if (!NT_SUCCESS(Status))
669 {
670 return Status;
671 }
672
673 if (InterlockedCompareExchangePointer(&KsecDeviceHandle, DeviceHandle, NULL) != NULL)
674 {
675 NtClose(DeviceHandle);
676 }
677
678 return STATUS_SUCCESS;
679 }
680
681 VOID
CloseKsecDdHandle(VOID)682 CloseKsecDdHandle(VOID)
683 {
684 /* Check if we already opened a handle to ksecdd */
685 if (KsecDeviceHandle != NULL)
686 {
687 /* Close it */
688 CloseHandle(KsecDeviceHandle);
689 KsecDeviceHandle = NULL;
690 }
691 }
692
693 static
694 NTSTATUS
KsecDeviceIoControl(ULONG IoControlCode,PVOID InputBuffer,SIZE_T InputBufferLength,PVOID OutputBuffer,SIZE_T OutputBufferLength)695 KsecDeviceIoControl(
696 ULONG IoControlCode,
697 PVOID InputBuffer,
698 SIZE_T InputBufferLength,
699 PVOID OutputBuffer,
700 SIZE_T OutputBufferLength)
701 {
702 IO_STATUS_BLOCK IoStatusBlock;
703 NTSTATUS Status;
704
705 /* Check if we already have a handle */
706 if (KsecDeviceHandle == NULL)
707 {
708 /* Try to open the device */
709 Status = KsecOpenDevice();
710 if (!NT_SUCCESS(Status))
711 {
712 //ERR("Failed to open handle to KsecDd driver!\n");
713 return Status;
714 }
715 }
716
717 /* Call the driver */
718 Status = NtDeviceIoControlFile(KsecDeviceHandle,
719 NULL,
720 NULL,
721 NULL,
722 &IoStatusBlock,
723 IoControlCode,
724 InputBuffer,
725 InputBufferLength,
726 OutputBuffer,
727 OutputBufferLength);
728
729 return Status;
730 }
731
732 /*
733 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
734 in crypt32.dll.
735 */
736
737 /******************************************************************************
738 * SystemFunction040 (ADVAPI32.@)
739 *
740 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h.
741 *
742 * PARAMS
743 * memory [I/O] Pointer to memory to encrypt.
744 * length [I] Length of region to encrypt in bytes.
745 * flags [I] Control whether other processes are able to decrypt the memory.
746 * RTL_ENCRYPT_OPTION_SAME_PROCESS
747 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
748 * RTL_ENCRYPT_OPTION_SAME_LOGON
749 *
750 * RETURNS
751 * Success: STATUS_SUCCESS
752 * Failure: NTSTATUS error code
753 *
754 * NOTES
755 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
756 * If flags are specified when encrypting, the same flag value must be given
757 * when decrypting the memory.
758 */
759 NTSTATUS
760 WINAPI
SystemFunction040(_Inout_ PVOID Memory,_In_ ULONG MemoryLength,_In_ ULONG OptionFlags)761 SystemFunction040(
762 _Inout_ PVOID Memory,
763 _In_ ULONG MemoryLength,
764 _In_ ULONG OptionFlags)
765 {
766 ULONG IoControlCode;
767
768 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
769 {
770 IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_PROCESS;
771 }
772 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
773 {
774 IoControlCode = IOCTL_KSEC_ENCRYPT_CROSS_PROCESS;
775 }
776 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
777 {
778 IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_LOGON;
779 }
780 else
781 {
782 return STATUS_INVALID_PARAMETER;
783 }
784
785 return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
786 }
787
788 /******************************************************************************
789 * SystemFunction041 (ADVAPI32.@)
790 *
791 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h.
792 *
793 * PARAMS
794 * memory [I/O] Pointer to memory to decrypt.
795 * length [I] Length of region to decrypt in bytes.
796 * flags [I] Control whether other processes are able to decrypt the memory.
797 * RTL_ENCRYPT_OPTION_SAME_PROCESS
798 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
799 * RTL_ENCRYPT_OPTION_SAME_LOGON
800 *
801 * RETURNS
802 * Success: STATUS_SUCCESS
803 * Failure: NTSTATUS error code
804 *
805 * NOTES
806 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
807 * If flags are specified when encrypting, the same flag value must be given
808 * when decrypting the memory.
809 */
810 NTSTATUS
811 WINAPI
SystemFunction041(_Inout_ PVOID Memory,_In_ ULONG MemoryLength,_In_ ULONG OptionFlags)812 SystemFunction041(
813 _Inout_ PVOID Memory,
814 _In_ ULONG MemoryLength,
815 _In_ ULONG OptionFlags)
816 {
817 ULONG IoControlCode;
818
819 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
820 {
821 IoControlCode = IOCTL_KSEC_DECRYPT_SAME_PROCESS;
822 }
823 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
824 {
825 IoControlCode = IOCTL_KSEC_DECRYPT_CROSS_PROCESS;
826 }
827 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
828 {
829 IoControlCode = IOCTL_KSEC_DECRYPT_SAME_LOGON;
830 }
831 else
832 {
833 return STATUS_INVALID_PARAMETER;
834 }
835
836 return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
837 }
838
839 /* EOF */
840