Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/advapi32/misc/sysfunc.c * PURPOSE: advapi32.dll system functions (undocumented) * PROGRAMMER: Emanuele Aliberti * UPDATE HISTORY: * 19990413 EA created * 19990415 EA * 20080424 Ported from WINE */
#include <advapi32.h>#include <ntsecapi.h>#include <ksecioctl.h>#include <md4.h>#include <md5.h>#include <rc4.h>
static const unsigned char CRYPT_LMhash_Magic[8] = { 'K', 'G', 'S', '!', '@', '#', '$', '%' };static const unsigned char DefaultSessionKey[16] = {'D', 'e', 'f', 'S', 'e', 's', 's', 'i', 'o', 'n', 'K', 'e', 'y', '!', '@', '#'};
/****************************************************************************** * SystemFunction001 [ADVAPI32.@] * * Encrypts a single block of data using DES * * PARAMS * data [I] data to encrypt (8 bytes) * key [I] key data (7 bytes) * output [O] the encrypted data (8 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * */NTSTATUSWINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output){ if (!data || !output) return STATUS_UNSUCCESSFUL; CRYPT_DEShash(output, key, data); return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction002 [ADVAPI32.@] * * Decrypts a single block of data using DES * * PARAMS * data [I] data to decrypt (8 bytes) * key [I] key data (7 bytes) * output [O] the decrypted data (8 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * */NTSTATUSWINAPI SystemFunction002(const BYTE *data, const BYTE *key, LPBYTE output){ if (!data || !output) return STATUS_UNSUCCESSFUL; CRYPT_DESunhash(output, key, data); return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction003 [ADVAPI32.@] * * Hashes a key using DES and a fixed datablock * * PARAMS * key [I] key data (7 bytes) * output [O] hashed key (8 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * */NTSTATUSWINAPI SystemFunction003(const BYTE *key, LPBYTE output){ if (!output) return STATUS_UNSUCCESSFUL; CRYPT_DEShash(output, key, CRYPT_LMhash_Magic); return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction004 [ADVAPI32.@] * * Encrypts a block of data with DES in ECB mode, preserving the length * * PARAMS * data [I] data to encrypt * key [I] key data (up to 7 bytes) * output [O] buffer to receive encrypted data * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length * * NOTES * Encrypt buffer size should be input size rounded up to 8 bytes * plus an extra 8 bytes. */NTSTATUSWINAPI SystemFunction004(const struct ustring *in, const struct ustring *key, struct ustring *out){ union { unsigned char uc[8]; unsigned int ui[2]; } data; unsigned char deskey[7]; unsigned int crypt_len, ofs;
if (key->Length<=0) return STATUS_INVALID_PARAMETER_2;
crypt_len = ((in->Length+7)&~7); if (out->MaximumLength < (crypt_len+8)) { out->Length = crypt_len + 8; return STATUS_BUFFER_TOO_SMALL; }
data.ui[0] = in->Length; data.ui[1] = 1;
if (key->Length<sizeof deskey) { memset(deskey, 0, sizeof deskey); memcpy(deskey, key->Buffer, key->Length); } else memcpy(deskey, key->Buffer, sizeof deskey);
CRYPT_DEShash(out->Buffer, deskey, data.uc);
for(ofs=0; ofs<(crypt_len-8); ofs+=8) CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
memset(data.uc, 0, sizeof data.uc); memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len); CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
out->Length = crypt_len+8;
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction005 [ADVAPI32.@] * * Decrypts a block of data with DES in ECB mode * * PARAMS * data [I] data to decrypt * key [I] key data (up to 7 bytes) * output [O] buffer to receive decrypted data * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length * */NTSTATUSWINAPI SystemFunction005(const struct ustring *in, const struct ustring *key, struct ustring *out){ union { unsigned char uc[8]; unsigned int ui[2]; } data; unsigned char deskey[7]; unsigned int ofs, crypt_len;
if (key->Length<=0) return STATUS_INVALID_PARAMETER_2;
if (key->Length<sizeof deskey) { memset(deskey, 0, sizeof deskey); memcpy(deskey, key->Buffer, key->Length); } else memcpy(deskey, key->Buffer, sizeof deskey);
CRYPT_DESunhash(data.uc, deskey, in->Buffer);
if (data.ui[1] != 1) return STATUS_UNKNOWN_REVISION;
crypt_len = data.ui[0]; if (crypt_len > out->MaximumLength) { out->Length = crypt_len; return STATUS_BUFFER_TOO_SMALL; }
for (ofs=0; (ofs+8)<crypt_len; ofs+=8) CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
if (ofs<crypt_len) { CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8); memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs); }
out->Length = crypt_len;
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction007 [ADVAPI32.@] * * MD4 hash a unicode string * * PARAMS * string [I] the string to hash * output [O] the md4 hash of the string (16 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * */NTSTATUSWINAPI SystemFunction007(const UNICODE_STRING *string, LPBYTE hash){ MD4_CTX ctx;
MD4Init( &ctx ); MD4Update( &ctx, (const BYTE *)string->Buffer, string->Length ); MD4Final( &ctx ); memcpy( hash, ctx.digest, 0x10 );
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction008 [ADVAPI32.@] * * Creates a LM response from a challenge and a password hash * * PARAMS * challenge [I] Challenge from authentication server * hash [I] NTLM hash (from SystemFunction006) * response [O] response to send back to the server * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * * NOTES * see http://davenport.sourceforge.net/ntlm.html#theLmResponse * */NTSTATUSWINAPI SystemFunction008(const BYTE *challenge, const BYTE *hash, LPBYTE response){ BYTE key[7*3];
if (!challenge || !response) return STATUS_UNSUCCESSFUL;
memset(key, 0, sizeof key); memcpy(key, hash, 0x10);
CRYPT_DEShash(response, key, challenge); CRYPT_DEShash(response+8, key+7, challenge); CRYPT_DEShash(response+16, key+14, challenge);
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction009 [ADVAPI32.@] * * Seems to do the same as SystemFunction008... */NTSTATUSWINAPI SystemFunction009(const BYTE *challenge, const BYTE *hash, LPBYTE response){ return SystemFunction008(challenge, hash, response);}
/****************************************************************************** * SystemFunction010 [ADVAPI32.@] * SystemFunction011 [ADVAPI32.@] * * MD4 hashes 16 bytes of data * * PARAMS * unknown [] seems to have no effect on the output * data [I] pointer to data to hash (16 bytes) * output [O] the md4 hash of the data (16 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * */NTSTATUSWINAPI SystemFunction010(LPVOID unknown, const BYTE *data, LPBYTE hash){ MD4_CTX ctx;
MD4Init( &ctx ); MD4Update( &ctx, data, 0x10 ); MD4Final( &ctx ); memcpy( hash, ctx.digest, 0x10 );
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction012 [ADVAPI32.@] * SystemFunction014 [ADVAPI32.@] * SystemFunction016 [ADVAPI32.@] * SystemFunction018 [ADVAPI32.@] * SystemFunction020 [ADVAPI32.@] * SystemFunction022 [ADVAPI32.@] * * Encrypts two DES blocks with two keys * * PARAMS * data [I] data to encrypt (16 bytes) * key [I] key data (two lots of 7 bytes) * output [O] buffer to receive encrypted data (16 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL */NTSTATUSWINAPI SystemFunction012(const BYTE *in, const BYTE *key, LPBYTE out){ if (!in || !out) return STATUS_UNSUCCESSFUL;
CRYPT_DEShash(out, key, in); CRYPT_DEShash(out+8, key+7, in+8); return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction013 [ADVAPI32.@] * SystemFunction015 [ADVAPI32.@] * SystemFunction017 [ADVAPI32.@] * SystemFunction019 [ADVAPI32.@] * SystemFunction021 [ADVAPI32.@] * SystemFunction023 [ADVAPI32.@] * * Decrypts two DES blocks with two keys * * PARAMS * data [I] data to decrypt (16 bytes) * key [I] key data (two lots of 7 bytes) * output [O] buffer to receive decrypted data (16 bytes) * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL */NTSTATUSWINAPI SystemFunction013(const BYTE *in, const BYTE *key, LPBYTE out){ if (!in || !out) return STATUS_UNSUCCESSFUL; CRYPT_DESunhash(out, key, in); CRYPT_DESunhash(out+8, key+7, in+8); return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction024 [ADVAPI32.@] * * Encrypts two DES blocks with a 32 bit key... * * PARAMS * data [I] data to encrypt (16 bytes) * key [I] key data (4 bytes) * output [O] buffer to receive encrypted data (16 bytes) * * RETURNS * Success: STATUS_SUCCESS */NTSTATUSWINAPI SystemFunction024(const BYTE *in, const BYTE *key, LPBYTE out){ BYTE deskey[0x10];
memcpy(deskey, key, 4); memcpy(deskey+4, key, 4); memcpy(deskey+8, key, 4); memcpy(deskey+12, key, 4);
CRYPT_DEShash(out, deskey, in); CRYPT_DEShash(out+8, deskey+7, in+8);
return STATUS_SUCCESS;}
/****************************************************************************** * SystemFunction025 [ADVAPI32.@] * * Decrypts two DES blocks with a 32 bit key... * * PARAMS * data [I] data to encrypt (16 bytes) * key [I] key data (4 bytes) * output [O] buffer to receive encrypted data (16 bytes) * * RETURNS * Success: STATUS_SUCCESS */NTSTATUSWINAPI SystemFunction025(const BYTE *in, const BYTE *key, LPBYTE out){ BYTE deskey[0x10];
memcpy(deskey, key, 4); memcpy(deskey+4, key, 4); memcpy(deskey+8, key, 4); memcpy(deskey+12, key, 4);
CRYPT_DESunhash(out, deskey, in); CRYPT_DESunhash(out+8, deskey+7, in+8);
return STATUS_SUCCESS;}
/********************************************************************** * SystemFunction028 [ADVAPI32.@] * * Retrieves an encryption session key... * * PARAMS * ContextHandle [I] RPC context handle * SessionKey [O] buffer to receive the session key (16 bytes) * * RETURNS * Success: STATUS_LOCAL_USER_SESSION_KEY * * @unimplemented */NTSTATUSWINAPISystemFunction028( _In_ PVOID ContextHandle, _Out_ LPBYTE SessionKey){ /* HACK: Always return the default key */ memcpy(SessionKey, DefaultSessionKey, sizeof(DefaultSessionKey)); return STATUS_LOCAL_USER_SESSION_KEY;
#if 0 //NDRCContextBinding(); //SystemFunction034() SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 28;#endif}
/********************************************************************** * * @unimplemented */INTWINAPISystemFunction029(INT a, INT b){ //I_RpcBindingIsClientLocal() SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 29;}
/****************************************************************************** * SystemFunction030 (ADVAPI32.@) * * Tests if two blocks of 16 bytes are equal * * PARAMS * b1,b2 [I] block of 16 bytes * * RETURNS * TRUE if blocks are the same * FALSE if blocks are different */BOOLWINAPI SystemFunction030(LPCVOID b1, LPCVOID b2){ return !memcmp(b1, b2, 0x10);}
/****************************************************************************** * SystemFunction032 [ADVAPI32.@] * * Encrypts a string data using ARC4 * * PARAMS * data [I/O] data to encrypt * key [I] key data * * RETURNS * Success: STATUS_SUCCESS * Failure: STATUS_UNSUCCESSFUL * * NOTES * see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail */NTSTATUSWINAPI SystemFunction032(struct ustring *data, const struct ustring *key){ RC4_CONTEXT a4i;
rc4_init(&a4i, key->Buffer, key->Length); rc4_crypt(&a4i, data->Buffer, data->Length);
return STATUS_SUCCESS;}
/********************************************************************** * * @unimplemented */INTWINAPISystemFunction033(INT a, INT b){ SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 33;}
/********************************************************************** * * @unimplemented */INTWINAPISystemFunction034(INT a, INT b){ //RpcBindingToStringBindingW //I_RpcMapWin32Status //RpcStringBindingParseW //RpcStringFreeW SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 34;}
/****************************************************************************** * SystemFunction035 (ADVAPI32.@) * * Described here:http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem * * NOTES * Stub, always return TRUE. */BOOL WINAPI SystemFunction035(LPCSTR lpszDllFilePath){ //FIXME("%s: stub\n", debugstr_a(lpszDllFilePath)); return TRUE;}
/****************************************************************************** * SystemFunction036 (ADVAPI32.@) * * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h * * PARAMS * pbBuffer [O] Pointer to memory to receive random bytes. * dwLen [I] Number of random bytes to fetch. * * RETURNS * Always TRUE in my tests */BOOLEANWINAPISystemFunction036(PVOID pbBuffer, ULONG dwLen){ //////////////////////////////////////////////////////////////// //////////////////// B I G W A R N I N G !!! //////////////// // This function will output numbers based on the tick count. // // It will NOT OUTPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!! // ////////////////////////////////////////////////////////////////
DWORD dwSeed; PBYTE pBuffer; ULONG uPseudoRandom; LARGE_INTEGER time; static ULONG uCounter = 17;
if(!pbBuffer || !dwLen) { /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */ return TRUE; }
/* Get the first seed from the performance counter */ QueryPerformanceCounter(&time); dwSeed = time.LowPart ^ time.HighPart ^ RtlUlongByteSwap(uCounter++);
/* We will access the buffer bytewise */ pBuffer = (PBYTE)pbBuffer;
do { /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */ uPseudoRandom = RtlRandom(&dwSeed);
do { /* Get each byte from the pseudo random number and store it in the buffer */ *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 3) & 0xFF); ++pBuffer; } while(--dwLen % 3); } while(dwLen);
return TRUE;}
HANDLE KsecDeviceHandle;
staticNTSTATUSKsecOpenDevice(){ UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KsecDD"); OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; HANDLE DeviceHandle; NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&DeviceHandle, FILE_READ_DATA | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { return Status; }
if (InterlockedCompareExchangePointer(&KsecDeviceHandle, DeviceHandle, NULL) != NULL) { NtClose(DeviceHandle); }
return STATUS_SUCCESS;}
VOIDCloseKsecDdHandle(VOID){ /* Check if we already opened a handle to ksecdd */ if (KsecDeviceHandle != NULL) { /* Close it */ CloseHandle(KsecDeviceHandle); KsecDeviceHandle = NULL; }}
staticNTSTATUSKsecDeviceIoControl( ULONG IoControlCode, PVOID InputBuffer, SIZE_T InputBufferLength, PVOID OutputBuffer, SIZE_T OutputBufferLength){ IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
/* Check if we already have a handle */ if (KsecDeviceHandle == NULL) { /* Try to open the device */ Status = KsecOpenDevice(); if (!NT_SUCCESS(Status)) { //ERR("Failed to open handle to KsecDd driver!\n"); return Status; } }
/* Call the driver */ Status = NtDeviceIoControlFile(KsecDeviceHandle, NULL, NULL, NULL, &IoStatusBlock, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength);
return Status;}
/* These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory, in crypt32.dll. */
/****************************************************************************** * SystemFunction040 (ADVAPI32.@) * * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h. * * PARAMS * memory [I/O] Pointer to memory to encrypt. * length [I] Length of region to encrypt in bytes. * flags [I] Control whether other processes are able to decrypt the memory. * RTL_ENCRYPT_OPTION_SAME_PROCESS * RTL_ENCRYPT_OPTION_CROSS_PROCESS * RTL_ENCRYPT_OPTION_SAME_LOGON * * RETURNS * Success: STATUS_SUCCESS * Failure: NTSTATUS error code * * NOTES * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE. * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */NTSTATUSWINAPISystemFunction040( _Inout_ PVOID Memory, _In_ ULONG MemoryLength, _In_ ULONG OptionFlags){ ULONG IoControlCode;
if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS) { IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_PROCESS; } else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS) { IoControlCode = IOCTL_KSEC_ENCRYPT_CROSS_PROCESS; } else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON) { IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_LOGON; } else { return STATUS_INVALID_PARAMETER; }
return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);}
/****************************************************************************** * SystemFunction041 (ADVAPI32.@) * * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h. * * PARAMS * memory [I/O] Pointer to memory to decrypt. * length [I] Length of region to decrypt in bytes. * flags [I] Control whether other processes are able to decrypt the memory. * RTL_ENCRYPT_OPTION_SAME_PROCESS * RTL_ENCRYPT_OPTION_CROSS_PROCESS * RTL_ENCRYPT_OPTION_SAME_LOGON * * RETURNS * Success: STATUS_SUCCESS * Failure: NTSTATUS error code * * NOTES * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE. * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */NTSTATUSWINAPISystemFunction041( _Inout_ PVOID Memory, _In_ ULONG MemoryLength, _In_ ULONG OptionFlags){ ULONG IoControlCode;
if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS) { IoControlCode = IOCTL_KSEC_DECRYPT_SAME_PROCESS; } else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS) { IoControlCode = IOCTL_KSEC_DECRYPT_CROSS_PROCESS; } else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON) { IoControlCode = IOCTL_KSEC_DECRYPT_SAME_LOGON; } else { return STATUS_INVALID_PARAMETER; }
return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);}
/* EOF */