Mike McCormack : advapi32: Implement and test SystemFunction002 (
DES decrypt).
Alexandre Julliard
julliard at wine.codeweavers.com
Mon May 15 07:34:55 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 50ed147db04172f428af8bb123fa9b64d0845934
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=50ed147db04172f428af8bb123fa9b64d0845934
Author: Mike McCormack <mike at codeweavers.com>
Date: Fri May 12 00:47:39 2006 +0900
advapi32: Implement and test SystemFunction002 (DES decrypt).
---
dlls/advapi32/advapi32.spec | 2 -
dlls/advapi32/crypt.h | 2 +
dlls/advapi32/crypt_des.c | 77 +++++++++++++++++++++++++++++++++++-
dlls/advapi32/crypt_lmhash.c | 23 +++++++++++
dlls/advapi32/tests/crypt_lmhash.c | 23 ++++++++++-
5 files changed, 122 insertions(+), 5 deletions(-)
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index c824421..cb747b0 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -596,7 +596,7 @@ # @ stub StopTraceA
# @ stub StopTraceW
@ stdcall SynchronizeWindows31FilesAndWindowsNTRegistry(long long long long)
@ stdcall SystemFunction001(ptr ptr ptr)
-@ stub SystemFunction002
+@ stdcall SystemFunction002(ptr ptr ptr)
@ stub SystemFunction003
@ stub SystemFunction004
@ stub SystemFunction005
diff --git a/dlls/advapi32/crypt.h b/dlls/advapi32/crypt.h
index f5696e6..207ef5d 100644
--- a/dlls/advapi32/crypt.h
+++ b/dlls/advapi32/crypt.h
@@ -85,5 +85,7 @@ #define MAXPROVTYPES 999
extern unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key );
extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key,
const unsigned char *src );
+extern unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key,
+ const unsigned char *src );
#endif /* __WINE_CRYPT_H_ */
diff --git a/dlls/advapi32/crypt_des.c b/dlls/advapi32/crypt_des.c
index 4b527dd..c2d6e9f 100644
--- a/dlls/advapi32/crypt_des.c
+++ b/dlls/advapi32/crypt_des.c
@@ -1,5 +1,6 @@
/*
* Copyright 2004 Hans Leidekker
+ * Copyright 2006 Mike McCormack
*
* Based on DES.c from libcifs
*
@@ -159,9 +160,9 @@ static void Permute( unsigned char *dst,
if (GETBIT( src, map[i] ))
SETBIT( dst, i );
}
-}
+}
-static void KeyShift( unsigned char *key, const int numbits )
+static void KeyShiftLeft( unsigned char *key, const int numbits )
{
int i;
unsigned char keep = key[0];
@@ -190,6 +191,35 @@ static void KeyShift( unsigned char *key
}
}
+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 )
{
int i;
@@ -267,7 +297,7 @@ unsigned char *CRYPT_DEShash( unsigned c
unsigned char Rn[4];
unsigned char SubK[6];
- KeyShift( K, KeyRotation[i] );
+ KeyShiftLeft( K, KeyRotation[i] );
Permute( SubK, K, KeyCompression, 6 );
Permute( Rexp, R, DataExpansion, 6 );
@@ -288,3 +318,44 @@ unsigned char *CRYPT_DEShash( unsigned c
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;
+}
diff --git a/dlls/advapi32/crypt_lmhash.c b/dlls/advapi32/crypt_lmhash.c
index 01f6049..85e29fb 100644
--- a/dlls/advapi32/crypt_lmhash.c
+++ b/dlls/advapi32/crypt_lmhash.c
@@ -112,3 +112,26 @@ NTSTATUS WINAPI SystemFunction001(const
CRYPT_DEShash(output, key, data);
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;
+}
diff --git a/dlls/advapi32/tests/crypt_lmhash.c b/dlls/advapi32/tests/crypt_lmhash.c
index 0e45ddc..c0353d3 100644
--- a/dlls/advapi32/tests/crypt_lmhash.c
+++ b/dlls/advapi32/tests/crypt_lmhash.c
@@ -37,11 +37,13 @@ struct ustring {
typedef VOID (WINAPI *fnSystemFunction006)( PCSTR passwd, PSTR lmhash );
typedef NTSTATUS (WINAPI *fnSystemFunction008)(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 *);
fnSystemFunction006 pSystemFunction006;
fnSystemFunction008 pSystemFunction008;
fnSystemFunction001 pSystemFunction001;
+fnSystemFunction002 pSystemFunction002;
fnSystemFunction032 pSystemFunction032;
static void test_SystemFunction006(void)
@@ -122,6 +124,21 @@ static void test_SystemFunction001(void)
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)
{
struct ustring key, data;
@@ -143,7 +160,7 @@ static void test_SystemFunction032(void)
r = pSystemFunction032(&data, &key);
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)
@@ -168,5 +185,9 @@ START_TEST(crypt_lmhash)
if (pSystemFunction032)
test_SystemFunction032();
+ pSystemFunction002 = (fnSystemFunction002)GetProcAddress( module, "SystemFunction002" );
+ if (pSystemFunction002)
+ test_SystemFunction002();
+
FreeLibrary( module );
}
More information about the wine-cvs
mailing list