Samuel SerapiĆ³n (samdwise51 AT gmail DOT com):
authorColin Finck <colin@reactos.org>
Sat, 24 May 2008 22:16:15 +0000 (22:16 +0000)
committerColin Finck <colin@reactos.org>
Sat, 24 May 2008 22:16:15 +0000 (22:16 +0000)
- Sync the advapi32 crypt functions to Wine 1.0-rc2, this way we pass some more winetests.

Changes by myself:
- Implement SystemFunction036 (RtlGenRandom) as the Wine equivalent is based on /dev/urandom, so that it cannot be used.
  Warning: This function uses the pseudo random number generator RtlRandom. It should better be implemented using a crypto-safe random number generator!

svn path=/trunk/; revision=33679

reactos/dll/win32/advapi32/advapi32.def
reactos/dll/win32/advapi32/advapi32.rbuild
reactos/dll/win32/advapi32/crypt/crypt.c
reactos/dll/win32/advapi32/crypt/crypt.h
reactos/dll/win32/advapi32/crypt/crypt_arc4.c [new file with mode: 0644]
reactos/dll/win32/advapi32/crypt/crypt_des.c
reactos/dll/win32/advapi32/crypt/crypt_md4.c
reactos/dll/win32/advapi32/misc/sysfunc.c

index 8d7fed9..af2bf1a 100644 (file)
@@ -623,31 +623,31 @@ SystemFunction007@8
 SystemFunction008@12
 SystemFunction009@12
 SystemFunction010@12
-SystemFunction011@12
+SystemFunction011@12=ADVAPI32.SystemFunction010@12
 SystemFunction012@12
 SystemFunction013@12
-SystemFunction014@12
-SystemFunction015@12
-SystemFunction016@12
-SystemFunction017@12
-SystemFunction018@12
-SystemFunction019@12
-SystemFunction020@12
-SystemFunction021@12
-SystemFunction022@12
-SystemFunction023@12
+SystemFunction014@12=ADVAPI32.SystemFunction012@12
+SystemFunction015@12=ADVAPI32.SystemFunction013@13
+SystemFunction016@12=ADVAPI32.SystemFunction012@12
+SystemFunction017@12=ADVAPI32.SystemFunction013@12
+SystemFunction018@12=ADVAPI32.SystemFunction012@12
+SystemFunction019@12=ADVAPI32.SystemFunction013@12
+SystemFunction020@12=ADVAPI32.SystemFunction012@12
+SystemFunction021@12=ADVAPI32.SystemFunction013@12
+SystemFunction022@12=ADVAPI32.SystemFunction012@12
+SystemFunction023@12=ADVAPI32.SystemFunction013@12
 SystemFunction024@12
 SystemFunction025@12
-SystemFunction026@12
-SystemFunction027@12
+SystemFunction026@12=ADVAPI32.SystemFunction024@12
+SystemFunction027@12=ADVAPI32.SystemFunction025@12
 SystemFunction028@8
 SystemFunction029@8
 SystemFunction030@8
-SystemFunction031@8
+SystemFunction031@8=ADVAPI32.SystemFunction030@8
 SystemFunction032@8
 SystemFunction033@8
 SystemFunction034@8
-SystemFunction035@8
+SystemFunction035@4
 SystemFunction036@8
 SystemFunction040@12
 SystemFunction041@12
index 32a8615..e6d2c4f 100644 (file)
@@ -19,6 +19,7 @@
        <pch>advapi32.h</pch>
        <directory name="crypt">
                        <file>crypt.c</file>
+                       <file>crypt_arc4.c</file>
                        <file>crypt_des.c</file>
                        <file>crypt_lmhash.c</file>
                        <file>crypt_md4.c</file>
index f27b3f6..f80bac1 100644 (file)
@@ -543,6 +543,11 @@ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFl
                SetLastError(NTE_BAD_UID);
                return FALSE;
        }
