advapi32: Implement and test SystemFunction005.

This commit is contained in:
Mike McCormack 2006-05-15 22:03:41 +09:00 committed by Alexandre Julliard
parent b96d630022
commit 9b3d8a3527
3 changed files with 125 additions and 1 deletions

View File

@ -599,7 +599,7 @@
@ stdcall SystemFunction002(ptr ptr ptr)
@ stdcall SystemFunction003(ptr ptr)
@ stdcall SystemFunction004(ptr ptr ptr)
@ stub SystemFunction005
@ stdcall SystemFunction005(ptr ptr ptr)
@ stdcall SystemFunction006(ptr ptr)
@ stdcall SystemFunction007(ptr ptr)
@ stdcall SystemFunction008(ptr ptr ptr)

View File

@ -219,3 +219,64 @@ NTSTATUS WINAPI SystemFunction004(const struct ustring *in,
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
*
*/
NTSTATUS WINAPI 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];
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)
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;
}

View File

@ -38,6 +38,7 @@ typedef NTSTATUS (WINAPI *fnSystemFunction001)(const LPBYTE, const LPBYTE, LPBYT
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 NTSTATUS (WINAPI *fnSystemFunction005)(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 *);
@ -46,6 +47,7 @@ fnSystemFunction001 pSystemFunction001;
fnSystemFunction002 pSystemFunction002;
fnSystemFunction003 pSystemFunction003;
fnSystemFunction004 pSystemFunction004;
fnSystemFunction004 pSystemFunction005;
fnSystemFunction006 pSystemFunction006;
fnSystemFunction008 pSystemFunction008;
fnSystemFunction032 pSystemFunction032;
@ -274,6 +276,63 @@ static void test_SystemFunction004(void)
ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n");
}
static void test_SystemFunction005(void)
{
char output[0x40], result[0x40];
int r;
struct ustring in, key, out, res;
char *datastr = "twinkle twinkle little star";
char *keystr = "byolnim";
in.Buffer = (unsigned char *) datastr;
in.Length = strlen(datastr);
in.MaximumLength = 0;
key.Buffer = (unsigned char *)keystr;
key.Length = strlen(keystr);
key.MaximumLength = 0;
out.Buffer = (unsigned char *)output;
out.Length = out.MaximumLength = sizeof output;
r = pSystemFunction004(&in, &key, &out);
ok(r == STATUS_SUCCESS, "function failed\n");
memset(result, 0, sizeof result);
res.Buffer = (unsigned char *)result;
res.Length = 0;
res.MaximumLength = sizeof result;
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_SUCCESS, "function failed\n");
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_SUCCESS, "function failed\n");
ok(res.Length == in.Length, "Length wrong\n");
ok(!memcmp(res.Buffer, in.Buffer, in.Length), "data wrong\n");
out.Length = 0;
out.MaximumLength = 0;
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_SUCCESS, "function failed\n");
ok(res.Length == in.Length, "Length wrong\n");
ok(!memcmp(res.Buffer, in.Buffer, in.Length), "data wrong\n");
res.MaximumLength = 0;
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_BUFFER_TOO_SMALL, "function failed\n");
key.Length = 1;
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_UNKNOWN_REVISION, "function failed\n");
key.Length = 0;
r = pSystemFunction005(&out, &key, &res);
ok(r == STATUS_INVALID_PARAMETER_2, "function failed\n");
}
START_TEST(crypt_lmhash)
{
HMODULE module;
@ -296,6 +355,10 @@ START_TEST(crypt_lmhash)
if (pSystemFunction004)
test_SystemFunction004();
pSystemFunction005 = (fnSystemFunction005)GetProcAddress( module, "SystemFunction005" );
if (pSystemFunction005)
test_SystemFunction005();
pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" );
if (pSystemFunction006)
test_SystemFunction006();