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
11 * 20080424 Ported from WINE
19 static const unsigned char CRYPT_LMhash_Magic
[8] =
20 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
22 /******************************************************************************
23 * SystemFunction001 [ADVAPI32.@]
25 * Encrypts a single block of data using DES
28 * data [I] data to encrypt (8 bytes)
29 * key [I] key data (7 bytes)
30 * output [O] the encrypted data (8 bytes)
33 * Success: STATUS_SUCCESS
34 * Failure: STATUS_UNSUCCESSFUL
38 WINAPI
SystemFunction001(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
41 return STATUS_UNSUCCESSFUL
;
42 CRYPT_DEShash(output
, key
, data
);
43 return STATUS_SUCCESS
;
47 /******************************************************************************
48 * SystemFunction002 [ADVAPI32.@]
50 * Decrypts a single block of data using DES
53 * data [I] data to decrypt (8 bytes)
54 * key [I] key data (7 bytes)
55 * output [O] the decrypted data (8 bytes)
58 * Success: STATUS_SUCCESS
59 * Failure: STATUS_UNSUCCESSFUL
63 WINAPI
SystemFunction002(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
66 return STATUS_UNSUCCESSFUL
;
67 CRYPT_DESunhash(output
, key
, data
);
68 return STATUS_SUCCESS
;
72 /******************************************************************************
73 * SystemFunction003 [ADVAPI32.@]
75 * Hashes a key using DES and a fixed datablock
78 * key [I] key data (7 bytes)
79 * output [O] hashed key (8 bytes)
82 * Success: STATUS_SUCCESS
83 * Failure: STATUS_UNSUCCESSFUL
87 WINAPI
SystemFunction003(const BYTE
*key
, LPBYTE output
)
90 return STATUS_UNSUCCESSFUL
;
91 CRYPT_DEShash(output
, key
, CRYPT_LMhash_Magic
);
92 return STATUS_SUCCESS
;
96 /******************************************************************************
97 * SystemFunction004 [ADVAPI32.@]
99 * Encrypts a block of data with DES in ECB mode, preserving the length
102 * data [I] data to encrypt
103 * key [I] key data (up to 7 bytes)
104 * output [O] buffer to receive encrypted data
107 * Success: STATUS_SUCCESS
108 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
109 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
112 * Encrypt buffer size should be input size rounded up to 8 bytes
113 * plus an extra 8 bytes.
116 WINAPI
SystemFunction004(const struct ustring
*in
,
117 const struct ustring
*key
,
124 unsigned char deskey
[7];
125 unsigned int crypt_len
, ofs
;
128 return STATUS_INVALID_PARAMETER_2
;
130 crypt_len
= ((in
->Length
+7)&~7);
131 if (out
->MaximumLength
< (crypt_len
+8))
132 return STATUS_BUFFER_TOO_SMALL
;
134 data
.ui
[0] = in
->Length
;
137 if (key
->Length
<sizeof deskey
)
139 memset(deskey
, 0, sizeof deskey
);
140 memcpy(deskey
, key
->Buffer
, key
->Length
);
143 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
145 CRYPT_DEShash(out
->Buffer
, deskey
, data
.uc
);
147 for(ofs
=0; ofs
<(crypt_len
-8); ofs
+=8)
148 CRYPT_DEShash(out
->Buffer
+8+ofs
, deskey
, in
->Buffer
+ofs
);
150 memset(data
.uc
, 0, sizeof data
.uc
);
151 memcpy(data
.uc
, in
->Buffer
+ofs
, in
->Length
+8-crypt_len
);
152 CRYPT_DEShash(out
->Buffer
+8+ofs
, deskey
, data
.uc
);
154 out
->Length
= crypt_len
+8;
156 return STATUS_SUCCESS
;
159 /******************************************************************************
160 * SystemFunction005 [ADVAPI32.@]
162 * Decrypts a block of data with DES in ECB mode
165 * data [I] data to decrypt
166 * key [I] key data (up to 7 bytes)
167 * output [O] buffer to receive decrypted data
170 * Success: STATUS_SUCCESS
171 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
172 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
176 WINAPI
SystemFunction005(const struct ustring
*in
,
177 const struct ustring
*key
,
184 unsigned char deskey
[7];
185 unsigned int ofs
, crypt_len
;
188 return STATUS_INVALID_PARAMETER_2
;
190 if (key
->Length
<sizeof deskey
)
192 memset(deskey
, 0, sizeof deskey
);
193 memcpy(deskey
, key
->Buffer
, key
->Length
);
196 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
198 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
);
201 return STATUS_UNKNOWN_REVISION
;
203 crypt_len
= data
.ui
[0];
204 if (crypt_len
> out
->MaximumLength
)
205 return STATUS_BUFFER_TOO_SMALL
;
207 for (ofs
=0; (ofs
+8)<crypt_len
; ofs
+=8)
208 CRYPT_DESunhash(out
->Buffer
+ofs
, deskey
, in
->Buffer
+ofs
+8);
212 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
+ofs
+8);
213 memcpy(out
->Buffer
+ofs
, data
.uc
, crypt_len
-ofs
);
216 out
->Length
= crypt_len
;
218 return STATUS_SUCCESS
;
221 /******************************************************************************
222 * SystemFunction007 [ADVAPI32.@]
224 * MD4 hash a unicode string
227 * string [I] the string to hash
228 * output [O] the md4 hash of the string (16 bytes)
231 * Success: STATUS_SUCCESS
232 * Failure: STATUS_UNSUCCESSFUL
236 WINAPI
SystemFunction007(const UNICODE_STRING
*string
, LPBYTE hash
)
241 MD4Update( &ctx
, (const BYTE
*)string
->Buffer
, string
->Length
);
243 memcpy( hash
, ctx
.digest
, 0x10 );
245 return STATUS_SUCCESS
;
248 /******************************************************************************
249 * SystemFunction008 [ADVAPI32.@]
251 * Creates a LM response from a challenge and a password hash
254 * challenge [I] Challenge from authentication server
255 * hash [I] NTLM hash (from SystemFunction006)
256 * response [O] response to send back to the server
259 * Success: STATUS_SUCCESS
260 * Failure: STATUS_UNSUCCESSFUL
263 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
267 WINAPI
SystemFunction008(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
271 if (!challenge
|| !response
)
272 return STATUS_UNSUCCESSFUL
;
274 memset(key
, 0, sizeof key
);
275 memcpy(key
, hash
, 0x10);
277 CRYPT_DEShash(response
, key
, challenge
);
278 CRYPT_DEShash(response
+8, key
+7, challenge
);
279 CRYPT_DEShash(response
+16, key
+14, challenge
);
281 return STATUS_SUCCESS
;
284 /******************************************************************************
285 * SystemFunction009 [ADVAPI32.@]
287 * Seems to do the same as SystemFunction008...
290 WINAPI
SystemFunction009(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
292 return SystemFunction008(challenge
, hash
, response
);
295 /******************************************************************************
296 * SystemFunction010 [ADVAPI32.@]
297 * SystemFunction011 [ADVAPI32.@]
299 * MD4 hashes 16 bytes of data
302 * unknown [] seems to have no effect on the output
303 * data [I] pointer to data to hash (16 bytes)
304 * output [O] the md4 hash of the data (16 bytes)
307 * Success: STATUS_SUCCESS
308 * Failure: STATUS_UNSUCCESSFUL
312 WINAPI
SystemFunction010(LPVOID unknown
, const BYTE
*data
, LPBYTE hash
)
317 MD4Update( &ctx
, data
, 0x10 );
319 memcpy( hash
, ctx
.digest
, 0x10 );
321 return STATUS_SUCCESS
;
324 /******************************************************************************
325 * SystemFunction012 [ADVAPI32.@]
326 * SystemFunction014 [ADVAPI32.@]
327 * SystemFunction016 [ADVAPI32.@]
328 * SystemFunction018 [ADVAPI32.@]
329 * SystemFunction020 [ADVAPI32.@]
330 * SystemFunction022 [ADVAPI32.@]
332 * Encrypts two DES blocks with two keys
335 * data [I] data to encrypt (16 bytes)
336 * key [I] key data (two lots of 7 bytes)
337 * output [O] buffer to receive encrypted data (16 bytes)
340 * Success: STATUS_SUCCESS
341 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
344 WINAPI
SystemFunction012(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
347 return STATUS_UNSUCCESSFUL
;
349 CRYPT_DEShash(out
, key
, in
);
350 CRYPT_DEShash(out
+8, key
+7, in
+8);
351 return STATUS_SUCCESS
;
354 /******************************************************************************
355 * SystemFunction013 [ADVAPI32.@]
356 * SystemFunction015 [ADVAPI32.@]
357 * SystemFunction017 [ADVAPI32.@]
358 * SystemFunction019 [ADVAPI32.@]
359 * SystemFunction021 [ADVAPI32.@]
360 * SystemFunction023 [ADVAPI32.@]
362 * Decrypts two DES blocks with two keys
365 * data [I] data to decrypt (16 bytes)
366 * key [I] key data (two lots of 7 bytes)
367 * output [O] buffer to receive decrypted data (16 bytes)
370 * Success: STATUS_SUCCESS
371 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
374 WINAPI
SystemFunction013(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
377 return STATUS_UNSUCCESSFUL
;
378 CRYPT_DESunhash(out
, key
, in
);
379 CRYPT_DESunhash(out
+8, key
+7, in
+8);
380 return STATUS_SUCCESS
;
383 /******************************************************************************
384 * SystemFunction024 [ADVAPI32.@]
386 * Encrypts two DES blocks with a 32 bit key...
389 * data [I] data to encrypt (16 bytes)
390 * key [I] key data (4 bytes)
391 * output [O] buffer to receive encrypted data (16 bytes)
394 * Success: STATUS_SUCCESS
397 WINAPI
SystemFunction024(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
401 memcpy(deskey
, key
, 4);
402 memcpy(deskey
+4, key
, 4);
403 memcpy(deskey
+8, key
, 4);
404 memcpy(deskey
+12, key
, 4);
406 CRYPT_DEShash(out
, deskey
, in
);
407 CRYPT_DEShash(out
+8, deskey
+7, in
+8);
409 return STATUS_SUCCESS
;
412 /******************************************************************************
413 * SystemFunction025 [ADVAPI32.@]
415 * Decrypts two DES blocks with a 32 bit key...
418 * data [I] data to encrypt (16 bytes)
419 * key [I] key data (4 bytes)
420 * output [O] buffer to receive encrypted data (16 bytes)
423 * Success: STATUS_SUCCESS
426 WINAPI
SystemFunction025(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
430 memcpy(deskey
, key
, 4);
431 memcpy(deskey
+4, key
, 4);
432 memcpy(deskey
+8, key
, 4);
433 memcpy(deskey
+12, key
, 4);
435 CRYPT_DESunhash(out
, deskey
, in
);
436 CRYPT_DESunhash(out
+8, deskey
+7, in
+8);
438 return STATUS_SUCCESS
;
441 /**********************************************************************
447 SystemFunction028(INT a
, INT b
)
449 //NDRCContextBinding()
450 //SystemFunction034()
451 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
456 /**********************************************************************
462 SystemFunction029(INT a
, INT b
)
464 //I_RpcBindingIsClientLocal()
465 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
470 /******************************************************************************
471 * SystemFunction030 (ADVAPI32.@)
473 * Tests if two blocks of 16 bytes are equal
476 * b1,b2 [I] block of 16 bytes
479 * TRUE if blocks are the same
480 * FALSE if blocks are different
483 WINAPI
SystemFunction030(LPCVOID b1
, LPCVOID b2
)
485 return !memcmp(b1
, b2
, 0x10);
489 /******************************************************************************
490 * SystemFunction032 [ADVAPI32.@]
492 * Encrypts a string data using ARC4
495 * data [I/O] data to encrypt
499 * Success: STATUS_SUCCESS
500 * Failure: STATUS_UNSUCCESSFUL
503 * see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail
506 WINAPI
SystemFunction032(struct ustring
*data
, const struct ustring
*key
)
510 rc4_init(&a4i
, key
->Buffer
, key
->Length
);
511 rc4_crypt(&a4i
, data
->Buffer
, data
->Length
);
513 return STATUS_SUCCESS
;
517 /**********************************************************************
523 SystemFunction033(INT a
, INT b
)
525 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
529 /**********************************************************************
535 SystemFunction034(INT a
, INT b
)
537 //RpcBindingToStringBindingW
538 //I_RpcMapWin32Status
539 //RpcStringBindingParseW
541 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
546 /******************************************************************************
547 * SystemFunction035 (ADVAPI32.@)
550 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem
553 * Stub, always return TRUE.
555 BOOL WINAPI
SystemFunction035(LPCSTR lpszDllFilePath
)
557 //FIXME("%s: stub\n", debugstr_a(lpszDllFilePath));
561 /******************************************************************************
562 * SystemFunction036 (ADVAPI32.@)
564 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
567 * pbBuffer [O] Pointer to memory to receive random bytes.
568 * dwLen [I] Number of random bytes to fetch.
571 * Always TRUE in my tests
575 SystemFunction036(PVOID pbBuffer
, ULONG dwLen
)
577 ////////////////////////////////////////////////////////////////
578 //////////////////// B I G W A R N I N G !!! ////////////////
579 // This function will output numbers based on the tick count. //
580 // It will NOT OUPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!! //
581 ////////////////////////////////////////////////////////////////
587 static ULONG uCounter
= 17;
589 if(!pbBuffer
|| !dwLen
)
591 /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */
595 /* Get the first seed from the performance counter */
596 QueryPerformanceCounter(&time
);
597 dwSeed
= time
.LowPart
^ time
.HighPart
^ RtlUlongByteSwap(uCounter
++);
599 /* We will access the buffer bytewise */
600 pBuffer
= (PBYTE
)pbBuffer
;
604 /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */
605 uPseudoRandom
= RtlRandom(&dwSeed
);
609 /* Get each byte from the pseudo random number and store it in the buffer */
610 *pBuffer
= (BYTE
)(uPseudoRandom
>> 8 * (dwLen
% 4) & 0xFF);
612 } while(--dwLen
% 4);
619 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
623 /******************************************************************************
624 * SystemFunction040 (ADVAPI32.@)
626 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h.
629 * memory [I/O] Pointer to memory to encrypt.
630 * length [I] Length of region to encrypt in bytes.
631 * flags [I] Control whether other processes are able to decrypt the memory.
632 * RTL_ENCRYPT_OPTION_SAME_PROCESS
633 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
634 * RTL_ENCRYPT_OPTION_SAME_LOGON
637 * Success: STATUS_SUCCESS
638 * Failure: NTSTATUS error code
641 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
642 * If flags are specified when encrypting, the same flag value must be given
643 * when decrypting the memory.
645 NTSTATUS WINAPI
SystemFunction040(PVOID memory
, ULONG length
, ULONG flags
)
647 //FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory, length, flags);
648 return STATUS_SUCCESS
;
651 /******************************************************************************
652 * SystemFunction041 (ADVAPI32.@)
654 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h.
657 * memory [I/O] Pointer to memory to decrypt.
658 * length [I] Length of region to decrypt in bytes.
659 * flags [I] Control whether other processes are able to decrypt the memory.
660 * RTL_ENCRYPT_OPTION_SAME_PROCESS
661 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
662 * RTL_ENCRYPT_OPTION_SAME_LOGON
665 * Success: STATUS_SUCCESS
666 * Failure: NTSTATUS error code
669 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
670 * If flags are specified when encrypting, the same flag value must be given
671 * when decrypting the memory.
673 NTSTATUS WINAPI
SystemFunction041(PVOID memory
, ULONG length
, ULONG flags
)
675 //FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory, length, flags);
676 return STATUS_SUCCESS
;