SetLastError(NTE_BAD_UID);
return FALSE;
}
+ if (pProv->dwMagic != MAGIC_CRYPTPROV)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
pProv->refcount++;
return TRUE;
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);
}
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);
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;
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);
TRACE("(0x%lx)\n", hHash);
- if (!hash)
+ if (!hash || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
prov = hash->pProvider;
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);
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;
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;
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;
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;
}
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;
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);
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;
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;
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);
}
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);
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;
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);
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))))
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;
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;
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;
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");
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)
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
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);
}
/*
return FALSE;
}
-
-
-/* $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;
}
* @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;
}
* @unimplemented
*/
INT
-STDCALL
+WINAPI
SystemFunction033(INT a, INT b)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
* @unimplemented
*/
INT
-STDCALL
+WINAPI
SystemFunction034(INT a, INT b)
{
+ //RpcBindingToStringBindingW
+ //I_RpcMapWin32Status
+ //RpcStringBindingParseW
+ //RpcStringFreeW
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 34;
}
*
* @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 */