advapi32: Implement and test SystemFunction004.
This commit is contained in:
parent
09fc7e046a
commit
dcfb0f44d1
|
@ -598,7 +598,7 @@
|
|||
@ stdcall SystemFunction001(ptr ptr ptr)
|
||||
@ stdcall SystemFunction002(ptr ptr ptr)
|
||||
@ stdcall SystemFunction003(ptr ptr)
|
||||
@ stub SystemFunction004
|
||||
@ stdcall SystemFunction004(ptr ptr ptr)
|
||||
@ stub SystemFunction005
|
||||
@ stdcall SystemFunction006(ptr ptr)
|
||||
@ stdcall SystemFunction007(ptr ptr)
|
||||
|
|
|
@ -88,4 +88,10 @@ extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *ke
|
|||
extern unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key,
|
||||
const unsigned char *src );
|
||||
|
||||
struct ustring {
|
||||
DWORD Length;
|
||||
DWORD MaximumLength;
|
||||
unsigned char *Buffer;
|
||||
};
|
||||
|
||||
#endif /* __WINE_CRYPT_H_ */
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "crypt.h"
|
||||
|
||||
typedef struct tag_arc4_info {
|
||||
unsigned char state[256];
|
||||
unsigned char x, y;
|
||||
|
@ -76,12 +78,6 @@ static void arc4_ProcessString(arc4_info *a4i, BYTE *inoutString, unsigned int l
|
|||
a4i->y = y;
|
||||
}
|
||||
|
||||
struct ustring {
|
||||
DWORD Length;
|
||||
DWORD MaximumLength;
|
||||
unsigned char *Buffer;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* SystemFunction032 [ADVAPI32.@]
|
||||
*
|
||||
|
|
|
@ -157,3 +157,65 @@ NTSTATUS WINAPI SystemFunction003(const LPBYTE key, LPBYTE output)
|
|||
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.
|
||||
*/
|
||||
NTSTATUS WINAPI 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];
|
||||
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))
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ struct ustring {
|
|||
typedef NTSTATUS (WINAPI *fnSystemFunction001)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||
typedef NTSTATUS (WINAPI *fnSystemFunction002)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||
typedef NTSTATUS (WINAPI *fnSystemFunction003)(const LPBYTE, LPBYTE);
|
||||
typedef NTSTATUS (WINAPI *fnSystemFunction004)(const struct ustring *, const struct ustring *, struct ustring *);
|
||||
typedef VOID (WINAPI *fnSystemFunction006)( PCSTR passwd, PSTR lmhash );
|
||||
typedef NTSTATUS (WINAPI *fnSystemFunction008)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||
typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring *);
|
||||
|
@ -44,6 +45,7 @@ typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring
|
|||
fnSystemFunction001 pSystemFunction001;
|
||||
fnSystemFunction002 pSystemFunction002;
|
||||
fnSystemFunction003 pSystemFunction003;
|
||||
fnSystemFunction004 pSystemFunction004;
|
||||
fnSystemFunction006 pSystemFunction006;
|
||||
fnSystemFunction008 pSystemFunction008;
|
||||
fnSystemFunction032 pSystemFunction032;
|
||||
|
@ -190,6 +192,88 @@ static void test_SystemFunction003(void)
|
|||
ok( !memcmp(exp2, output, sizeof output), "decrypted message wrong\n");
|
||||
}
|
||||
|
||||
static void test_SystemFunction004(void)
|
||||
{
|
||||
unsigned char inbuf[0x100], keybuf[0x100], resbuf[0x100];
|
||||
unsigned char output[8];
|
||||
int r;
|
||||
struct ustring in, key, out;
|
||||
|
||||
/* crash
|
||||
r = pSystemFunction004(NULL, NULL, NULL);
|
||||
ok(r == STATUS_UNSUCCESSFUL, "function failed\n");
|
||||
*/
|
||||
|
||||
memset(inbuf, 0, sizeof inbuf);
|
||||
memset(keybuf, 0, sizeof keybuf);
|
||||
memset(resbuf, 0, sizeof resbuf);
|
||||
|
||||
in.Buffer = NULL;
|
||||
in.Length = in.MaximumLength = 0;
|
||||
|
||||
key.Buffer = NULL;
|
||||
key.Length = key.MaximumLength = 0;
|
||||
|
||||
out.Buffer = NULL;
|
||||
out.Length = out.MaximumLength = 0;
|
||||
|
||||
r = pSystemFunction004(&in, &key, &out);
|
||||
ok(r == STATUS_INVALID_PARAMETER_2, "function failed\n");
|
||||
|
||||
key.Buffer = keybuf;
|
||||
key.Length = 0x100;
|
||||
key.MaximumLength = 0x100;
|
||||
|
||||
r = pSystemFunction004(&in, &key, (struct ustring *)&out);
|
||||
ok(r == STATUS_BUFFER_TOO_SMALL, "function failed\n");
|
||||
|
||||
in.Buffer = inbuf;
|
||||
in.Length = 0x0c;
|
||||
in.MaximumLength = 0;
|
||||
|
||||
/* add two identical blocks... */
|
||||
inbuf[0] = 1;
|
||||
inbuf[1] = 2;
|
||||
inbuf[2] = 3;
|
||||
inbuf[3] = 4;
|
||||
|
||||
inbuf[8] = 1;
|
||||
inbuf[9] = 2;
|
||||
inbuf[10] = 3;
|
||||
inbuf[11] = 4;
|
||||
|
||||
/* check that the Length field is really obeyed */
|
||||
keybuf[6] = 1;
|
||||
|
||||
key.Buffer = keybuf;
|
||||
key.Length = 6;
|
||||
key.MaximumLength = 0;
|
||||
|
||||
keybuf[1] = 0x33;
|
||||
|
||||
out.Buffer = resbuf;
|
||||
out.Length = 0;
|
||||
out.MaximumLength = 0x40;
|
||||
r = pSystemFunction004(&in, &key, &out);
|
||||
ok(r == STATUS_SUCCESS, "function failed\n");
|
||||
|
||||
keybuf[6] = 0;
|
||||
|
||||
memset(output, 0, sizeof output);
|
||||
r = pSystemFunction002(out.Buffer, key.Buffer, output);
|
||||
|
||||
ok(((unsigned int*)output)[0] == in.Length, "crypted length wrong\n");
|
||||
ok(((unsigned int*)output)[1] == 1, "crypted value wrong\n");
|
||||
|
||||
memset(output, 0, sizeof output);
|
||||
r = pSystemFunction002(out.Buffer+8, key.Buffer, output);
|
||||
ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n");
|
||||
|
||||
memset(output, 0, sizeof output);
|
||||
r = pSystemFunction002(out.Buffer+16, key.Buffer, output);
|
||||
ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n");
|
||||
}
|
||||
|
||||
START_TEST(crypt_lmhash)
|
||||
{
|
||||
HMODULE module;
|
||||
|
@ -208,6 +292,10 @@ START_TEST(crypt_lmhash)
|
|||
if (pSystemFunction003)
|
||||
test_SystemFunction003();
|
||||
|
||||
pSystemFunction004 = (fnSystemFunction004)GetProcAddress( module, "SystemFunction004" );
|
||||
if (pSystemFunction004)
|
||||
test_SystemFunction004();
|
||||
|
||||
pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" );
|
||||
if (pSystemFunction006)
|
||||
test_SystemFunction006();
|
||||
|
|
Loading…
Reference in New Issue