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
16 static const unsigned char CRYPT_LMhash_Magic
[8] =
17 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
19 /******************************************************************************
20 * SystemFunction001 [ADVAPI32.@]
22 * Encrypts a single block of data using DES
25 * data [I] data to encrypt (8 bytes)
26 * key [I] key data (7 bytes)
27 * output [O] the encrypted data (8 bytes)
30 * Success: STATUS_SUCCESS
31 * Failure: STATUS_UNSUCCESSFUL
35 WINAPI
SystemFunction001(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
38 return STATUS_UNSUCCESSFUL
;
39 CRYPT_DEShash(output
, key
, data
);
40 return STATUS_SUCCESS
;
44 /******************************************************************************
45 * SystemFunction002 [ADVAPI32.@]
47 * Decrypts a single block of data using DES
50 * data [I] data to decrypt (8 bytes)
51 * key [I] key data (7 bytes)
52 * output [O] the decrypted data (8 bytes)
55 * Success: STATUS_SUCCESS
56 * Failure: STATUS_UNSUCCESSFUL
60 WINAPI
SystemFunction002(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
63 return STATUS_UNSUCCESSFUL
;
64 CRYPT_DESunhash(output
, key
, data
);
65 return STATUS_SUCCESS
;
69 /******************************************************************************
70 * SystemFunction003 [ADVAPI32.@]
72 * Hashes a key using DES and a fixed datablock
75 * key [I] key data (7 bytes)
76 * output [O] hashed key (8 bytes)
79 * Success: STATUS_SUCCESS
80 * Failure: STATUS_UNSUCCESSFUL
84 WINAPI
SystemFunction003(const BYTE
*key
, LPBYTE output
)
87 return STATUS_UNSUCCESSFUL
;
88 CRYPT_DEShash(output
, key
, CRYPT_LMhash_Magic
);
89 return STATUS_SUCCESS
;
93 /******************************************************************************
94 * SystemFunction004 [ADVAPI32.@]
96 * Encrypts a block of data with DES in ECB mode, preserving the length
99 * data [I] data to encrypt
100 * key [I] key data (up to 7 bytes)
101 * output [O] buffer to receive encrypted data
104 * Success: STATUS_SUCCESS
105 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
106 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
109 * Encrypt buffer size should be input size rounded up to 8 bytes
110 * plus an extra 8 bytes.
113 WINAPI
SystemFunction004(const struct ustring
*in
,
114 const struct ustring
*key
,
121 unsigned char deskey
[7];
122 unsigned int crypt_len
, ofs
;
125 return STATUS_INVALID_PARAMETER_2
;
127 crypt_len
= ((in
->Length
+7)&~7);
128 if (out
->MaximumLength
< (crypt_len
+8))
129 return STATUS_BUFFER_TOO_SMALL
;
131 data
.ui
[0] = in
->Length
;
134 if (key
->Length
<sizeof deskey
)
136 memset(deskey
, 0, sizeof deskey
);
137 memcpy(deskey
, key
->Buffer
, key
->Length
);
140 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
142 CRYPT_DEShash(out
->Buffer
, deskey
, data
.uc
);
144 for(ofs
=0; ofs
<(crypt_len
-8); ofs
+=8)
145 CRYPT_DEShash(out
->Buffer
+8+ofs
, deskey
, in
->Buffer
+ofs
);
147 memset(data
.uc
, 0, sizeof data
.uc
);
148 memcpy(data
.uc
, in
->Buffer
+ofs
, in
->Length
+8-crypt_len
);
149 CRYPT_DEShash(out
->Buffer
+8+ofs
, deskey
, data
.uc
);
151 out
->Length
= crypt_len
+8;
153 return STATUS_SUCCESS
;
156 /******************************************************************************
157 * SystemFunction005 [ADVAPI32.@]
159 * Decrypts a block of data with DES in ECB mode
162 * data [I] data to decrypt
163 * key [I] key data (up to 7 bytes)
164 * output [O] buffer to receive decrypted data
167 * Success: STATUS_SUCCESS
168 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
169 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
173 WINAPI
SystemFunction005(const struct ustring
*in
,
174 const struct ustring
*key
,
181 unsigned char deskey
[7];
182 unsigned int ofs
, crypt_len
;
185 return STATUS_INVALID_PARAMETER_2
;
187 if (key
->Length
<sizeof deskey
)
189 memset(deskey
, 0, sizeof deskey
);
190 memcpy(deskey
, key
->Buffer
, key
->Length
);
193 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
195 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
);
198 return STATUS_UNKNOWN_REVISION
;
200 crypt_len
= data
.ui
[0];
201 if (crypt_len
> out
->MaximumLength
)
202 return STATUS_BUFFER_TOO_SMALL
;
204 for (ofs
=0; (ofs
+8)<crypt_len
; ofs
+=8)
205 CRYPT_DESunhash(out
->Buffer
+ofs
, deskey
, in
->Buffer
+ofs
+8);
209 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
+ofs
+8);
210 memcpy(out
->Buffer
+ofs
, data
.uc
, crypt_len
-ofs
);
213 out
->Length
= crypt_len
;
215 return STATUS_SUCCESS
;
218 /******************************************************************************
219 * SystemFunction007 [ADVAPI32.@]
221 * MD4 hash a unicode string
224 * string [I] the string to hash
225 * output [O] the md4 hash of the string (16 bytes)
228 * Success: STATUS_SUCCESS
229 * Failure: STATUS_UNSUCCESSFUL
233 WINAPI
SystemFunction007(const UNICODE_STRING
*string
, LPBYTE hash
)
238 MD4Update( &ctx
, (const BYTE
*)string
->Buffer
, string
->Length
);
240 memcpy( hash
, ctx
.digest
, 0x10 );
242 return STATUS_SUCCESS
;
245 /******************************************************************************
246 * SystemFunction008 [ADVAPI32.@]
248 * Creates a LM response from a challenge and a password hash
251 * challenge [I] Challenge from authentication server
252 * hash [I] NTLM hash (from SystemFunction006)
253 * response [O] response to send back to the server
256 * Success: STATUS_SUCCESS
257 * Failure: STATUS_UNSUCCESSFUL
260 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
264 WINAPI
SystemFunction008(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
268 if (!challenge
|| !response
)
269 return STATUS_UNSUCCESSFUL
;
271 memset(key
, 0, sizeof key
);
272 memcpy(key
, hash
, 0x10);
274 CRYPT_DEShash(response
, key
, challenge
);
275 CRYPT_DEShash(response
+8, key
+7, challenge
);
276 CRYPT_DEShash(response
+16, key
+14, challenge
);
278 return STATUS_SUCCESS
;
281 /******************************************************************************
282 * SystemFunction009 [ADVAPI32.@]
284 * Seems to do the same as SystemFunction008...
287 WINAPI
SystemFunction009(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
289 return SystemFunction008(challenge
, hash
, response
);
292 /******************************************************************************
293 * SystemFunction010 [ADVAPI32.@]
294 * SystemFunction011 [ADVAPI32.@]
296 * MD4 hashes 16 bytes of data
299 * unknown [] seems to have no effect on the output
300 * data [I] pointer to data to hash (16 bytes)
301 * output [O] the md4 hash of the data (16 bytes)
304 * Success: STATUS_SUCCESS
305 * Failure: STATUS_UNSUCCESSFUL
309 WINAPI
SystemFunction010(LPVOID unknown
, const BYTE
*data
, LPBYTE hash
)
314 MD4Update( &ctx
, data
, 0x10 );
316 memcpy( hash
, ctx
.digest
, 0x10 );
318 return STATUS_SUCCESS
;
321 /******************************************************************************
322 * SystemFunction012 [ADVAPI32.@]
323 * SystemFunction014 [ADVAPI32.@]
324 * SystemFunction016 [ADVAPI32.@]
325 * SystemFunction018 [ADVAPI32.@]
326 * SystemFunction020 [ADVAPI32.@]
327 * SystemFunction022 [ADVAPI32.@]
329 * Encrypts two DES blocks with two keys
332 * data [I] data to encrypt (16 bytes)
333 * key [I] key data (two lots of 7 bytes)
334 * output [O] buffer to receive encrypted data (16 bytes)
337 * Success: STATUS_SUCCESS
338 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
341 WINAPI
SystemFunction012(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
344 return STATUS_UNSUCCESSFUL
;
346 CRYPT_DEShash(out
, key
, in
);
347 CRYPT_DEShash(out
+8, key
+7, in
+8);
348 return STATUS_SUCCESS
;
351 /******************************************************************************
352 * SystemFunction013 [ADVAPI32.@]
353 * SystemFunction015 [ADVAPI32.@]
354 * SystemFunction017 [ADVAPI32.@]
355 * SystemFunction019 [ADVAPI32.@]
356 * SystemFunction021 [ADVAPI32.@]
357 * SystemFunction023 [ADVAPI32.@]
359 * Decrypts two DES blocks with two keys
362 * data [I] data to decrypt (16 bytes)
363 * key [I] key data (two lots of 7 bytes)
364 * output [O] buffer to receive decrypted data (16 bytes)
367 * Success: STATUS_SUCCESS
368 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
371 WINAPI
SystemFunction013(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
374 return STATUS_UNSUCCESSFUL
;
375 CRYPT_DESunhash(out
, key
, in
);
376 CRYPT_DESunhash(out
+8, key
+7, in
+8);
377 return STATUS_SUCCESS
;
380 /******************************************************************************
381 * SystemFunction024 [ADVAPI32.@]
383 * Encrypts two DES blocks with a 32 bit key...
386 * data [I] data to encrypt (16 bytes)
387 * key [I] key data (4 bytes)
388 * output [O] buffer to receive encrypted data (16 bytes)
391 * Success: STATUS_SUCCESS
394 WINAPI
SystemFunction024(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
398 memcpy(deskey
, key
, 4);
399 memcpy(deskey
+4, key
, 4);
400 memcpy(deskey
+8, key
, 4);
401 memcpy(deskey
+12, key
, 4);
403 CRYPT_DEShash(out
, deskey
, in
);
404 CRYPT_DEShash(out
+8, deskey
+7, in
+8);
406 return STATUS_SUCCESS
;
409 /******************************************************************************
410 * SystemFunction025 [ADVAPI32.@]
412 * Decrypts two DES blocks with a 32 bit key...
415 * data [I] data to encrypt (16 bytes)
416 * key [I] key data (4 bytes)
417 * output [O] buffer to receive encrypted data (16 bytes)
420 * Success: STATUS_SUCCESS
423 WINAPI
SystemFunction025(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
427 memcpy(deskey
, key
, 4);
428 memcpy(deskey
+4, key
, 4);
429 memcpy(deskey
+8, key
, 4);
430 memcpy(deskey
+12, key
, 4);
432 CRYPT_DESunhash(out
, deskey
, in
);
433 CRYPT_DESunhash(out
+8, deskey
+7, in
+8);
435 return STATUS_SUCCESS
;
438 /**********************************************************************
444 SystemFunction028(INT a
, INT b
)
446 //NDRCContextBinding()
447 //SystemFunction034()
448 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
453 /**********************************************************************
459 SystemFunction029(INT a
, INT b
)
461 //I_RpcBindingIsClientLocal()
462 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
467 /******************************************************************************
468 * SystemFunction030 (ADVAPI32.@)
470 * Tests if two blocks of 16 bytes are equal
473 * b1,b2 [I] block of 16 bytes
476 * TRUE if blocks are the same
477 * FALSE if blocks are different
480 WINAPI
SystemFunction030(PVOID b1
, PVOID b2
)
482 return !memcmp(b1
, b2
, 0x10);
486 /******************************************************************************
487 * SystemFunction032 [ADVAPI32.@]
489 * Encrypts a string data using ARC4
492 * data [I/O] data to encrypt
496 * Success: STATUS_SUCCESS
497 * Failure: STATUS_UNSUCCESSFUL
500 * see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail
503 WINAPI
SystemFunction032(struct ustring
*data
, struct ustring
*key
)
507 arc4_init(&a4i
, key
->Buffer
, key
->Length
);
508 arc4_ProcessString(&a4i
, data
->Buffer
, data
->Length
);
510 return STATUS_SUCCESS
;
514 /**********************************************************************
520 SystemFunction033(INT a
, INT b
)
522 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
526 /**********************************************************************
532 SystemFunction034(INT a
, INT b
)
534 //RpcBindingToStringBindingW
535 //I_RpcMapWin32Status
536 //RpcStringBindingParseW
538 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
543 /**********************************************************************
549 SystemFunction035(LPCSTR lpszDllFilePath
)
554 /******************************************************************************
555 * SystemFunction036 (ADVAPI32.@)
557 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
560 * pbBuffer [O] Pointer to memory to receive random bytes.
561 * dwLen [I] Number of random bytes to fetch.
564 * Always TRUE in my tests
568 SystemFunction036(PVOID pbBuffer
, ULONG dwLen
)
570 ////////////////////////////////////////////////////////////////
571 //////////////////// B I G W A R N I N G !!! ////////////////
572 // This function will output numbers based on the tick count. //
573 // It will NOT OUPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!! //
574 ////////////////////////////////////////////////////////////////
580 static ULONG uCounter
= 17;
582 if(!pbBuffer
|| !dwLen
)
584 /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */
588 /* Get the first seed from the performance counter */
589 QueryPerformanceCounter(&time
);
590 dwSeed
= time
.LowPart
^ time
.HighPart
^ RtlUlongByteSwap(uCounter
++);
592 /* We will access the buffer bytewise */
593 pBuffer
= (PBYTE
)pbBuffer
;
597 /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */
598 uPseudoRandom
= RtlRandom(&dwSeed
);
602 /* Get each byte from the pseudo random number and store it in the buffer */
603 *pBuffer
= (BYTE
)(uPseudoRandom
>> 8 * (dwLen
% 4) & 0xFF);
605 } while(--dwLen
% 4);
612 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
616 /******************************************************************************
617 * SystemFunction040 (ADVAPI32.@)
620 * memory : pointer to memory to encrypt
621 * length : length of region to encrypt, in bytes. must be multiple of RTL_ENCRYPT_MEMORY_SIZE
622 * flags : RTL_ENCRYPT_OPTION_SAME_PROCESS | RTL_ENCRYPT_OPTION_CROSS_PROCESS, | RTL_ENCRYPT_OPTION_SAME_LOGON
623 * control whether other processes are able to decrypt the memory. The same value must be given
624 * when decrypting the memory.
626 NTSTATUS WINAPI
SystemFunction040(PVOID memory
, ULONG length
, ULONG flags
) /* RtlEncryptMemory */
628 //FIXME("(%p, %lx, %lx): stub [RtlEncryptMemory]\n", memory, length, flags);
629 return STATUS_SUCCESS
;
632 /******************************************************************************
633 * SystemFunction041 (ADVAPI32.@)
636 * memory : pointer to memory to decrypt
637 * length : length of region to decrypt, in bytes. must be multiple of RTL_ENCRYPT_MEMORY_SIZE
638 * flags : RTL_ENCRYPT_OPTION_SAME_PROCESS | RTL_ENCRYPT_OPTION_CROSS_PROCESS, | RTL_ENCRYPT_OPTION_SAME_LOGON
639 * control whether other processes are able to decrypt the memory. The same value must be given
640 * when encrypting the memory.
642 NTSTATUS WINAPI
SystemFunction041(PVOID memory
, ULONG length
, ULONG flags
) /* RtlDecryptMemory */
644 //FIXME("(%p, %lx, %lx): stub [RtlDecryptMemory]\n", memory, length, flags);
645 return STATUS_SUCCESS
;