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