+    if (pProv->dwMagic != MAGIC_CRYPTPROV)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
        pProv->refcount++;
        return TRUE;
@@ -616,6 +621,9 @@ BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
        if (!hProv)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
 
+    if (prov->dwMagic != MAGIC_CRYPTPROV)
+        CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
        return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
 }
 
@@ -649,7 +657,7 @@ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
 
        if (!prov)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!phHash)
+       if (!phHash || prov->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
        if (dwFlags)
                CRYPT_ReturnLastError(NTE_BAD_FLAGS);
@@ -698,7 +706,7 @@ BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
 
        TRACE("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
 
-       if (!key || !pbData || !pdwDataLen)
+       if (!key || !pbData || !pdwDataLen || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = key->pProvider;
@@ -733,7 +741,7 @@ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData
 
        if (!prov || !hash)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!phKey)
+       if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
        if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
                CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -771,7 +779,7 @@ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
 
        TRACE("(0x%lx)\n", hHash);
 
-       if (!hash)
+       if (!hash || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
 
        prov = hash->pProvider;
@@ -803,6 +811,9 @@ BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
        if (!key)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
 
+    if (!key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
+        CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
        prov = key->pProvider;
        ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
        CRYPT_Free(key);
@@ -833,7 +844,8 @@ BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
        TRACE("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
 
        orghash = (PCRYPTHASH)hHash;
-       if (!orghash || pdwReserved || !phHash)
+       if (!orghash || pdwReserved || !phHash|| 
+        orghash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = orghash->pProvider;
@@ -876,7 +888,7 @@ BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags
        TRACE("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
 
        orgkey = (PCRYPTKEY)hKey;
-       if (!orgkey || pdwReserved || !phKey)
+       if (!orgkey || pdwReserved || !phKey || orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = orgkey->pProvider;
@@ -928,7 +940,7 @@ BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
 
        TRACE("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
 
-       if (!key || !pdwDataLen)
+       if (!key || !pdwDataLen || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = key->pProvider;
@@ -1024,22 +1036,29 @@ BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved,
                DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName)
 {
        PWSTR str = NULL;
-       DWORD strlen;
+       DWORD bufsize;
        BOOL ret; /* = FALSE; */
 
        TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
                        pdwProvType, pszProvName, pcbProvName);
 
-       strlen = *pcbProvName * sizeof(WCHAR);
-       if (pszProvName && !(str = CRYPT_Alloc(strlen)))
+    if(!CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize))
+        return FALSE;
+       if (pszProvName && !(str = CRYPT_Alloc(bufsize)))
                CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
-       ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen);
+       ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize);
+    if (str)
+        CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
+    *pcbProvName = bufsize / sizeof(WCHAR);
        if (str)
        {
-               CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
                CRYPT_Free(str);
+        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+        {
+            SetLastError(ERROR_MORE_DATA);
+            return FALSE;
+        }
        }
-       *pcbProvName = strlen / sizeof(WCHAR);  /* FIXME: not correct */
        return ret;
 }
 
@@ -1168,7 +1187,7 @@ BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType,
 
        TRACE("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
 
-       if (!key || !pdwDataLen)
+       if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = key->pProvider;
@@ -1200,7 +1219,7 @@ BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKE
 
        if (!prov)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!phKey)
+       if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
        if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
                CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -1352,7 +1371,7 @@ BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData,
 
        TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags);
 
-       if (!hash || !pdwDataLen)
+       if (!hash || !pdwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = hash->pProvider;
@@ -1387,7 +1406,7 @@ BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData,
 
        TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags);
 
-       if (!key || !pdwDataLen)
+       if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = key->pProvider;
@@ -1421,6 +1440,9 @@ BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
 
        TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags);
 
+    if (!prov || prov->dwMagic != MAGIC_CRYPTPROV)
+        CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
        return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags);
 }
 
@@ -1447,7 +1469,7 @@ BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUse
 
        if (!prov)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!phUserKey)
