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