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