From 9e37591d209362f2aa174b3459a94590740188af Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 10 May 2006 21:41:48 +0900 Subject: [PATCH] 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 deletion(-) create mode 100644 dlls/advapi32/crypt_arc4.c diff --git a/dlls/advapi32/Makefile.in b/dlls/advapi32/Makefile.in index cf969cf9b86..19967c169a4 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 742376c3978..c8244215238 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -626,7 +626,7 @@ @ 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 00000000000..2ba2b1aa787 --- /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 + +#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 5c266331aa2..0e45ddcafea 100644 --- a/dlls/advapi32/tests/crypt_lmhash.c +++ b/dlls/advapi32/tests/crypt_lmhash.c @@ -28,13 +28,21 @@ #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 ); }