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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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