advapi32: Implement and test SystemFunction004.
This commit is contained in:
parent
09fc7e046a
commit
dcfb0f44d1
@ -598,7 +598,7 @@
|
|||||||
@ stdcall SystemFunction001(ptr ptr ptr)
|
@ stdcall SystemFunction001(ptr ptr ptr)
|
||||||
@ stdcall SystemFunction002(ptr ptr ptr)
|
@ stdcall SystemFunction002(ptr ptr ptr)
|
||||||
@ stdcall SystemFunction003(ptr ptr)
|
@ stdcall SystemFunction003(ptr ptr)
|
||||||
@ stub SystemFunction004
|
@ stdcall SystemFunction004(ptr ptr ptr)
|
||||||
@ stub SystemFunction005
|
@ stub SystemFunction005
|
||||||
@ stdcall SystemFunction006(ptr ptr)
|
@ stdcall SystemFunction006(ptr ptr)
|
||||||
@ stdcall SystemFunction007(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,
|
extern unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key,
|
||||||
const unsigned char *src );
|
const unsigned char *src );
|
||||||
|
|
||||||
|
struct ustring {
|
||||||
|
DWORD Length;
|
||||||
|
DWORD MaximumLength;
|
||||||
|
unsigned char *Buffer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __WINE_CRYPT_H_ */
|
#endif /* __WINE_CRYPT_H_ */
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
|
||||||
|
#include "crypt.h"
|
||||||
|
|
||||||
typedef struct tag_arc4_info {
|
typedef struct tag_arc4_info {
|
||||||
unsigned char state[256];
|
unsigned char state[256];
|
||||||
unsigned char x, y;
|
unsigned char x, y;
|
||||||
@ -76,12 +78,6 @@ static void arc4_ProcessString(arc4_info *a4i, BYTE *inoutString, unsigned int l
|
|||||||
a4i->y = y;
|
a4i->y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ustring {
|
|
||||||
DWORD Length;
|
|
||||||
DWORD MaximumLength;
|
|
||||||
unsigned char *Buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* SystemFunction032 [ADVAPI32.@]
|
* SystemFunction032 [ADVAPI32.@]
|
||||||
*
|
*
|
||||||
|
@ -157,3 +157,65 @@ NTSTATUS WINAPI SystemFunction003(const LPBYTE key, LPBYTE output)
|
|||||||
CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
|
CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
|
||||||
return STATUS_SUCCESS;
|
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 *fnSystemFunction001)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||||
typedef NTSTATUS (WINAPI *fnSystemFunction002)(const LPBYTE, const LPBYTE, LPBYTE);
|
typedef NTSTATUS (WINAPI *fnSystemFunction002)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||||
typedef NTSTATUS (WINAPI *fnSystemFunction003)(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 VOID (WINAPI *fnSystemFunction006)( PCSTR passwd, PSTR lmhash );
|
||||||
typedef NTSTATUS (WINAPI *fnSystemFunction008)(const LPBYTE, const LPBYTE, LPBYTE);
|
typedef NTSTATUS (WINAPI *fnSystemFunction008)(const LPBYTE, const LPBYTE, LPBYTE);
|
||||||
typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring *);
|
typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring *);
|
||||||
@ -44,6 +45,7 @@ typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring
|
|||||||
fnSystemFunction001 pSystemFunction001;
|
fnSystemFunction001 pSystemFunction001;
|
||||||
fnSystemFunction002 pSystemFunction002;
|
fnSystemFunction002 pSystemFunction002;
|
||||||
fnSystemFunction003 pSystemFunction003;
|
fnSystemFunction003 pSystemFunction003;
|
||||||
|
fnSystemFunction004 pSystemFunction004;
|
||||||
fnSystemFunction006 pSystemFunction006;
|
fnSystemFunction006 pSystemFunction006;
|
||||||
fnSystemFunction008 pSystemFunction008;
|
fnSystemFunction008 pSystemFunction008;
|
||||||
fnSystemFunction032 pSystemFunction032;
|
fnSystemFunction032 pSystemFunction032;
|
||||||
@ -190,6 +192,88 @@ static void test_SystemFunction003(void)
|
|||||||
ok( !memcmp(exp2, output, sizeof output), "decrypted message wrong\n");
|
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)
|
START_TEST(crypt_lmhash)
|
||||||
{
|
{
|
||||||
HMODULE module;
|
HMODULE module;
|
||||||
@ -208,6 +292,10 @@ START_TEST(crypt_lmhash)
|
|||||||
if (pSystemFunction003)
|
if (pSystemFunction003)
|
||||||
test_SystemFunction003();
|
test_SystemFunction003();
|
||||||
|
|
||||||
|
pSystemFunction004 = (fnSystemFunction004)GetProcAddress( module, "SystemFunction004" );
|
||||||
|
if (pSystemFunction004)
|
||||||
|
test_SystemFunction004();
|
||||||
|
|
||||||
pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" );
|
pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" );
|
||||||
if (pSystemFunction006)
|
if (pSystemFunction006)
|
||||||
test_SystemFunction006();
|
test_SystemFunction006();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user