+       if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
        if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
                CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -1490,7 +1512,7 @@ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen
 
        if (!hash)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!pbData || !dwDataLen)
+       if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = hash->pProvider;
@@ -1519,6 +1541,8 @@ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags
 
        if (!hash || !key)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+    if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
+        CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = hash->pProvider;
        return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags);
@@ -1547,7 +1571,7 @@ BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLe
 
        TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
 
-       if (!prov || !pbData || !dwDataLen || !phKey)
+       if (!prov || !pbData || !dwDataLen || !phKey || prov->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        if (!(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))))
@@ -1612,7 +1636,7 @@ BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescript
 
        if (!hash)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!pdwSigLen || !hash->pProvider)
+       if (!pdwSigLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = hash->pProvider;
@@ -1643,7 +1667,7 @@ BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, CONST BYTE *pbDa
 
        TRACE("(0x%lx, %ld, %p, %08ld)\n", hHash, dwParam, pbData, dwFlags);
 
-       if (!hash || !pbData)
+       if (!hash || !pbData || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = hash->pProvider;
@@ -1673,7 +1697,7 @@ BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, CONST BYTE *pbData,
 
        TRACE("(0x%lx, %ld, %p, %08ld)\n", hKey, dwParam, pbData, dwFlags);
 
-       if (!key || !pbData)
+       if (!key || !pbData || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
                CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 
        prov = key->pProvider;
@@ -1845,6 +1869,8 @@ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, CONST BYTE *pbDa
 
        if (!prov)
                CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+    if (prov->dwMagic != MAGIC_CRYPTPROV)
+        CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
        if (dwFlags & PP_USE_HARDWARE_RNG)
        {
                FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n");
@@ -1894,10 +1920,6 @@ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, CONST BYTE *pbDa
 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen,
                HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags)
 {
-       PCRYPTHASH hash = (PCRYPTHASH)hHash;
-       PCRYPTKEY key = (PCRYPTKEY)hPubKey;
-       PCRYPTPROV prov;
-
        TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld)\n", hHash, pbSignature,
                        dwSigLen, hPubKey, dwFlags);
        if (sDescription)
@@ -1905,14 +1927,7 @@ BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, CONST BYTE *pbSignature, DW
                WARN("The sDescription parameter is not supported (and no longer used).  Ignoring.\n");
        }
 
-       if (!hash || !key)
-               CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
-       if (!pbSignature || !dwSigLen)
-               CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
-
-       prov = hash->pProvider;
-       return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
-               key->hPrivate, NULL, dwFlags);
+    return CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, NULL, dwFlags);
 }
 
 BOOL WINAPI
@@ -1923,8 +1938,27 @@ CryptVerifySignatureW (HCRYPTHASH hHash,
                        LPCWSTR sDescription,
                        DWORD dwFlags)
 {
-       FIXME("ADVAPI32!CryptVerifySignatureW not implemented!");
-       return FALSE;
+    PCRYPTHASH hash = (PCRYPTHASH)hHash;
+    PCRYPTKEY key = (PCRYPTKEY)hPubKey;
+    PCRYPTPROV prov;
+
+    TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature,
+        dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags);
+
+    if (sDescription)
+       {
+               WARN("The sDescription parameter is not supported (and no longer used).  Ignoring.\n");
+       }
+
+    if (!hash || !key ||
+        !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV ||
+        !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
+    CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+
+    prov = hash->pProvider;
+    return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
+        key->hPrivate, sDescription, dwFlags);
 }
 
 /*
@@ -2085,5 +2119,3 @@ BOOL WINAPI EncryptionDisable(
        return FALSE;
 }
 
-
-
index 7c7f127..2548d57 100644 (file)
@@ -96,6 +96,23 @@ struct ustring {
     unsigned char *Buffer;
 };
 
-NTSTATUS WINAPI SystemFunction032(struct ustring *data, struct ustring *key);
+typedef struct {
+    unsigned int buf[4];
+    unsigned int i[2];
+    unsigned char in[64];
+    unsigned char digest[16];
+} MD4_CTX;
+
+typedef struct tag_arc4_info {
+    unsigned char state[256];
+    unsigned char x, y;
+} arc4_info;
+
+VOID WINAPI MD4Init( MD4_CTX *ctx );
+VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len );
+VOID WINAPI MD4Final(MD4_CTX *ctx);
+void arc4_init(arc4_info *a4i, const BYTE *key, unsigned int keyLen);
+void arc4_ProcessString(arc4_info *a4i, BYTE *inoutString, unsigned int length);
+
 
 #endif /* __WINE_CRYPT_H_ */
diff --git a/reactos/dll/win32/advapi32/crypt/crypt_arc4.c b/reactos/dll/win32/advapi32/crypt/crypt_arc4.c
new file mode 100644 (file)
index 0000000..a55e2c5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/* http://cryptopp.sourceforge.net/docs/ref521/arc4_8cpp-source.html */
+
+#include <advapi32.h>
+#include "crypt.h"
+
+
+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;
+    }
+}
+
+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;
+}
+
index 3c9b1d5..50b60c5 100644 (file)
@@ -161,7 +161,7 @@ static void Permute(unsigned char *dst, const unsigned char *src, const unsigned
     }
 }
 
-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 +190,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 = 6; j >= 0; j--)
+        {
+            if (j!=6 && (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;
@@ -268,7 +297,7 @@ unsigned char *CRYPT_DEShash(unsigned char *dst, const unsigned char *key, const
         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);
@@ -289,3 +318,44 @@ unsigned char *CRYPT_DEShash(unsigned char *dst, const unsigned char *key, const
 
     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;
+}
index 6b360b3..49e1fcf 100644 (file)
 #include "crypt.h"
 
 
-typedef struct
-{
-    unsigned int buf[4];
-    unsigned int i[2];
-    unsigned char in[64];
-    unsigned char digest[16];
-} MD4_CTX;
-
-
 /* The three core functions */
 
 #define rotl32(x,n)  (((x) << ((unsigned int)(n))) | ((x) >> (32 - (unsigned int)(n))))
index c9dc3a0..7003684 100644 (file)
-/* $Id$
+/*
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
- * FILE:            lib/advapi32/misc/sysfun.c
+ * FILE:            dll/win32/advapi32/misc/sysfun.c
  * PURPOSE:         advapi32.dll system functions (undocumented)
  * PROGRAMMER:      Emanuele Aliberti
  * UPDATE HISTORY:
  *     19990413 EA     created
  *     19990415 EA
+ *     20080424 Ported from WINE
  */
 
 #include <advapi32.h>
+#include <crypt/crypt.h>
 
-/**********************************************************************
- *     SystemFunction001
+static const unsigned char CRYPT_LMhash_Magic[8] =
+    { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
+
+/******************************************************************************
+ * SystemFunction001  [ADVAPI32.@]
+ *
+ * Encrypts a single block of data using DES
+ *
+ * PARAMS
+ *   data    [I] data to encrypt    (8 bytes)
+ *   key     [I] key data           (7 bytes)
+ *   output  [O] the encrypted data (8 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction001(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 1;
+    if (!data || !output)
+        return STATUS_UNSUCCESSFUL;
+    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
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction002(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction002(const BYTE *data, const BYTE *key, LPBYTE output)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 2;
+    if (!data || !output)
+        return STATUS_UNSUCCESSFUL;
+    CRYPT_DESunhash(output, key, data);
+    return STATUS_SUCCESS;
 }
 
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction003  [ADVAPI32.@]
+ *
+ * Hashes a key using DES and a fixed datablock
+ *
+ * PARAMS
+ *   key     [I] key data    (7 bytes)
+ *   output  [O] hashed key  (8 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction003(INT a, INT b)
+NTSTATUS
+WINAPI SystemFunction003(const BYTE *key, LPBYTE output)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 3;
+    if (!output)
+        return STATUS_UNSUCCESSFUL;
+    CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
+    return STATUS_SUCCESS;
 }
 
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction004  [ADVAPI32.@]
  *
- * @unimplemented
+ * Encrypts a block of data with DES in ECB mode, preserving the length
+ *
+ * PARAMS
+ *   data    [I] data to encrypt
+ *   key     [I] key data (up to 7 bytes)
+ *   output  [O] buffer to receive encrypted data
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_BUFFER_TOO_SMALL     if the output buffer is too small
+ *  Failure: STATUS_INVALID_PARAMETER_2  if the key is zero length
+ *
+ * NOTES
+ *  Encrypt buffer size should be input size rounded up to 8 bytes
+ *   plus an extra 8 bytes.
  */
-INT
-STDCALL
-SystemFunction004(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction004(const struct ustring *in,
+                                  const struct ustring *key,
+                                  struct ustring *out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 4;
-}
+    union {
+        unsigned char uc[8];
+          unsigned int  ui[2];
+    } data;
+    unsigned char deskey[7];
+    unsigned int crypt_len, ofs;
 
+    if (key->Length<=0)
+        return STATUS_INVALID_PARAMETER_2;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction005(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 5;
-}
+    crypt_len = ((in->Length+7)&~7);
+    if (out->MaximumLength < (crypt_len+8))
+        return STATUS_BUFFER_TOO_SMALL;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction007(INT a, INT b)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 7;
-}
+    data.ui[0] = in->Length;
+    data.ui[1] = 1;
 
+    if (key->Length<sizeof deskey)
+    {
+        memset(deskey, 0, sizeof deskey);
+        memcpy(deskey, key->Buffer, key->Length);
+    }
+    else
+        memcpy(deskey, key->Buffer, sizeof deskey);
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction008(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 8;
-}
+    CRYPT_DEShash(out->Buffer, deskey, data.uc);
 
+    for(ofs=0; ofs<(crypt_len-8); ofs+=8)
+        CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction009(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 9;
-}
+    memset(data.uc, 0, sizeof data.uc);
+    memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len);
+    CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
 
+    out->Length = crypt_len+8;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction010(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 10;
+    return STATUS_SUCCESS;
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction005  [ADVAPI32.@]
+ *
+ * Decrypts a block of data with DES in ECB mode
+ *
+ * PARAMS
+ *   data    [I] data to decrypt
+ *   key     [I] key data (up to 7 bytes)
+ *   output  [O] buffer to receive decrypted data
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_BUFFER_TOO_SMALL     if the output buffer is too small
+ *  Failure: STATUS_INVALID_PARAMETER_2  if the key is zero length
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction011(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction005(const struct ustring *in,
+                         const struct ustring *key,
+                         struct ustring *out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 11;
-}
+    union {
+        unsigned char uc[8];
+        unsigned int  ui[2];
+    } data;
+    unsigned char deskey[7];
+    unsigned int ofs, crypt_len;
 
+    if (key->Length<=0)
+        return STATUS_INVALID_PARAMETER_2;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction012(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 12;
-}
+    if (key->Length<sizeof deskey)
+    {
+        memset(deskey, 0, sizeof deskey);
+        memcpy(deskey, key->Buffer, key->Length);
+    }
+    else
+        memcpy(deskey, key->Buffer, sizeof deskey);
 
+    CRYPT_DESunhash(data.uc, deskey, in->Buffer);
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction013(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 13;
-}
+    if (data.ui[1] != 1)
+        return STATUS_UNKNOWN_REVISION;
 
+    crypt_len = data.ui[0];
+    if (crypt_len > out->MaximumLength)
+        return STATUS_BUFFER_TOO_SMALL;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction014(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 14;
-}
+    for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
+        CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
 
+    if (ofs<crypt_len)
+    {
+        CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8);
+        memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs);
+    }
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction015(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 15;
-}
+    out->Length = crypt_len;
 
+    return STATUS_SUCCESS;
+}
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction007  [ADVAPI32.@]
+ *
+ * MD4 hash a unicode string
+ *
+ * PARAMS
+ *   string  [I] the string to hash
+ *   output  [O] the md4 hash of the string (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction016(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction007(const UNICODE_STRING *string, LPBYTE hash)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 16;
-}
+    MD4_CTX ctx;
 
+    MD4Init( &ctx );
+    MD4Update( &ctx, (const BYTE *)string->Buffer, string->Length );
+    MD4Final( &ctx );
+    memcpy( hash, ctx.digest, 0x10 );
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction017(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 17;
+    return STATUS_SUCCESS;
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction008  [ADVAPI32.@]
+ *
+ * Creates a LM response from a challenge and a password hash
+ *
+ * PARAMS
+ *   challenge  [I] Challenge from authentication server
+ *   hash       [I] NTLM hash (from SystemFunction006)
+ *   response   [O] response to send back to the server
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
+ *
+ * NOTES
+ *  see http://davenport.sourceforge.net/ntlm.html#theLmResponse
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction018(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction008(const BYTE *challenge, const BYTE *hash, LPBYTE response)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 18;
-}
+    BYTE key[7*3];
 
+    if (!challenge || !response)
+        return STATUS_UNSUCCESSFUL;
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction019(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 19;
-}
+    memset(key, 0, sizeof key);
+    memcpy(key, hash, 0x10);
 
+    CRYPT_DEShash(response, key, challenge);
+    CRYPT_DEShash(response+8, key+7, challenge);
+    CRYPT_DEShash(response+16, key+14, challenge);
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction020(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 20;
+    return STATUS_SUCCESS;
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction009  [ADVAPI32.@]
  *
- * @unimplemented
+ * Seems to do the same as SystemFunction008...
  */
-INT
-STDCALL
-SystemFunction021(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction009(const BYTE *challenge, const BYTE *hash, LPBYTE response)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 21;
+    return SystemFunction008(challenge, hash, response);
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction010  [ADVAPI32.@]
+ * SystemFunction011  [ADVAPI32.@]
+ *
+ * MD4 hashes 16 bytes of data
+ *
+ * PARAMS
+ *   unknown []  seems to have no effect on the output
+ *   data    [I] pointer to data to hash (16 bytes)
+ *   output  [O] the md4 hash of the data (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL
  *
- * @unimplemented
  */
-INT
-STDCALL
-SystemFunction022(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction010(LPVOID unknown, const BYTE *data, LPBYTE hash)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 22;
-}
+    MD4_CTX ctx;
 
+    MD4Init( &ctx );
+    MD4Update( &ctx, data, 0x10 );
+    MD4Final( &ctx );
+    memcpy( hash, ctx.digest, 0x10 );
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction023(INT a, INT b, INT c)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 23;
+    return STATUS_SUCCESS;
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction012  [ADVAPI32.@]
+ * SystemFunction014  [ADVAPI32.@]
+ * SystemFunction016  [ADVAPI32.@]
+ * SystemFunction018  [ADVAPI32.@]
+ * SystemFunction020  [ADVAPI32.@]
+ * SystemFunction022  [ADVAPI32.@]
  *
- * @unimplemented
+ * Encrypts two DES blocks with two keys
+ *
+ * PARAMS
+ *   data    [I] data to encrypt (16 bytes)
+ *   key     [I] key data (two lots of 7 bytes)
+ *   output  [O] buffer to receive encrypted data (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL  if the input or output buffer is NULL
  */
-INT
-STDCALL
-SystemFunction024(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction012(const BYTE *in, const BYTE *key, LPBYTE out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 24;
-}
+    if (!in || !out)
+        return STATUS_UNSUCCESSFUL;
 
+    CRYPT_DEShash(out, key, in);
+    CRYPT_DEShash(out+8, key+7, in+8);
+    return STATUS_SUCCESS;
+}
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction013  [ADVAPI32.@]
+ * SystemFunction015  [ADVAPI32.@]
+ * SystemFunction017  [ADVAPI32.@]
+ * SystemFunction019  [ADVAPI32.@]
+ * SystemFunction021  [ADVAPI32.@]
+ * SystemFunction023  [ADVAPI32.@]
  *
- * @unimplemented
+ * Decrypts two DES blocks with two keys
+ *
+ * PARAMS
+ *   data    [I] data to decrypt (16 bytes)
+ *   key     [I] key data (two lots of 7 bytes)
+ *   output  [O] buffer to receive decrypted data (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
+ *  Failure: STATUS_UNSUCCESSFUL  if the input or output buffer is NULL
  */
-INT
-STDCALL
-SystemFunction025(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction013(const BYTE *in, const BYTE *key, LPBYTE out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 25;
+    if (!in || !out)
+        return STATUS_UNSUCCESSFUL;
+    CRYPT_DESunhash(out, key, in);
+    CRYPT_DESunhash(out+8, key+7, in+8);
+    return STATUS_SUCCESS;
 }
 
-
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction024  [ADVAPI32.@]
  *
- * @unimplemented
+ * Encrypts two DES blocks with a 32 bit key...
+ *
+ * PARAMS
+ *   data    [I] data to encrypt (16 bytes)
+ *   key     [I] key data (4 bytes)
+ *   output  [O] buffer to receive encrypted data (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
  */
-INT
-STDCALL
-SystemFunction026(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction024(const BYTE *in, const BYTE *key, LPBYTE out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 26;
-}
+    BYTE deskey[0x10];
 
+    memcpy(deskey, key, 4);
+    memcpy(deskey+4, key, 4);
+    memcpy(deskey+8, key, 4);
+    memcpy(deskey+12, key, 4);
 
-/**********************************************************************
+    CRYPT_DEShash(out, deskey, in);
+    CRYPT_DEShash(out+8, deskey+7, in+8);
+
+    return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * SystemFunction025  [ADVAPI32.@]
  *
- * @unimplemented
+ * Decrypts two DES blocks with a 32 bit key...
+ *
+ * PARAMS
+ *   data    [I] data to encrypt (16 bytes)
+ *   key     [I] key data (4 bytes)
+ *   output  [O] buffer to receive encrypted data (16 bytes)
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS
  */
-INT
-STDCALL
-SystemFunction027(INT a, INT b, INT c)
+NTSTATUS
+WINAPI SystemFunction025(const BYTE *in, const BYTE *key, LPBYTE out)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 27;
-}
+    BYTE deskey[0x10];
 
+    memcpy(deskey, key, 4);
+    memcpy(deskey+4, key, 4);
+    memcpy(deskey+8, key, 4);
+    memcpy(deskey+12, key, 4);
+
+    CRYPT_DESunhash(out, deskey, in);
+    CRYPT_DESunhash(out+8, deskey+7, in+8);
+
+    return STATUS_SUCCESS;
+}
 
 /**********************************************************************
  *
  * @unimplemented
  */
 INT
-STDCALL
+WINAPI
 SystemFunction028(INT a, INT b)
 {
+    //NDRCContextBinding()
+    //SystemFunction034()
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
        return 28;
 }
@@ -368,50 +456,59 @@ SystemFunction028(INT a, INT b)
  * @unimplemented
  */
 INT
-STDCALL
+WINAPI
 SystemFunction029(INT a, INT b)
 {
+    //I_RpcBindingIsClientLocal()
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
        return 29;
 }
 
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction030   (ADVAPI32.@)
  *
- * @unimplemented
+ * Tests if two blocks of 16 bytes are equal
+ *
+ * PARAMS
+ *  b1,b2   [I] block of 16 bytes
+ *
+ * RETURNS
+ *  TRUE  if blocks are the same
+ *  FALSE if blocks are different
  */
-INT
-STDCALL
-SystemFunction030(INT a, INT b)
+BOOL
+WINAPI SystemFunction030(PVOID b1, PVOID b2)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 30;
+       return !memcmp(b1, b2, 0x10);
 }
 
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction032  [ADVAPI32.@]
  *
- * @unimplemented
+ * 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
  */
-INT
-STDCALL
-SystemFunction031(INT a, INT b)
+NTSTATUS
+WINAPI SystemFunction032(struct ustring *data, struct ustring *key)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 31;
-}
+    arc4_info a4i;
 
+    arc4_init(&a4i, key->Buffer, key->Length);
+    arc4_ProcessString(&a4i, data->Buffer, data->Length);
 
-/**********************************************************************
- *
- * @unimplemented
- */
-INT
-STDCALL
-SystemFunction032(INT a, INT b)
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 32;
+    return STATUS_SUCCESS;
 }
 
 
@@ -420,7 +517,7 @@ SystemFunction032(INT a, INT b)
  * @unimplemented
  */
 INT
-STDCALL
+WINAPI
 SystemFunction033(INT a, INT b)
 {
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@@ -432,9 +529,13 @@ SystemFunction033(INT a, INT b)
  * @unimplemented
  */
 INT
-STDCALL
+WINAPI
 SystemFunction034(INT a, INT b)
 {
+    //RpcBindingToStringBindingW
+    //I_RpcMapWin32Status
+    //RpcStringBindingParseW
+    //RpcStringFreeW
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
        return 34;
 }
@@ -444,24 +545,65 @@ SystemFunction034(INT a, INT b)
  *
  * @unimplemented
  */
-INT
-STDCALL
-SystemFunction035(INT a, INT b)
+BOOL
+WINAPI
+SystemFunction035(LPCSTR lpszDllFilePath)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 35;
+       return TRUE;
 }
 
-/**********************************************************************
+/******************************************************************************
+ * SystemFunction036   (ADVAPI32.@)
  *
- * @unimplemented
+ * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
+ *
+ * PARAMS
+ *  pbBuffer [O] Pointer to memory to receive random bytes.
+ *  dwLen    [I] Number of random bytes to fetch.
+ *
+ * RETURNS
+ *  Always TRUE in my tests
  */
-INT
-STDCALL
-SystemFunction036(INT a, INT b)
+BOOL
+WINAPI
+SystemFunction036(PVOID pbBuffer, ULONG dwLen)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 36;
+    ////////////////////////////////////////////////////////////////
+    //////////////////// B I G   W A R N I N G  !!! ////////////////
+    // This function will output numbers based on the tick count. //
+    // It will NOT OUPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!!    //
+    ////////////////////////////////////////////////////////////////
+
+    DWORD dwSeed;
+    PBYTE pBuffer;
+    ULONG uPseudoRandom;
+
+    if(!pbBuffer || !dwLen)
+    {
+        /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */
+        return TRUE;
+    }
+
+    /* Get the first seed from the tick count */
+    dwSeed = GetTickCount();
+
+    /* We will access the buffer bytewise */
+    pBuffer = (PBYTE)pbBuffer;
+
+    do
+    {
+        /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */
+        uPseudoRandom = RtlRandom(&dwSeed);
+
+        do
+        {
+            /* Get each byte from the pseudo random number and store it in the buffer */
+            *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 4) & 0xFF);
+            ++pBuffer;
+        } while(--dwLen % 4);
+    } while(dwLen);
+
+    return TRUE;
 }
 
 /* EOF */