Commit 50ed147d authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

advapi32: Implement and test SystemFunction002 (DES decrypt).

parent eaec7793
...@@ -596,7 +596,7 @@ ...@@ -596,7 +596,7 @@
# @ stub StopTraceW # @ stub StopTraceW
@ stdcall SynchronizeWindows31FilesAndWindowsNTRegistry(long long long long) @ stdcall SynchronizeWindows31FilesAndWindowsNTRegistry(long long long long)
@ stdcall SystemFunction001(ptr ptr ptr) @ stdcall SystemFunction001(ptr ptr ptr)
@ stub SystemFunction002 @ stdcall SystemFunction002(ptr ptr ptr)
@ stub SystemFunction003 @ stub SystemFunction003
@ stub SystemFunction004 @ stub SystemFunction004
@ stub SystemFunction005 @ stub SystemFunction005
......
...@@ -85,5 +85,7 @@ typedef struct tagCRYPTHASH ...@@ -85,5 +85,7 @@ typedef struct tagCRYPTHASH
extern unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key ); extern unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key );
extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key,
const unsigned char *src ); const unsigned char *src );
extern unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key,
const unsigned char *src );
#endif /* __WINE_CRYPT_H_ */ #endif /* __WINE_CRYPT_H_ */
/* /*
* Copyright 2004 Hans Leidekker * Copyright 2004 Hans Leidekker
* Copyright 2006 Mike McCormack
* *
* Based on DES.c from libcifs * Based on DES.c from libcifs
* *
...@@ -159,9 +160,9 @@ static void Permute( unsigned char *dst, const unsigned char *src, const unsigne ...@@ -159,9 +160,9 @@ static void Permute( unsigned char *dst, const unsigned char *src, const unsigne
if (GETBIT( src, map[i] )) if (GETBIT( src, map[i] ))
SETBIT( dst, i ); SETBIT( dst, i );
} }
} }
static void KeyShift( unsigned char *key, const int numbits ) static void KeyShiftLeft( unsigned char *key, const int numbits )
{ {
int i; int i;
unsigned char keep = key[0]; unsigned char keep = key[0];
...@@ -190,6 +191,35 @@ static void KeyShift( unsigned char *key, const int numbits ) ...@@ -190,6 +191,35 @@ static void KeyShift( unsigned char *key, const int numbits )
} }
} }
static void KeyShiftRight( unsigned char *key, const int numbits )
{
int i;
unsigned char keep = key[6];
for (i = 0; i < numbits; i++)
{
int j;
for (j = 7; j >= 0; j--)
{
if (j!=7 && (key[j] & 0x01))
key[j+1] |= 0x80;
key[j] >>= 1;
}
if (GETBIT( key, 28 ))
{
CLRBIT( key, 28 );
SETBIT( key, 0 );
}
if (keep & 0x01)
SETBIT( key, 28 );
keep >>= 1;
}
}
static void sbox( unsigned char *dst, const unsigned char *src ) static void sbox( unsigned char *dst, const unsigned char *src )
{ {
int i; int i;
...@@ -267,7 +297,7 @@ unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, cons ...@@ -267,7 +297,7 @@ unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, cons
unsigned char Rn[4]; unsigned char Rn[4];
unsigned char SubK[6]; unsigned char SubK[6];
KeyShift( K, KeyRotation[i] ); KeyShiftLeft( K, KeyRotation[i] );
Permute( SubK, K, KeyCompression, 6 ); Permute( SubK, K, KeyCompression, 6 );
Permute( Rexp, R, DataExpansion, 6 ); Permute( Rexp, R, DataExpansion, 6 );
...@@ -288,3 +318,44 @@ unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, cons ...@@ -288,3 +318,44 @@ unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, cons
return dst; return dst;
} }
unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
{
int i;
unsigned char K[7];
unsigned char D[8];
Permute( K, key, KeyPermuteMap, 7 );
Permute( D, src, InitialPermuteMap, 8 );
for (i = 0; i < 16; i++)
{
int j;
unsigned char *L = D;
unsigned char *R = &(D[4]);
unsigned char Rexp[6];
unsigned char Rn[4];
unsigned char SubK[6];
Permute( SubK, K, KeyCompression, 6 );
Permute( Rexp, R, DataExpansion, 6 );
xor( Rexp, Rexp, SubK, 6 );
sbox( Rn, Rexp );
Permute( Rexp, Rn, PBox, 4 );
xor( Rn, L, Rexp, 4 );
for (j = 0; j < 4; j++)
{
L[j] = R[j];
R[j] = Rn[j];
}
KeyShiftRight( K, KeyRotation[15 - i] );
}
Permute( dst, D, FinalPermuteMap, 8 );
return dst;
}
...@@ -112,3 +112,26 @@ NTSTATUS WINAPI SystemFunction001(const LPBYTE data, const LPBYTE key, LPBYTE ou ...@@ -112,3 +112,26 @@ NTSTATUS WINAPI SystemFunction001(const LPBYTE data, const LPBYTE key, LPBYTE ou
CRYPT_DEShash(output, key, data); CRYPT_DEShash(output, key, data);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/******************************************************************************
* SystemFunction002 [ADVAPI32.@]
*
* Decrypts a single block of data using DES
*
* PARAMS
* data [I] data to decrypt (8 bytes)
* key [I] key data (7 bytes)
* output [O] the decrypted data (8 bytes)
*
* RETURNS
* Success: STATUS_SUCCESS
* Failure: STATUS_UNSUCCESSFUL
*
*/
NTSTATUS WINAPI SystemFunction002(const LPBYTE data, const LPBYTE key, LPBYTE output)
{
if (!data || !output)
return STATUS_UNSUCCESSFUL;
CRYPT_DESunhash(output, key, data);
return STATUS_SUCCESS;
}
...@@ -37,11 +37,13 @@ struct ustring { ...@@ -37,11 +37,13 @@ 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 *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 *fnSystemFunction032)(struct ustring *, struct ustring *); typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring *);
fnSystemFunction006 pSystemFunction006; fnSystemFunction006 pSystemFunction006;
fnSystemFunction008 pSystemFunction008; fnSystemFunction008 pSystemFunction008;
fnSystemFunction001 pSystemFunction001; fnSystemFunction001 pSystemFunction001;
fnSystemFunction002 pSystemFunction002;
fnSystemFunction032 pSystemFunction032; fnSystemFunction032 pSystemFunction032;
static void test_SystemFunction006(void) static void test_SystemFunction006(void)
...@@ -122,6 +124,21 @@ static void test_SystemFunction001(void) ...@@ -122,6 +124,21 @@ static void test_SystemFunction001(void)
ok(!memcmp(output, expected, sizeof expected), "response wrong\n"); ok(!memcmp(output, expected, sizeof expected), "response wrong\n");
} }
static void test_SystemFunction002(void)
{
/* reverse of SystemFunction001 */
unsigned char key[8] = { 0xff, 0x37, 0x50, 0xbc, 0xc2, 0xb2, 0x24, 0 };
unsigned char expected[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
unsigned char data[8] = { 0xc3, 0x37, 0xcd, 0x5c, 0xbd, 0x44, 0xfc, 0x97 };
unsigned char output[8];
int r;
memset(output, 0, sizeof output);
r = pSystemFunction002(data, key, output);
ok(r == STATUS_SUCCESS, "function failed\n");
ok(!memcmp(output, expected, sizeof expected), "response wrong\n");
}
static void test_SystemFunction032(void) static void test_SystemFunction032(void)
{ {
struct ustring key, data; struct ustring key, data;
...@@ -143,7 +160,7 @@ static void test_SystemFunction032(void) ...@@ -143,7 +160,7 @@ static void test_SystemFunction032(void)
r = pSystemFunction032(&data, &key); r = pSystemFunction032(&data, &key);
ok(r == STATUS_SUCCESS, "function failed\n"); ok(r == STATUS_SUCCESS, "function failed\n");
ok( !memcmp(expected, data.Buffer, data.Length), "wrong result\n"); ok(!memcmp(expected, data.Buffer, data.Length), "wrong result\n");
} }
START_TEST(crypt_lmhash) START_TEST(crypt_lmhash)
...@@ -168,5 +185,9 @@ START_TEST(crypt_lmhash) ...@@ -168,5 +185,9 @@ START_TEST(crypt_lmhash)
if (pSystemFunction032) if (pSystemFunction032)
test_SystemFunction032(); test_SystemFunction032();
pSystemFunction002 = (fnSystemFunction002)GetProcAddress( module, "SystemFunction002" );
if (pSystemFunction002)
test_SystemFunction002();
FreeLibrary( module ); FreeLibrary( module );
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment