Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Exile 1.8 - The Password Manager

, 7 Mar 2005
Yet another password manager.
exile_18_setup.zip
exile_1.8_setup.exe
exile_exe.zip
exile.exe
Exile.exe.manifest
icons.dll
md5.dll
mdx.dll
PwsInfo.dll
rc5.dll
exile_exe_staticmfc.zip
exile.exe
icons.dll
md5.dll
mdx.dll
rc5.dll
exile_src.zip
exile
Exile
Exile.exe.manifest
exile.dep
exile.dsp
exile.dsw
res
aboveimportant.ico
advanced.bmp
belowcritical.ico
belowinsignificant.ico
belownormal.ico
changeicon.bmp
cold.ico
collapsed.ico
critical.ico
editcategory.bmp
editelement.bmp
enterpassword.bmp
error.ico
exile.ico
expanded.ico
exporttoxml.bmp
find.ico
found.ico
important.ico
insertcategory.bmp
insertelement.bmp
insignificant.ico
md5hashgenerator.bmp
new.bmp
normal.ico
options.bmp
passwordgenerator.bmp
rsasecurity.bmp
rsasecurity.ico
search.cur
storageproperties.bmp
switch.bmp
unimportant.ico
veryimportant.ico
vssver.scc
Icons
res
icon1.ico
icon10.ico
icon11.ico
icon12.ico
icon13.ico
icon14.ico
icon15.ico
icon16.ico
icon17.ico
icon18.ico
icon19.ico
icon2.ico
icon20.ico
icon21.ico
icon22.ico
icon23.ico
icon24.ico
icon25.ico
icon26.ico
icon27.ico
icon28.ico
icon3.ico
icon4.ico
icon5.ico
icon6.ico
icon7.ico
icon8.ico
icon9.ico
md5
md5.dep
md5.dsp
mdx
pwsinfo
passwordstorageshellext.rgs
pwsinfo.def
pwsinfo.dep
pwsinfo.dsp
pwsinfo.dsw
PwsInfo.tlb
pwsinfops.def
pwsinfops.mk
rc5
rc5.dep
rc5.dsp
xml
exile_src_vs2003.zip
Exile.exe.manifest
Exile.dep
Exile.dsp
Exile.dsw
Exile.suo
msxml3.tlh
msxml3.tli
res
AboveImportant.ico
Advanced.bmp
BelowCritical.ico
BelowInsignificant.ico
BelowNormal.ico
ChangeIcon.bmp
Cold.ico
Critical.ico
EditCategory.bmp
EditElement.bmp
EnterPassword.bmp
Error.ico
Exile.ico
ExportToXML.bmp
Find.ico
Found.ico
Icon1.ico
Icon10.ico
Icon11.ico
Icon12.ico
Icon13.ico
Icon14.ico
icon15.ico
Icon16.ico
Icon17.ico
Icon18.ico
Icon19.ico
Icon2.ico
Icon20.ico
Icon21.ico
Icon22.ico
Icon23.ico
Icon24.ico
Icon25.ico
Icon26.ico
Icon27.ico
Icon28.ico
Icon3.ico
Icon4.ico
Icon5.ico
Icon6.ico
Icon7.ico
Icon8.ico
Icon9.ico
Important.ico
InsertCategory.bmp
InsertElement.bmp
Insignificant.ico
MD5HashGenerator.bmp
New.bmp
Normal.ico
Options.bmp
PasswordGenerator.bmp
RSASecurity.bmp
rsasecurity.ico
Search.cur
StorageProperties.bmp
Switch.bmp
Unimportant.ico
VeryImportant.ico
vssver.scc
MD5
MD5.dep
MD5.dsp
PwsInfo
PasswordStorageShellExt.rgs
PwsInfo.def
PwsInfo.dep
PwsInfo.dsp
PwsInfo.dsw
PwsInfo.tlb
PwsInfops.def
PwsInfops.mk
RC5
RC5.dep
RC5.dsp
// MDX.cpp : Defines the entry point for the DLL
//

#include "stdafx.h"
#include "MDX.h"
#include <stdlib.h>
#include <math.h>
#include <map>

// Context map
typedef std::map<HMDXCONTEXT, MDXCONTEXT> MDXCONTEXTMAP;

MDXCONTEXTMAP mMdxCtx;

// Summands used in rounds
MDX_WORD *g_pwSummands = 0;

// Chaining constants
static const MDX_WORD g_wChainA = 0x67452301;
static const MDX_WORD g_wChainB = 0xEFCDAB89;
static const MDX_WORD g_wChainC = 0x98BADCFE;
static const MDX_WORD g_wChainD = 0x10325476;

//////////////////////////////////////////////////////////////////////////
// MDX Nonlinear functions

inline MDX_WORD F(MDX_WORD wX, MDX_WORD wY, MDX_WORD wZ)
{
	return ((wX & wY) | ((~wX) & wZ));
}

inline MDX_WORD G(MDX_WORD wX, MDX_WORD wY, MDX_WORD wZ)
{
	return ((wX & wZ) | (wY & (~wZ)));
}

inline MDX_WORD H(MDX_WORD wX, MDX_WORD wY, MDX_WORD wZ)
{
	return (wX ^ wY ^ wZ);
}

inline MDX_WORD I(MDX_WORD wX, MDX_WORD wY, MDX_WORD wZ)
{
	return (wY ^ (wX | (~wZ)));
}

//////////////////////////////////////////////////////////////////////////
// MDX Transformation Functions

inline void FF(MDX_WORD &wA, MDX_WORD wB, MDX_WORD wC, MDX_WORD wD, MDX_WORD wM, int nS, MDX_WORD wT)
{	
	wA += F(wB, wC, wD) + wM + wT;
	wA = _lrotl(wA, nS);
	wA += wB;
}

inline void GG(MDX_WORD &wA, MDX_WORD wB, MDX_WORD wC, MDX_WORD wD, MDX_WORD wM, int nS, MDX_WORD wT)
{	
	wA += G(wB, wC, wD) + wM + wT;
	wA = _lrotl(wA, nS);
	wA += wB;
}

inline void HH(MDX_WORD &wA, MDX_WORD wB, MDX_WORD wC, MDX_WORD wD, MDX_WORD wM, int nS, MDX_WORD wT)
{	
	wA += H(wB, wC, wD) + wM + wT;
	wA = _lrotl(wA, nS);
	wA += wB;
}

inline void II(MDX_WORD &wA, MDX_WORD wB, MDX_WORD wC, MDX_WORD wD, MDX_WORD wM, int nS, MDX_WORD wT)
{	
	wA += I(wB, wC, wD) + wM + wT;
	wA = _lrotl(wA, nS);
	wA += wB;
}

//////////////////////////////////////////////////////////////////////////
// MDX Main

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
	switch(dwReason) 
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	} // switch

    return TRUE;
}

MDX_API BOOL MdxInitialize()
{
	if(g_pwSummands) 
	{
		// Already initialized
		return FALSE;		
	} // if

	g_pwSummands = new MDX_WORD[64];

	for(int n = 0; n < 64; ++n)
	{
		double dVal = pow(2.0, 32.0) * fabs(sin((double)n + 1.0));
		g_pwSummands[n] = MDX_WORD(dVal);
	} // for

	return TRUE;
}

MDX_API BOOL MdxUninitialize()
{
	if(g_pwSummands)
	{
		delete [] g_pwSummands;
		g_pwSummands = 0;
	
		return TRUE;
	} // if

	// Not yet initialized
	return FALSE;	
}

MDX_API BOOL MdxAcquireContext(HMDXCONTEXT &hMdx)
{
	hMdx = (HMDXCONTEXT)&hMdx;

	// Check for duplicates
	if(mMdxCtx.end() != mMdxCtx.find(hMdx)) 
	{
		hMdx = (HMDXCONTEXT)0;
		return FALSE;
	} // if

	MDXCONTEXT cMdx;

	cMdx.hsState.wA = g_wChainA;
	cMdx.hsState.wB = g_wChainB;
	cMdx.hsState.wC = g_wChainC;
	cMdx.hsState.wD = g_wChainD;
	cMdx.pBuffer = new BYTE[64];
	cMdx.unSize = 0;
	cMdx.unBuffer = 0;

	mMdxCtx[hMdx] = cMdx;

	return TRUE;
}

MDX_API BOOL MdxReleaseContext(HMDXCONTEXT &hMdx)
{
	// This is an error
	if(0 == hMdx) 
	{
		return FALSE;
	} // if

	MDXCONTEXTMAP::iterator mMdxi = mMdxCtx.find(hMdx);
	if(mMdxCtx.end() != mMdxi)
	{
		// Cleaning up
		delete [] mMdxi->second.pBuffer;

		hMdx = (HMDXCONTEXT)0;
		mMdxCtx.erase(mMdxi);

		return TRUE;
	} // if

	return FALSE;
}

MDX_API BOOL MdxResetContext(HMDXCONTEXT hMdx)
{
	if(0 == hMdx) 
	{
		return FALSE;
	} // if

	// Reset state variables and stuff...
	MDXCONTEXTMAP::iterator mMdxi = mMdxCtx.find(hMdx);
	if(mMdxCtx.end() != mMdxi)
	{
		mMdxi->second.hsState.wA = g_wChainA;
		mMdxi->second.hsState.wB = g_wChainB;
		mMdxi->second.hsState.wC = g_wChainC;
		mMdxi->second.hsState.wD = g_wChainD;

		mMdxi->second.unBuffer = 0;
		mMdxi->second.unSize = 0;

		return TRUE;
	} // if
	
	return FALSE;
}

MDX_API BOOL MdxValidContext(HMDXCONTEXT hMdx)
{
	// Zero context id indicates error
	if(0 == hMdx) 
	{
		return FALSE;
	} // if

	if(mMdxCtx.end() != mMdxCtx.find(hMdx)) 
	{
		return TRUE;
	} // if
	
	return FALSE;
}

MDX_API BOOL MdxHashBuffer(HMDXCONTEXT hMdx, BYTE *pBuffer, size_t sBuffer)
{
	if(0 == hMdx) 
	{
		return FALSE;
	} // if

	MDXCONTEXTMAP::iterator mMdxi = mMdxCtx.find(hMdx);
	if(mMdxCtx.end() == mMdxi) 
	{
		return FALSE;
	} // if

	// If we still have input data
	while(sBuffer) 
	{
#ifdef _DEBUG
		MDXCONTEXT cmd5 = mMdxi->second;
#endif // _DEBUG

		// Fill our context buffer with as much data as possible
		size_t sData = ((sBuffer >= (64 - mMdxi->second.unBuffer)) ? 64 - mMdxi->second.unBuffer : sBuffer);
		
		memcpy(mMdxi->second.pBuffer + mMdxi->second.unBuffer, pBuffer, sData);
		sBuffer -= sData; // Now have less data
		pBuffer += sData; // And buffer pointer goes forward
		mMdxi->second.unBuffer += sData;
		mMdxi->second.unSize += sData;

#ifdef _DEBUG
		cmd5 = mMdxi->second;
#endif // _DEBUG

		// If we have a whole block...
		if(64 == mMdxi->second.unBuffer)
		{
			// ...hash it
			MdxHashDependentBuffer((MDX_WORD *)mMdxi->second.pBuffer, mMdxi->second.hsState);
			mMdxi->second.unBuffer = 0;
		} // if
	} // while
	
	return TRUE;
}

MDX_API BOOL MdxHashFinal(HMDXCONTEXT hMdx, MDXHASH &hsMdx)
{
	if(0 == hMdx) 
	{
		return FALSE;
	} // if

	MDXCONTEXTMAP::iterator mMdxi = mMdxCtx.find(hMdx);
	if(mMdxCtx.end() == mMdxi) 
	{
		return FALSE;
	} // if

	// If we have more than of 56 bytes of data buffered, we must pad the pemaining bytes
	// with proper bits (0x80 first and 0x00 after that) and hash it, and then pad
	// 56 bytes of a new buffer with zeroes and append message length (which should also
	// be adjusted). It we have 56 or less bytes of buffered data, just pad it,
	// append length and hash.
	BYTE bPad = 0x80;

#ifdef _DEBUG
		MDXCONTEXT cmd5 = mMdxi->second;
#endif // _DEBUG

	if(mMdxi->second.unBuffer > 56) 
	{
		mMdxi->second.pBuffer[mMdxi->second.unBuffer] = 0x80;
		// And pad the rest with zeroes
		for(unsigned int n = mMdxi->second.unBuffer + 1; n < 64; ++n)
			mMdxi->second.pBuffer[n] = 0x00;

		MdxHashDependentBuffer((MDX_WORD *)mMdxi->second.pBuffer, mMdxi->second.hsState);

		mMdxi->second.unSize += 64 - mMdxi->second.unBuffer;
		mMdxi->second.unBuffer = 0;		

		bPad = 0x00; // Has already been padded
	} // if

#ifdef _DEBUG
	cmd5 = mMdxi->second;
#endif // _DEBUG

	// Either a new block or a block with less than 56 bytes of data. 
	// Padding with zeroes adjusting size...
	memset(mMdxi->second.pBuffer + mMdxi->second.unBuffer, 0, 64 - mMdxi->second.unBuffer);
	mMdxi->second.pBuffer[mMdxi->second.unBuffer] = bPad;

	mMdxi->second.unSize += 64 - mMdxi->second.unBuffer;

	// Appending 64-bit length
	unsigned __int64 nSz = (unsigned __int64)mMdxi->second.unSize;
	memmove(mMdxi->second.pBuffer + 56, &nSz, sizeof(unsigned __int64));

#ifdef _DEBUG
	cmd5 = mMdxi->second;
#endif // _DEBUG

	MdxHashDependentBuffer((MDX_WORD *)mMdxi->second.pBuffer, mMdxi->second.hsState);

	hsMdx = mMdxi->second.hsState;
	MdxResetContext(hMdx);

	return TRUE;
}

MDX_API BOOL MdxHashDependentBuffer(MDX_WORD *pwData, MDXHASH &hMdx)
{
	if(!g_pwSummands)
		return FALSE;

	MDX_WORD wA, wB, wC, wD;
	
	// Here we go
	wA = hMdx.wA;
	wB = hMdx.wB;
	wC = hMdx.wC;
	wD = hMdx.wD;

	// Stage 1
	FF(wA, wB, wC, wD, pwData[0], 7, g_pwSummands[0]);
	FF(wD, wA, wB, wC, pwData[1], 12, g_pwSummands[1]);
	FF(wC, wD, wA, wB, pwData[2], 17, g_pwSummands[2]);
	FF(wB, wC, wD, wA, pwData[3], 22, g_pwSummands[3]);

	FF(wA, wB, wC, wD, pwData[4], 7, g_pwSummands[4]);
	FF(wD, wA, wB, wC, pwData[5], 12, g_pwSummands[5]);
	FF(wC, wD, wA, wB, pwData[6], 17, g_pwSummands[6]);
	FF(wB, wC, wD, wA, pwData[7], 22, g_pwSummands[7]);

	FF(wA, wB, wC, wD, pwData[8], 7, g_pwSummands[8]);
	FF(wD, wA, wB, wC, pwData[9], 12, g_pwSummands[9]);
	FF(wC, wD, wA, wB, pwData[10], 17, g_pwSummands[10]);
	FF(wB, wC, wD, wA, pwData[11], 22, g_pwSummands[11]);

	FF(wA, wB, wC, wD, pwData[12], 7, g_pwSummands[12]);
	FF(wD, wA, wB, wC, pwData[13], 12, g_pwSummands[13]);
	FF(wC, wD, wA, wB, pwData[14], 17, g_pwSummands[14]);
	FF(wB, wC, wD, wA, pwData[15], 22, g_pwSummands[15]);

	// Stage 2 
	GG(wA, wB, wC, wD, pwData[1], 5, g_pwSummands[16]);
	GG(wD, wA, wB, wC, pwData[6], 9, g_pwSummands[17]);
	GG(wC, wD, wA, wB, pwData[11], 14, g_pwSummands[18]);
	GG(wB, wC, wD, wA, pwData[0], 20, g_pwSummands[19]);

	GG(wA, wB, wC, wD, pwData[5], 5, g_pwSummands[20]);
	GG(wD, wA, wB, wC, pwData[10], 9, g_pwSummands[21]);
	GG(wC, wD, wA, wB, pwData[15], 14, g_pwSummands[22]);
	GG(wB, wC, wD, wA, pwData[4], 20, g_pwSummands[23]);

	GG(wA, wB, wC, wD, pwData[9], 5, g_pwSummands[24]);
	GG(wD, wA, wB, wC, pwData[14], 9, g_pwSummands[25]);
	GG(wC, wD, wA, wB, pwData[3], 14, g_pwSummands[26]);
	GG(wB, wC, wD, wA, pwData[8], 20, g_pwSummands[27]);

	GG(wA, wB, wC, wD, pwData[13], 5, g_pwSummands[28]);
	GG(wD, wA, wB, wC, pwData[2], 9, g_pwSummands[29]);
	GG(wC, wD, wA, wB, pwData[7], 14, g_pwSummands[30]);
	GG(wB, wC, wD, wA, pwData[12], 20, g_pwSummands[31]);

	// Stage 3
	HH(wA, wB, wC, wD, pwData[5], 4, g_pwSummands[32]);
	HH(wD, wA, wB, wC, pwData[8], 11, g_pwSummands[33]);
	HH(wC, wD, wA, wB, pwData[11], 16, g_pwSummands[34]);
	HH(wB, wC, wD, wA, pwData[14], 23, g_pwSummands[35]);

	HH(wA, wB, wC, wD, pwData[1], 4, g_pwSummands[36]);
	HH(wD, wA, wB, wC, pwData[4], 11, g_pwSummands[37]);
	HH(wC, wD, wA, wB, pwData[7], 16, g_pwSummands[38]);
	HH(wB, wC, wD, wA, pwData[10], 23, g_pwSummands[39]);

	HH(wA, wB, wC, wD, pwData[13], 4, g_pwSummands[40]);
	HH(wD, wA, wB, wC, pwData[0], 11, g_pwSummands[41]);
	HH(wC, wD, wA, wB, pwData[3], 16, g_pwSummands[42]);
	HH(wB, wC, wD, wA, pwData[6], 23, g_pwSummands[43]);

	HH(wA, wB, wC, wD, pwData[8], 4, g_pwSummands[44]);
	HH(wD, wA, wB, wC, pwData[12], 11, g_pwSummands[45]);
	HH(wC, wD, wA, wB, pwData[15], 16, g_pwSummands[46]);
	HH(wB, wC, wD, wA, pwData[2], 23, g_pwSummands[47]);

	// Stage 4
	II(wA, wB, wC, wD, pwData[0], 6, g_pwSummands[48]);
	II(wD, wA, wB, wC, pwData[7], 10, g_pwSummands[49]);
	II(wC, wD, wA, wB, pwData[14], 15, g_pwSummands[50]);
	II(wB, wC, wD, wA, pwData[5], 21, g_pwSummands[51]);

	II(wA, wB, wC, wD, pwData[12], 6, g_pwSummands[52]);
	II(wD, wA, wB, wC, pwData[3], 10, g_pwSummands[53]);
	II(wC, wD, wA, wB, pwData[10], 15, g_pwSummands[54]);
	II(wB, wC, wD, wA, pwData[1], 21, g_pwSummands[55]);

	II(wA, wB, wC, wD, pwData[8], 6, g_pwSummands[56]);
	II(wD, wA, wB, wC, pwData[15], 10, g_pwSummands[57]);
	II(wC, wD, wA, wB, pwData[6], 15, g_pwSummands[58]);
	II(wB, wC, wD, wA, pwData[13], 21, g_pwSummands[59]);

	II(wA, wB, wC, wD, pwData[4], 6, g_pwSummands[60]);
	II(wD, wA, wB, wC, pwData[11], 10, g_pwSummands[61]);
	II(wC, wD, wA, wB, pwData[2], 15, g_pwSummands[62]);
	II(wB, wC, wD, wA, pwData[9], 21, g_pwSummands[63]);

	// Now we add resulting values to the MDX hash structure
	hMdx.wA += wA;
	hMdx.wB += wB;
	hMdx.wC += wC;
	hMdx.wD += wD;

	return TRUE;
}

MDX_API size_t MdxGetExpandedBufferSize(size_t sSize)
{
	// The (resultant buffer size + 8 bytes) must be a multiple of 64
	while((sSize + 8) % 64)
		++sSize;

	// Eight bytes for length
	sSize += 8;
	
	return sSize;
}

MDX_API BOOL MdxExpandData(void *pvData, size_t sSgSize, size_t sTotal)
{
	// First, we set all bytes starting from (pvData + sSgSize) to (pvData + sTotal) to zero
	memset((BYTE *)pvData + sSgSize, 0, sTotal - sSgSize);

	// Now we set the first byte after significant data to 0x80
	((BYTE *)pvData)[sSgSize] = 0x80;

	// And set last 64 bits (8 bytes) to be equal to total message size (sTotal)
	unsigned __int64 nSz = (unsigned __int64)sTotal;
	memmove((BYTE *)pvData + sTotal - 8, &nSz, sizeof(unsigned __int64));
	
	return TRUE;
}

MDX_API BOOL MdxHashData(MDX_WORD *pwData, UINT nBlocks, MDXHASH &hMdx)
{
	if(!g_pwSummands)
		return FALSE;

	hMdx.wA = g_wChainA;
	hMdx.wB = g_wChainB;
	hMdx.wC = g_wChainC;
	hMdx.wD = g_wChainD;

	for( ; nBlocks; --nBlocks, pwData += 16) // Moving data pointer 512 bits (16 words) forward
	{
		if(!MdxHashDependentBuffer(pwData, hMdx))
			return FALSE;
	} // for

	return TRUE;
}

MDX_API BOOL MdxEqualHashes(MDXHASH hsMdxA, MDXHASH hsMdxB)
{
	return ((hsMdxA.wA == hsMdxB.wA) &&
		(hsMdxA.wB == hsMdxB.wB) &&
		(hsMdxA.wC == hsMdxB.wC) &&
		(hsMdxA.wD == hsMdxB.wD));
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

AntonGogolev
Web Developer
Russian Federation Russian Federation
I'll think about it later on...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 7 Mar 2005
Article Copyright 2004 by AntonGogolev
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid