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