Mike McCormack : advapi32: Implement and test SystemFunction032 ( arc4 encryption).

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 10 12:57:04 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 9e37591d209362f2aa174b3459a94590740188af
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=9e37591d209362f2aa174b3459a94590740188af

Author: Mike McCormack <mike at codeweavers.com>
Date:   Wed May 10 21:41:48 2006 +0900

advapi32: Implement and test SystemFunction032 (arc4 encryption).

---

 dlls/advapi32/Makefile.in          |    1 
 dlls/advapi32/advapi32.spec        |    2 -
 dlls/advapi32/crypt_arc4.c         |  109 ++++++++++++++++++++++++++++++++++++
 dlls/advapi32/tests/crypt_lmhash.c |   36 ++++++++++++
 4 files changed, 147 insertions(+), 1 deletions(-)
 create mode 100644 dlls/advapi32/crypt_arc4.c

diff --git a/dlls/advapi32/Makefile.in b/dlls/advapi32/Makefile.in
index cf969cf..19967c1 100644
--- a/dlls/advapi32/Makefile.in
+++ b/dlls/advapi32/Makefile.in
@@ -11,6 +11,7 @@ EXTRALIBS = $(LIBUNICODE)
 C_SRCS = \
 	advapi.c \
 	crypt.c \
+	crypt_arc4.c \
 	crypt_des.c \
 	crypt_lmhash.c \
 	crypt_md4.c \
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 742376c..c824421 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -626,7 +626,7 @@ # @ stub StopTraceW
 @ stub SystemFunction029
 @ stub SystemFunction030
 @ stub SystemFunction031
-@ stub SystemFunction032
+@ stdcall SystemFunction032(ptr ptr)
 @ stub SystemFunction033
 @ stub SystemFunction034
 @ stub SystemFunction035
diff --git a/dlls/advapi32/crypt_arc4.c b/dlls/advapi32/crypt_arc4.c
new file mode 100644
index 0000000..2ba2b1a
--- /dev/null
+++ b/dlls/advapi32/crypt_arc4.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright 2006 Mike McCormack
+ *
+ *  based on arc4.cpp - written and placed in the public domain by Wei Dai
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* http://cryptopp.sourceforge.net/docs/ref521/arc4_8cpp-source.html */
+
+#include <stdarg.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+
+typedef struct tag_arc4_info {
+    unsigned char state[256];
+    unsigned char x, y;
+} arc4_info;
+
+static void arc4_init(arc4_info *a4i, const BYTE *key, unsigned int keyLen)
+{
+    unsigned int keyIndex = 0, stateIndex = 0;
+    unsigned int i, a;
+
+    a4i->x = a4i->y = 0;
+
+    for (i=0; i<256; i++)
+        a4i->state[i] = i;
+
+    for (i=0; i<256; i++)
+    {
+        a = a4i->state[i];
+        stateIndex += key[keyIndex] + a;
+        stateIndex &= 0xff;
+        a4i->state[i] = a4i->state[stateIndex];
+        a4i->state[stateIndex] = a;
+        if (++keyIndex >= keyLen)
+            keyIndex = 0;
+    }
+}
+
+static void arc4_ProcessString(arc4_info *a4i, BYTE *inoutString, unsigned int length)
+{
+    BYTE *const s=a4i->state;
+    unsigned int x = a4i->x;
+    unsigned int y = a4i->y;
+    unsigned int a, b;
+
+    while(length--)
+    {
+        x = (x+1) & 0xff;
+        a = s[x];
+        y = (y+a) & 0xff;
+        b = s[y];
+        s[x] = b;
+        s[y] = a;
+        *inoutString++ ^= s[(a+b) & 0xff];
+    }
+
+    a4i->x = x;
+    a4i->y = y;
+}
+
+struct ustring {
+    DWORD Length;
+    DWORD MaximumLength;
+    unsigned char *Buffer;
+};
+
+/******************************************************************************
+ * SystemFunction032  [ADVAPI32.@]
+ *
+ * Encrypts a string data using ARC4
+ *
+ * PARAMS
+ *   data    [I/O] data to encrypt
+ *   key     [I] key data
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
+ *
+ * NOTES
+ *  see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail
+ */
+NTSTATUS WINAPI SystemFunction032(struct ustring *data, struct ustring *key)
+{
+    arc4_info a4i;
+
+    arc4_init(&a4i, key->Buffer, key->Length);
+    arc4_ProcessString(&a4i, data->Buffer, key->Length);
+
+    return STATUS_SUCCESS;
+}
diff --git a/dlls/advapi32/tests/crypt_lmhash.c b/dlls/advapi32/tests/crypt_lmhash.c
index 5c26633..0e45ddc 100644
--- a/dlls/advapi32/tests/crypt_lmhash.c
+++ b/dlls/advapi32/tests/crypt_lmhash.c
@@ -28,13 +28,21 @@ #include "windef.h"
 #include "winbase.h"
 #include "winternl.h"
 
+struct ustring {
+    DWORD Length;
+    DWORD MaximumLength;
+    unsigned char *Buffer;
+};
+
 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 *fnSystemFunction032)(struct ustring *, struct ustring *);
 
 fnSystemFunction006 pSystemFunction006;
 fnSystemFunction008 pSystemFunction008;
 fnSystemFunction001 pSystemFunction001;
+fnSystemFunction032 pSystemFunction032;
 
 static void test_SystemFunction006(void)
 {
@@ -114,6 +122,30 @@ static void test_SystemFunction001(void)
     ok(!memcmp(output, expected, sizeof expected), "response wrong\n");
 }
 
+static void test_SystemFunction032(void)
+{
+    struct ustring key, data;
+    unsigned char szKey[] = { 'f','o','o',0 };
+    unsigned char szData[8] = { 'b','a','r',0 };
+    unsigned char expected[] = {0x28, 0xb9, 0xf8, 0xe1};
+    int r;
+
+    /* crashes:    pSystemFunction032(NULL,NULL); */
+
+    key.Buffer = szKey;
+    key.Length = sizeof szKey;
+    key.MaximumLength = key.Length;
+
+    data.Buffer = szData;
+    data.Length = 4;
+    data.MaximumLength = 8;
+
+    r = pSystemFunction032(&data, &key);
+    ok(r == STATUS_SUCCESS, "function failed\n");
+
+    ok( !memcmp(expected, data.Buffer, data.Length), "wrong result\n");
+}
+
 START_TEST(crypt_lmhash)
 {
     HMODULE module;
@@ -132,5 +164,9 @@ START_TEST(crypt_lmhash)
     if (pSystemFunction001)
         test_SystemFunction001();
 
+    pSystemFunction032 = (fnSystemFunction032)GetProcAddress( module, "SystemFunction032" );
+    if (pSystemFunction032)
+        test_SystemFunction032();
+
     FreeLibrary( module );
 }




More information about the wine-cvs mailing list