Răsfoiți Sursa

send clips encrypted across the network
[SAB]


git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@152 595ec19a-5cb4-439b-94a8-42fb3063c22c

sabrogden 21 ani în urmă
părinte
comite
69d94b16fa

+ 7 - 0
CP_Main.cpp

@@ -414,6 +414,8 @@ long CCP_MainApp::SaveCopyClips()
 		}
 	}
 
+	bool bEnteredThread = false;
+
 	count = pClips->AddToDB( true );
 	if( count > 0 )
 	{		
@@ -423,8 +425,13 @@ long CCP_MainApp::SaveCopyClips()
 		if(g_Opt.m_lAutoSendClientCount > 0)
 		{
 			AfxBeginThread(SendClientThread, pCopyOfClips);
+			bEnteredThread = true;
 		}
+		
 	}
+	
+	if(bEnteredThread == false)
+		delete pCopyOfClips;
 
 	delete pClips;
 

+ 26 - 6
CP_Main.dsp

@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "AFTER_98" /FAs /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "EncryptDecrypt\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "AFTER_98" /FAs /Yu"stdafx.h" /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
-# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib riched20.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"Release/Ditto.exe" /libpath:"focusdll\Release"
+# ADD LINK32 ws2_32.lib riched20.lib kernel32.lib user32.lib gdi32.lib winspool.lib Winmm.lib EncryptDecrypt.lib Version.Lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"Release/Ditto.exe" /libpath:"focusdll\Release"
 
 !ELSEIF  "$(CFG)" == "CP_Main - Win32 Debug"
 
@@ -69,7 +69,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "AFTER_98" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "EncryptDecrypt\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "AFTER_98" /Yu"stdafx.h" /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
@@ -79,7 +79,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib riched20.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/Ditto.exe" /pdbtype:sept
+# ADD LINK32 ws2_32.lib riched20.lib kernel32.lib user32.lib gdi32.lib winspool.lib Winmm.lib EncryptDecryptD.lib Version.Lib Pdh.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/Ditto.exe" /pdbtype:sept
 
 !ENDIF 
 
@@ -600,13 +600,33 @@ SOURCE=.\res\VerticleScrollbarTop.bmp
 SOURCE=.\res\VerticleScrollBarUpArrow.bmp
 # End Source File
 # End Group
+# Begin Group "Exclude From Build"
+
+# PROP Default_Filter ""
 # Begin Source File
 
-SOURCE=.\ReadMe.txt
+SOURCE=.\Debug\focus.dll
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=.\Release\focus.dll
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=.\EncryptDecryptD.lib
+# PROP Exclude_From_Build 1
 # End Source File
 # Begin Source File
 
-SOURCE=.\Version.Lib
+SOURCE=.\EncryptDecrypt.lib
+# PROP Exclude_From_Build 1
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
 # End Source File
 # Begin Source File
 

+ 12 - 8
CP_Main.dsw

@@ -7,10 +7,18 @@ Project: "CP_Main"=".\CP_Main.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
-    begin source code control
-    "$/", AAAAAAAA
-    .
-    end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "EncryptDecrypt"=".\EncryptDecrypt\EncryptDecrypt.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
 }}}
 
 Package=<4>
@@ -35,10 +43,6 @@ Global:
 
 Package=<5>
 {{{
-    begin source code control
-    "$/Ditto", UFAAAAAA
-    .
-    end source code control
 }}}
 
 Package=<3>

+ 18 - 12
CP_Main.rc

@@ -483,7 +483,7 @@ BEGIN
                     49,288,106
 END
 
-IDD_OPTIONS_GENERAL DIALOG DISCARDABLE  0, 0, 294, 188
+IDD_OPTIONS_GENERAL DIALOG DISCARDABLE  0, 0, 294, 199
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "General"
 FONT 8, "MS Sans Serif"
@@ -517,12 +517,16 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,131,101,10
     CONTROL         "Save Multi-Pastes",IDC_SAVE_MULTIPASTE,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,23,142,73,10
-    EDITTEXT        IDC_DESC_TEXT_SIZE,154,164,35,12,ES_AUTOHSCROLL
+    EDITTEXT        IDC_DESC_TEXT_SIZE,148,163,35,12,ES_AUTOHSCROLL
     LTEXT           "Amount of text to save for description",IDC_STATIC,24,
                     165,122,8
     CONTROL         "Hide Ditto on Hot Key if Ditto is Visible",
                     IDC_HIDE_DITO_ON_HOT_KEY,"Button",BS_AUTOCHECKBOX | 
                     WS_TABSTOP,23,153,135,10
+    LTEXT           "On copy play the sound",IDC_STATIC,24,177,81,10
+    EDITTEXT        IDC_EDIT_PLAY_SOUND,105,177,145,10,ES_AUTOHSCROLL
+    PUSHBUTTON      "....",IDC_SELECT_SOUND,273,177,14,12
+    PUSHBUTTON      "Play",IDC_BUTTON_PLAY,251,177,19,12
 END
 
 IDD_SELECT_DB DIALOG DISCARDABLE  0, 0, 276, 46
@@ -642,24 +646,26 @@ BEGIN
     EDITTEXT        IDC_NAME,7,11,172,12,ES_AUTOHSCROLL
 END
 
-IDD_OPTIONS_FRIENDS DIALOG DISCARDABLE  0, 0, 310, 227
+IDD_OPTIONS_FRIENDS DIALOG DISCARDABLE  0, 0, 321, 246
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Friends"
 FONT 8, "MS Sans Serif"
 BEGIN
     CONTROL         "List1",IDC_LIST,"SysListView32",LVS_REPORT | WS_BORDER | 
-                    WS_TABSTOP,7,93,296,116
+                    WS_TABSTOP,7,113,307,114
     LTEXT           "If Send All Copies is selected then all copies from this computer will be sent to the other computer.  If that is not selected then it will just be in the right click menu to send a copy to that computer.",
-                    IDC_STATIC,7,63,278,24
-    EDITTEXT        IDC_EDIT_PLACE_ON_CLIPBOARD,93,34,210,13,ES_AUTOHSCROLL
+                    IDC_STATIC,7,85,278,24
+    EDITTEXT        IDC_EDIT_PLACE_ON_CLIPBOARD,96,34,210,13,ES_AUTOHSCROLL
     LTEXT           "IP/Computer Names seperated by commas",IDC_STATIC,7,32,
                     70,17
     LTEXT           "When you recieve a sent copy if their ip or computer name is in this list then it will be put on the clipboard.  Otherwise it will be in the saved clips to use at a later time.",
-                    IDC_STATIC,7,10,296,18
+                    IDC_STATIC,7,10,307,18
     CONTROL         "Log Send Receive Commands",IDC_CHECK_LOG_SEND_RECIEVE,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,212,176,12
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,231,176,12
     CONTROL         "Disable Recieving Clips",IDC_CHECK_DISABLE_FRIENDS,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,48,90,10
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,95,48,90,10
+    LTEXT           "Network Password",IDC_STATIC,7,68,79,9
+    EDITTEXT        IDC_EDIT_PASSWORD,96,65,210,13,ES_AUTOHSCROLL
 END
 
 IDD_FRIEND_DETAILS DIALOG DISCARDABLE  0, 0, 203, 79
@@ -790,7 +796,7 @@ BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 287
         TOPMARGIN, 7
-        BOTTOMMARGIN, 180
+        BOTTOMMARGIN, 191
     END
 
     IDD_SELECT_DB, DIALOG
@@ -845,9 +851,9 @@ BEGIN
     IDD_OPTIONS_FRIENDS, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 303
+        RIGHTMARGIN, 314
         TOPMARGIN, 4
-        BOTTOMMARGIN, 224
+        BOTTOMMARGIN, 243
     END
 
     IDD_FRIEND_DETAILS, DIALOG

+ 82 - 23
Client.cpp

@@ -163,11 +163,18 @@ UINT  SendClientThread(LPVOID pParam)
 CClient::CClient()
 {
 	m_Connection = NULL;
+
+	m_pEncryptor = new CEncryption; //CreateEncryptionInterface("encryptdecrypt.dll");
 }
 
 CClient::~CClient()
 {			
 	CloseConnection();
+
+	delete m_pEncryptor;
+	m_pEncryptor = NULL;
+
+//	ReleaseEncryptionInterface(m_pEncryptor);
 }
 
 BOOL CClient::CloseConnection()
@@ -228,12 +235,13 @@ BOOL CClient::OpenConnection(const char* servername)
 		return FALSE;
 	}
 
-	server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
-	server.sin_family=AF_INET;
-	server.sin_port=htons( (u_short) g_Opt.m_lPort );
-	if(connect(m_Connection,(struct sockaddr*)&server,sizeof(server)))
+	server.sin_addr.s_addr = *((unsigned long*)hp->h_addr);
+	server.sin_family = AF_INET;
+	server.sin_port = htons((u_short) g_Opt.m_lPort);
+	if(connect(m_Connection, (struct sockaddr*)&server, sizeof(server)))
 	{
-		LogSendRecieveInfo("ERROR if(connect(m_Connection,(struct sockaddr*)&server,sizeof(server)))");
+		int nWhy = WSAGetLastError();
+		LogSendRecieveInfo(StrF("ERROR if(connect(m_Connection,(struct sockaddr*)&server,sizeof(server))) why = %d", nWhy));
 		closesocket(m_Connection);
 		m_Connection = NULL;
 		return FALSE;	
@@ -266,16 +274,42 @@ BOOL CClient::SendItem(CClip *pClip)
 	{
 		pCF = &pClip->m_Formats.GetData()[i];
 		
-		Info.m_lParameter1 = GlobalSize(pCF->m_hgData);
-		strncpy(Info.m_cDesc, GetFormatName(pCF->m_cfType), sizeof(Info.m_cDesc));
-		Info.m_cDesc[sizeof(Info.m_cDesc)-1] = 0;
+		LPVOID pvData = GlobalLock(pCF->m_hgData);
+		long lLength = GlobalSize(pCF->m_hgData);
 
-		if(SendCSendData(Info, MyEnums::DATA_START) == FALSE)
-			return FALSE;
+		UCHAR* pOutput = NULL;
+		int nLenOutput = 0;
 
-		LPVOID pvData = GlobalLock(pCF->m_hgData);
+		LogSendRecieveInfo(StrF("BEFORE Encrypt clip data %d", lLength));
+
+		if(m_pEncryptor)
+		{
+			if(m_pEncryptor->Encrypt((UCHAR*)pvData, lLength, g_Opt.m_csPassword, pOutput, nLenOutput))
+			{
+				LogSendRecieveInfo(StrF("AFTER Encrypt clip data %d", nLenOutput));
 
-		SendExactSize((char*)pvData, Info.m_lParameter1);
+				Info.m_lParameter1 = nLenOutput;
+				strncpy(Info.m_cDesc, GetFormatName(pCF->m_cfType), sizeof(Info.m_cDesc));
+				Info.m_cDesc[sizeof(Info.m_cDesc)-1] = 0;
+
+				if(SendCSendData(Info, MyEnums::DATA_START) == FALSE)
+					return FALSE;
+
+				SendExactSize((char*)pOutput, nLenOutput, false);
+
+				m_pEncryptor->FreeBuffer(pOutput);
+			}
+			else
+			{
+				LogSendRecieveInfo("Failed to encrypt data");
+				return FALSE;
+			}
+		}
+		else
+		{
+			ASSERT(!"SendItem::Encryption not initialized");
+			LogSendRecieveInfo("SendItem::Encryption not initialized");	
+		}
 
 		GlobalUnlock(pCF->m_hgData);
 		
@@ -297,26 +331,51 @@ BOOL CClient::SendCSendData(CSendInfo &data, MyEnums::eSendType type)
 	return SendExactSize((char *)&data, sizeof(CSendInfo));
 }
 
-BOOL CClient::SendExactSize(char *pData, long lLength)
+BOOL CClient::SendExactSize(char *pData, long lLength, bool bEncrypt)
 {
+	BOOL bRet = FALSE;
+	if(!m_pEncryptor && bEncrypt)
+	{
+		ASSERT(!"Encryption not initialized");
+		LogSendRecieveInfo("SendExactSize::Encryption not initialized");
+		return bRet;
+	}
+
+	LogSendRecieveInfo(StrF("START SendExactSize Total %d", lLength));
+
+	UCHAR* pOutput = (UCHAR*)pData;
+	int nLenOutput = lLength;
 	long lBytesRead = 0;
-	long lExpected = lLength;
 
-	while(lBytesRead < lExpected)
+	if(bEncrypt == false || m_pEncryptor->Encrypt((UCHAR*)pData, lLength, g_Opt.m_csPassword, pOutput, nLenOutput))
 	{
-		long lSize = send(m_Connection, pData + lBytesRead, lExpected - lBytesRead, 0);
-	
-		if(lSize == SOCKET_ERROR || lSize == 0)
+		long lExpected = nLenOutput;
+
+		while(lBytesRead < lExpected)
 		{
-			LogSendRecieveInfo(StrF("lSize == SOCKET_ERROR, %d", WSAGetLastError()));
-			return FALSE;
+			long lSize = send(m_Connection, (char*)pOutput + lBytesRead, lExpected - lBytesRead, 0);
+		
+			if(lSize == SOCKET_ERROR || lSize == 0)
+			{
+				LogSendRecieveInfo(StrF("lSize == SOCKET_ERROR, %d", WSAGetLastError()));
+				break;
+			}
+			lBytesRead += lSize;
+
+			LogSendRecieveInfo(StrF("SendExactSize Last Size %d - Total %d", lSize, lBytesRead));
 		}
-		lBytesRead += lSize;
 
-		LogSendRecieveInfo(StrF("SendExactSize Last Size %d - Total %d", lSize, lBytesRead));
+		bRet = TRUE;
+
+		if(pOutput != (UCHAR*)pData)
+			m_pEncryptor->FreeBuffer(pOutput);
+	}
+	else
+	{
+		LogSendRecieveInfo("SendExactSize::Failed to encrypt data");
 	}
 
 	LogSendRecieveInfo(StrF("END SendExactSize Total %d", lBytesRead));
 
-	return TRUE;
+	return bRet;
 }

+ 5 - 1
Client.h

@@ -10,6 +10,7 @@
 #endif // _MSC_VER > 1000
 
 #include "Server.h"
+#include "Encryption.h"
 
 class CSendToFriendInfo
 {
@@ -52,7 +53,10 @@ protected:
 	SOCKET m_Connection;
 
 	BOOL SendCSendData(CSendInfo &data, MyEnums::eSendType type);
-	BOOL SendExactSize(char *pData, long lLength);
+	BOOL SendExactSize(char *pData, long lLength, bool bEncrypt = true);
+
+protected:
+	CEncryption *m_pEncryptor;
 };
 
 BOOL SendToFriend(CSendToFriendInfo &Info);

+ 3 - 9
DittoSetup/DittoSetup.iss

@@ -20,18 +20,13 @@ Name: RunAtStartup; Description: "Run Ditto on Windows Startup";
 
 [Files]
 
-;installed if it is 2000 or greater
-Source: "..\Release\Ditto.exe"; DestDir: "{app}"; MinVersion: 0, 1; DestName: "Ditto.exe"; Flags: ignoreversion
-
-;installed if it is 95, 98, me
-Source: "..\Release\Ditto98.exe"; DestDir: "{app}"; MinVersion: 1, 0; DestName: "Ditto.exe"; Flags: ignoreversion
+Source: "..\Release\Ditto.exe"; DestDir: "{app}"; DestName: "Ditto.exe"; Flags: ignoreversion
+Source: "..\Release\focus.dll"; DestDir: "{app}";  Flags: ignoreversion onlyifdoesntexist
 
 Source: "Output\Changes.txt"; DestDir: "{app}"
 
-Source: "..\Release\focus.dll"; DestDir: "{app}";  Flags: ignoreversion onlyifdoesntexist
-
 ;Add help files
-Source: "..\Help\*.*"; DestDir: "{app}\Help"; Flags: ignoreversion
+Source: "..\Help\*.htm"; DestDir: "{app}\Help"; Flags: ignoreversion
 
 [Icons]
 Name: "{group}\Ditto"; Filename: "{app}\Ditto.exe";
@@ -43,7 +38,6 @@ Filename: "{app}\Ditto.exe"; Description: "Launch Ditto"; Flags: nowait postinst
 Filename: "{app}\Help\DittoGettingStarted.htm"; Description: "View Help"; Flags: nowait postinstall skipifsilent shellexec
 Filename: "{app}\Changes.txt"; Description: "View Change History"; Flags: nowait postinstall skipifsilent shellexec unchecked
 
-
 [Registry]
 Root: HKCU; Subkey: "Software\Ditto"; Flags: uninsdeletekey
 Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "Ditto"; flags: uninsdeletekey; ValueData: "{app}\Ditto.exe"; Tasks: RunAtStartup

BIN
EncryptDecrypt.lib


+ 159 - 0
EncryptDecrypt/EncryptDecrypt.dsp

@@ -0,0 +1,159 @@
+# Microsoft Developer Studio Project File - Name="EncryptDecrypt" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=EncryptDecrypt - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "EncryptDecrypt.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "EncryptDecrypt.mak" CFG="EncryptDecrypt - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "EncryptDecrypt - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "EncryptDecrypt - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "EncryptDecrypt - Win32 Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "EncrypDecrypt" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+# Begin Special Build Tool
+OutDir=.\Release
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy  $(OutDir)\*.lib  ..\ 
+# End Special Build Tool
+
+!ELSEIF  "$(CFG)" == "EncryptDecrypt - Win32 Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ  /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ   /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Debug\EncryptDecryptD.lib"
+# Begin Special Build Tool
+OutDir=.\Debug
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy  $(OutDir)\*.lib  ..\ 
+# End Special Build Tool
+
+!ENDIF 
+
+# Begin Target
+
+# Name "EncryptDecrypt - Win32 Release"
+# Name "EncryptDecrypt - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Encryption.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MemUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NewRandom.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rijndael.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sha2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Encryption.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IEncryption.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MemUtil.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NewRandom.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rijndael.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sha2.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Readme.txt
+# End Source File
+# End Target
+# End Project

+ 53 - 0
EncryptDecrypt/EncryptDecrypt.plg

@@ -0,0 +1,53 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: EncryptDecrypt - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A3.tmp" with contents
+[
+/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/EncryptDecrypt.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\Encryption.cpp"
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\MemUtil.cpp"
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\NewRandom.cpp"
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\rijndael.cpp"
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\sha2.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A3.tmp" 
+Creating temporary file "C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A4.tmp" with contents
+[
+/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/EncryptDecrypt.pch" /Yc"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
+"C:\Documents and Settings\Scott\Desktop\ditto\EncryptDecrypt\StdAfx.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A4.tmp" 
+Creating command line "link.exe -lib /nologo /out:"Debug\EncryptDecryptD.lib"  ".\Debug\Encryption.obj" ".\Debug\MemUtil.obj" ".\Debug\NewRandom.obj" ".\Debug\rijndael.obj" ".\Debug\sha2.obj" ".\Debug\StdAfx.obj" "
+<h3>Output Window</h3>
+Compiling...
+StdAfx.cpp
+Compiling...
+Encryption.cpp
+MemUtil.cpp
+NewRandom.cpp
+rijndael.cpp
+sha2.cpp
+Generating Code...
+Creating library...
+Creating temporary file "C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A5.bat" with contents
+[
+@echo off
+copy  .\Debug\*.lib  ..\
+]
+Creating command line "C:\DOCUME~1\Scott\LOCALS~1\Temp\RSP37A5.bat"
+
+.\Debug\EncryptDecryptD.lib
+        1 file(s) copied.
+
+
+
+<h3>Results</h3>
+EncryptDecryptD.lib - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>

+ 317 - 0
EncryptDecrypt/Encryption.cpp

@@ -0,0 +1,317 @@
+// Encryption.cpp: implementation of the CEncryption class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "Encryption.h"
+
+#include "MemUtil.h"
+#include "rijndael.h"
+#include "sha2.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CEncryption::CEncryption()
+{
+	m_dwKeyEncRounds = TD_STD_KEYENCROUNDS;
+
+	memset(m_pMasterKey, 0, 32);
+
+	m_random.Initialize();
+}
+
+CEncryption::~CEncryption()
+{
+	mem_erase(m_pMasterKey, 32);
+
+	m_random.Reset();
+}
+
+void CEncryption::Release()
+{
+	delete this;
+}
+
+bool CEncryption::Encrypt(const unsigned char* pInput, int nLenInput, const char* szPassword, 
+						 unsigned char*& pOutput, int& nLenOutput)
+{
+	bool			bResult = false;
+	TD_TLHEADER		hdr;
+	RD_UINT8		uFinalKey[32];
+	unsigned long	uFileSize = 0, uAllocated = 0, pos = 0;
+	int				nEncryptedPartSize = 0;
+
+	ASSERT(NULL != pInput);		if(NULL == pInput)		return FALSE;
+	ASSERT(0	!= nLenInput);	if(0	== nLenInput)	return FALSE;
+	ASSERT(NULL != szPassword); if(NULL == szPassword)	return FALSE;
+
+	uFileSize = nLenInput + sizeof(TD_TLHEADER);
+
+	// Allocate enough memory
+	uAllocated = uFileSize + 16;
+	pOutput = new unsigned char[uAllocated];
+	if(NULL != pOutput)
+	{
+		unsigned long uKeyLen;
+
+		// Build header structure
+		hdr.dwSignature1 = TD_TLSIG_1;
+		hdr.dwSignature2 = TD_TLSIG_2;
+		hdr.dwKeyEncRounds = m_dwKeyEncRounds;
+
+		// Make up the master key hash seed and the encryption IV
+		m_random.GetRandomBuffer(hdr.aMasterSeed, 16);
+		m_random.GetRandomBuffer((BYTE *)hdr.aEncryptionIV, 16);
+		m_random.GetRandomBuffer(hdr.aMasterSeed2, 32);
+
+		// Create MasterKey by hashing szPassword
+		uKeyLen = strlen(szPassword);
+		ASSERT(0 != uKeyLen);
+		if(0 != uKeyLen)
+		{
+			sha256_ctx sha32;
+
+			sha256_begin(&sha32);
+			sha256_hash((unsigned char *)szPassword, uKeyLen, &sha32);
+			sha256_end(m_pMasterKey, &sha32);
+
+			// Generate m_pTransformedMasterKey from m_pMasterKey
+			if(TRUE == _TransformMasterKey(hdr.aMasterSeed2))
+			{
+				// Hash the master password with the generated hash salt
+				sha256_begin(&sha32);
+				sha256_hash(hdr.aMasterSeed, 16, &sha32);
+				sha256_hash(m_pTransformedMasterKey, 32, &sha32);
+				sha256_end((unsigned char *)uFinalKey, &sha32);
+
+				// Hash the tasklist contents
+				sha256_begin(&sha32);
+				sha256_hash((unsigned char *)pInput, nLenInput, &sha32);
+				sha256_end((unsigned char *)hdr.aContentsHash, &sha32);
+
+				// Hash the header
+				sha256_begin(&sha32);
+				sha256_hash((unsigned char *)&hdr + 32, sizeof(TD_TLHEADER) - 32, &sha32);
+				sha256_end((unsigned char *)hdr.aHeaderHash, &sha32);
+				
+				bResult = true;
+			}
+		}
+	}
+
+	if (bResult)
+	{
+		bResult = false;
+		
+		// Now we have all to build up the header
+		memcpy(pOutput, &hdr, sizeof(TD_TLHEADER));
+	
+		Rijndael aes;
+		// Initialize Rijndael/AES
+		if(RIJNDAEL_SUCCESS == aes.init(Rijndael::CBC, Rijndael::Encrypt, uFinalKey,
+			Rijndael::Key32Bytes, hdr.aEncryptionIV) )
+		{
+			nEncryptedPartSize = aes.padEncrypt((RD_UINT8 *)pInput, nLenInput, (RD_UINT8 *)pOutput + sizeof(TD_TLHEADER));
+
+			// Check if all went correct
+			ASSERT(0 <= nEncryptedPartSize);
+			if(0 <= nEncryptedPartSize)
+			{
+				bResult = true; // data encrypted successfully
+			}
+
+			nLenOutput = sizeof(TD_TLHEADER) + nEncryptedPartSize;
+		}
+	}
+
+	if (!bResult)
+	{
+		SAFE_DELETE_ARRAY(pOutput);
+	}
+
+	return (bResult);
+}
+
+
+
+
+bool CEncryption::Decrypt(const unsigned char* pInput, int nLenInput, const char* szPassword,
+						 unsigned char*& pOutput, int& nLenOutput)
+{
+	bool			bResult = false;
+	TD_TLHEADER		hdr;
+	RD_UINT8		uFinalKey[32];
+	sha256_ctx		sha32;
+
+
+	ASSERT(NULL != pInput);						if(NULL == pInput)					return FALSE;
+	ASSERT(0	!= nLenInput);					if(0	== nLenInput)				return FALSE;
+	ASSERT(NULL != szPassword);					if(NULL == szPassword)				return FALSE;
+	ASSERT(sizeof(TD_TLHEADER) <= nLenInput);	if(sizeof(TD_TLHEADER) > nLenInput) return FALSE; 
+
+	// Extract header structure from memory file
+	memcpy(&hdr, pInput, sizeof(TD_TLHEADER));
+
+	// Hash the header
+	sha256_begin(&sha32);
+	sha256_hash((unsigned char *)&hdr + 32, sizeof(TD_TLHEADER) - 32, &sha32);
+	sha256_end((unsigned char *)uFinalKey, &sha32);
+
+	// Check if hash of header is the same as stored hash
+	// to verify integrity of header
+	if(0 == memcmp(hdr.aHeaderHash, uFinalKey, 32))
+	{
+		// Check if we can open this
+		if((hdr.dwSignature1 == TD_TLSIG_1) && (hdr.dwSignature2 == TD_TLSIG_2))
+		{
+			// Allocate enough memory
+			pOutput = new unsigned char[nLenInput];
+			if(NULL != pOutput)
+			{
+				memset(pOutput, 0, nLenInput);
+				unsigned long uKeyLen = strlen(szPassword);
+
+				// Create MasterKey by hashing szPassword
+				ASSERT(0 != uKeyLen);
+				if(0 != uKeyLen)
+				{
+					sha256_begin(&sha32);
+					sha256_hash((unsigned char *)szPassword, uKeyLen, &sha32);
+					sha256_end(m_pMasterKey, &sha32);
+
+					m_dwKeyEncRounds = hdr.dwKeyEncRounds;
+
+					// Generate m_pTransformedMasterKey from m_pMasterKey
+					if(TRUE == _TransformMasterKey(hdr.aMasterSeed2))
+					{
+						// Hash the master password with the generated hash salt
+						sha256_begin(&sha32);
+						sha256_hash(hdr.aMasterSeed, 16, &sha32);
+						sha256_hash(m_pTransformedMasterKey, 32, &sha32);
+						sha256_end((unsigned char *)uFinalKey, &sha32);
+
+						bResult = true;
+					}
+				}
+			}
+		}
+	}
+
+	if (bResult)
+	{
+		bResult = false;
+
+		Rijndael aes;
+		// Initialize Rijndael/AES
+		if(RIJNDAEL_SUCCESS == aes.init(Rijndael::CBC, Rijndael::Decrypt, uFinalKey,
+			Rijndael::Key32Bytes, hdr.aEncryptionIV) )
+		{
+			nLenOutput = aes.padDecrypt((RD_UINT8 *)pInput + sizeof(TD_TLHEADER), nLenInput - sizeof(TD_TLHEADER), (RD_UINT8 *)pOutput);
+
+			// Check if all went correct
+			ASSERT(0 <= nLenOutput);
+			if(0 <= nLenOutput)
+			{
+				// Check contents correct (with high probability)
+				sha256_begin(&sha32);
+				sha256_hash((unsigned char *)pOutput, nLenOutput, &sha32);
+				sha256_end((unsigned char *)uFinalKey, &sha32);
+				if(0 == memcmp(hdr.aContentsHash, uFinalKey, 32))
+				{
+					bResult = true; // data decrypted successfully
+				}
+			}
+		}
+	}
+
+	if (!bResult)
+	{
+		SAFE_DELETE_ARRAY(pOutput);
+	}
+
+	return (bResult);
+}
+
+void CEncryption::FreeBuffer(unsigned char*& pBuffer)
+{
+	SAFE_DELETE_ARRAY(pBuffer);
+}
+
+
+
+/*
+  Copyright (c) 2003/2004, Dominik Reichl <[email protected]>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer. 
+  - Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  - Neither the name of ReichlSoft nor the names of its contributors may be
+    used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+// Encrypt the master key a few times to make brute-force key-search harder
+BOOL CEncryption::_TransformMasterKey(BYTE *pKeySeed)
+{
+	Rijndael rijndael;
+	RD_UINT8 aKey[32];
+	RD_UINT8 aTest[16];
+	RD_UINT8 aRef[16] = { // The Rijndael class will be tested, that's the expected ciphertext
+		0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+		0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89
+	};
+	DWORD i;
+	sha256_ctx sha2;
+
+	ASSERT(pKeySeed != NULL); if(pKeySeed == NULL) return FALSE;
+
+	if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, (const RD_UINT8 *)pKeySeed,
+		Rijndael::Key32Bytes, 0) != RIJNDAEL_SUCCESS)
+	{
+		return FALSE;
+	}
+
+	memcpy(m_pTransformedMasterKey, m_pMasterKey, 32);
+
+	for(i = 0; i < m_dwKeyEncRounds; i++)
+	{
+		rijndael.blockEncrypt((const RD_UINT8 *)m_pTransformedMasterKey, 256, (RD_UINT8 *)m_pTransformedMasterKey);
+	}
+
+	// Do a quick test if the Rijndael class worked correctly
+	for(i = 0; i < 32; i++) aKey[i] = (RD_UINT8)i;
+	for(i = 0; i < 16; i++) aTest[i] = ((RD_UINT8)i << 4) | (RD_UINT8)i;
+	if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, aKey, Rijndael::Key32Bytes, NULL) != RIJNDAEL_SUCCESS)
+		{ ASSERT(FALSE); return FALSE; }
+	if(rijndael.blockEncrypt(aTest, 128, aTest) != 128) { ASSERT(FALSE); }
+	if(memcmp(aTest, aRef, 16) != 0) { ASSERT(FALSE); return FALSE; }
+
+	// Hash once with SHA-256
+	sha256_begin(&sha2);
+	sha256_hash(m_pTransformedMasterKey, 32, &sha2);
+	sha256_end(m_pTransformedMasterKey, &sha2);
+
+	return TRUE;
+}
+
+

+ 69 - 0
EncryptDecrypt/Encryption.h

@@ -0,0 +1,69 @@
+// Encryption.h: interface for the CEncryption class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_ENCRYPTION_H__06C80AE2_89BD_4040_A303_D3A71F44BFBD__INCLUDED_)
+#define AFX_ENCRYPTION_H__06C80AE2_89BD_4040_A303_D3A71F44BFBD__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "iencryption.h"
+
+#include "rijndael.h"
+#include "NewRandom.h"
+
+// The signature constants were chosen randomly
+#define TD_TLSIG_1				0x139C5AFE
+#define TD_TLSIG_2				0xBF3562DA
+
+#define TD_STD_KEYENCROUNDS		100000
+
+#pragma pack(1)
+
+typedef struct _TD_TLHEADER // The database header
+{
+	BYTE	aHeaderHash[32];	// SHA-256 hash of the rest of the header
+
+	DWORD dwSignature1; // = TD_TLSIG_1
+	DWORD dwSignature2; // = TD_TLSIG_2
+
+	BYTE aMasterSeed[16]; // Seed that gets hashed with the userkey to form the final key
+	RD_UINT8 aEncryptionIV[16]; // IV used for content encryption
+
+	BYTE aContentsHash[32]; // SHA-256 hash of the database, used for integrity check
+
+	BYTE aMasterSeed2[32]; // Used for the dwKeyEncRounds AES transformations
+	DWORD dwKeyEncRounds;
+} TD_TLHEADER, *PTD_TLHEADER;
+
+#pragma pack()
+
+
+class CEncryption : public IEncryption
+{
+public:
+	CEncryption();
+	virtual ~CEncryption();
+
+	void Release();
+	bool Encrypt(const unsigned char* szInput, int nLenInput, const char* szPassword,
+						 unsigned char*& pOutput, int& nLenOutput);
+	bool Decrypt(const unsigned char* pInput, int nLenInput, const char* szPassword,
+						 unsigned char*& pOutput, int& nLenOutput);
+	void FreeBuffer(unsigned char*& pBuffer);
+
+private:
+	// Encrypt the master key a few times to make brute-force key-search harder
+	BOOL _TransformMasterKey(BYTE *pKeySeed);
+
+	BYTE	m_pMasterKey[32]; // Master key used to encrypt the whole database
+	BYTE	m_pTransformedMasterKey[32]; // Master key encrypted several times
+	DWORD	m_dwKeyEncRounds;
+
+	CNewRandom	m_random; // Pseudo-random number generator
+
+};
+
+#endif // !defined(AFX_ENCRYPTION_H__06C80AE2_89BD_4040_A303_D3A71F44BFBD__INCLUDED_)

+ 98 - 0
EncryptDecrypt/IEncryption.h

@@ -0,0 +1,98 @@
+// IEncryption.h: interface for the IEncryption class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_IENCRYPTION_H__7741547B_BA15_4851_A41B_2B4EC1DC12D5__INCLUDED_)
+#define AFX_IENCRYPTION_H__7741547B_BA15_4851_A41B_2B4EC1DC12D5__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// function to be exported from dll to create instance of interface
+#ifdef _EXPORTING // declare this in project settings for dll _only_
+#	define DLL_DECLSPEC __declspec(dllexport)
+#else
+#	define DLL_DECLSPEC __declspec(dllimport)
+#endif 
+
+#define IENCRYPTION_VERSION 0x0000
+
+class IEncryption;
+
+typedef IEncryption* (*PFNCREATE)(); // function prototype
+extern "C" DLL_DECLSPEC IEncryption* CreateEncryptionInterface();
+
+typedef int (*PFNGETVERSION)(); // function prototype
+extern "C" DLL_DECLSPEC int GetInterfaceVersion();
+
+// helper method
+static IEncryption* CreateEncryptionInterface(const char* szDllPath)
+{
+    IEncryption* pInterface = NULL;
+    HMODULE hDll = LoadLibrary(szDllPath);
+	
+    if (hDll)
+    {
+        PFNCREATE pCreate = (PFNCREATE)GetProcAddress(hDll, "CreateEncryptionInterface");
+		
+        if (pCreate)
+		{
+			// check version
+			PFNGETVERSION pVersion = (PFNGETVERSION)GetProcAddress(hDll, "GetInterfaceVersion");
+
+			if (!IENCRYPTION_VERSION || (pVersion && pVersion() >= IENCRYPTION_VERSION))
+				pInterface = pCreate();
+		}
+    }
+	
+    return pInterface;
+}
+
+static BOOL IsEncryptionDll(const char* szDllPath)
+{
+    HMODULE hDll = LoadLibrary(szDllPath);
+	
+    if (hDll)
+    {
+        PFNCREATE pCreate = (PFNCREATE)GetProcAddress(hDll, "CreateEncryptionInterface");
+		FreeLibrary(hDll);
+
+		return (NULL != pCreate);
+	}
+
+	return FALSE;
+}
+
+class IEncryption
+{
+public:
+    virtual void Release() = 0; // releases the interface
+	
+    // returns a dynamically allocated buffer to the encrypted text
+    // caller responsible for calling FreeBuffer on the returned buffer
+    virtual bool Encrypt(const unsigned char* pInput, int nLenInput, const char* szPassword, 
+						 unsigned char*& pOutput, int& nLenOutput) = 0;
+	
+    // returns a dynamically allocated buffer to the decrypted text
+    // caller responsible for calling FreeBuffer on the returned buffer
+    virtual bool Decrypt(const unsigned char* pInput, int nLenInput, const char* szPassword,
+						 unsigned char*& pOutput, int& nLenOutput) = 0;
+	
+    // frees a previously returned buffer and sets the ptr to NULL
+    // eg for buffer allocated with 'new' use 'delete []'
+    // eg for buffer allocated with 'strdup' use 'free'
+    virtual void FreeBuffer(unsigned char*& pBuffer) = 0;
+	
+};
+
+static void ReleaseEncryptionInterface(IEncryption*& pInterface)
+{
+    if (pInterface)
+    {
+        pInterface->Release();
+        pInterface = NULL;
+    }
+}
+
+#endif // !defined(AFX_IENCRYPTION_H__7741547B_BA15_4851_A41B_2B4EC1DC12D5__INCLUDED_)

+ 66 - 0
EncryptDecrypt/MemUtil.cpp

@@ -0,0 +1,66 @@
+/*
+  Copyright (c) 2003/2004, Dominik Reichl <[email protected]>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer. 
+  - Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  - Neither the name of ReichlSoft nor the names of its contributors may be
+    used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "StdAfx.h"
+#include "MemUtil.h"
+#include "NewRandom.h"
+
+void mem_erase(unsigned char *p, unsigned long u)
+{
+	unsigned long i;
+
+	ASSERT(p != NULL);
+	if(p == NULL) return;
+	ASSERT(u != 0);
+	if(u == 0) return;
+
+	for(i = 0; i < u; i++)
+		p[i] = (unsigned char)(rand() & 0xFF);
+	for(i = 0; i < u; i++)
+		p[i] = (unsigned char)(rand() & 0xFF);
+	for(i = 0; i < u; i++)
+		p[i] = (unsigned char)(rand() & 0xFF);
+
+	memset(p, 0, u);
+}
+
+// Pack time to 5 byte structure:
+// Byte bits: 11111111 22222222 33333333 44444444 55555555
+// Contents : 00YYYYYY YYYYYYMM MMDDDDDH HHHHMMMM MMSSSSSS
+
+void _PackTimeToStruct(BYTE *pBytes, DWORD dwYear, DWORD dwMonth, DWORD dwDay, DWORD dwHour, DWORD dwMinute, DWORD dwSecond)
+{
+	ASSERT(pBytes != NULL); if(pBytes == NULL) return;
+	// Pack the time to a 5 byte structure
+	pBytes[0] = (BYTE)((dwYear >> 6) & 0x0000003F);
+	pBytes[1] = (BYTE)(((dwYear & 0x0000003F) << 2) | ((dwMonth >> 2) & 0x00000003));
+	pBytes[2] = (BYTE)(((dwMonth & 0x00000003) << 6) | ((dwDay & 0x0000001F) << 1) | ((dwHour >> 4) & 0x00000001));
+	pBytes[3] = (BYTE)(((dwHour & 0x0000000F) << 4) | ((dwMinute >> 2) & 0x0000000F));
+	pBytes[4] = (BYTE)(((dwMinute & 0x00000003) << 6) | (dwSecond & 0x0000003F));
+}

+ 45 - 0
EncryptDecrypt/MemUtil.h

@@ -0,0 +1,45 @@
+/*
+  Copyright (c) 2003/2004, Dominik Reichl <[email protected]>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer. 
+  - Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  - Neither the name of ReichlSoft nor the names of its contributors may be
+    used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ___MEMORY_UTILITIES_H___
+#define ___MEMORY_UTILITIES_H___
+
+//#include "../StdAfx.h"
+
+// Safely delete pointers
+#define SAFE_DELETE_ARRAY(p) { if((p) != NULL) { delete [](p);  (p) = NULL; } }
+
+
+// Securely erase memory
+void mem_erase(unsigned char *p, unsigned long u);
+
+// Time conversion functions
+void _PackTimeToStruct(BYTE *pBytes, DWORD dwYear, DWORD dwMonth, DWORD dwDay, DWORD dwHour, DWORD dwMinute, DWORD dwSecond);
+
+#endif

+ 281 - 0
EncryptDecrypt/NewRandom.cpp

@@ -0,0 +1,281 @@
+/*
+  Copyright (c) 2003/2004, Dominik Reichl <[email protected]>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer. 
+  - Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  - Neither the name of ReichlSoft nor the names of its contributors may be
+    used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "StdAfx.h"
+#include "NewRandom.h"
+#include "MemUtil.h"
+
+static DWORD g_dwNewRandomInstanceCounter = 0;
+
+static unsigned long g_xorW = 0;
+static unsigned long g_xorX = 0;
+static unsigned long g_xorY = 0;
+static unsigned long g_xorZ = 0;
+
+CNewRandom::CNewRandom()
+{
+	Reset();
+}
+
+CNewRandom::~CNewRandom()
+{
+	Reset();
+}
+
+void CNewRandom::Reset()
+{
+	mem_erase(m_pPseudoRandom, INTRAND_SIZE);
+	m_dwCounter = 0;
+}
+
+void CNewRandom::Initialize()
+{
+	DWORD inx;
+
+	WORD ww;
+	DWORD dw;
+	LARGE_INTEGER li;
+	SYSTEMTIME st;
+	POINT pt;
+	MEMORYSTATUS ms;
+	SYSTEM_INFO si;
+#ifndef _WIN32_WCE
+	STARTUPINFO sui;
+#endif
+
+	g_dwNewRandomInstanceCounter++;
+
+	Reset();
+
+	inx = 0;
+
+	dw = GetTickCount();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	QueryPerformanceCounter(&li);
+	memcpy(&m_pPseudoRandom[inx], &li, sizeof(LARGE_INTEGER));
+	inx += sizeof(LARGE_INTEGER);
+
+	GetLocalTime(&st);
+	memcpy(&m_pPseudoRandom[inx], &st, sizeof(SYSTEMTIME));
+	inx += sizeof(SYSTEMTIME);
+
+	GetCursorPos(&pt);
+	memcpy(&m_pPseudoRandom[inx], &pt, sizeof(POINT));
+	inx += sizeof(POINT);
+
+	ww = (WORD)(rand());
+	memcpy(&m_pPseudoRandom[inx], &ww, 2); inx += 2;
+	ww = (WORD)(rand());
+	memcpy(&m_pPseudoRandom[inx], &ww, 2); inx += 2;
+	ww = (WORD)(rand());
+	memcpy(&m_pPseudoRandom[inx], &ww, 2); inx += 2;
+
+	GetCaretPos(&pt);
+	memcpy(&m_pPseudoRandom[inx], &pt, sizeof(POINT));
+	inx += sizeof(POINT);
+
+	GlobalMemoryStatus(&ms);
+	memcpy(&m_pPseudoRandom[inx], &ms, sizeof(MEMORYSTATUS));
+	inx += sizeof(MEMORYSTATUS);
+
+	dw = (DWORD)GetActiveWindow();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetCapture();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetClipboardOwner();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+#ifndef _WIN32_WCE
+	// No support under Windows CE
+	dw = (DWORD)GetClipboardViewer();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); 
+#else
+	// Leave the stack data - random :)
+#endif
+	inx += 4;
+
+	dw = GetCurrentProcessId();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetCurrentProcess();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetActiveWindow();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = GetCurrentThreadId();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetCurrentThread();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetDesktopWindow();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetFocus();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetForegroundWindow();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+#ifndef _WIN32_WCE
+	dw = (DWORD)GetInputState();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); 
+#else
+	// Leave the stack data - random :)
+#endif
+	inx += 4;
+
+	dw = GetMessagePos();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+#ifndef _WIN32_WCE
+	dw = (DWORD)GetMessageTime();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4);
+#else
+	// Leave the stack data - random :)
+#endif
+	inx += 4;
+
+	dw = (DWORD)GetOpenClipboardWindow();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	dw = (DWORD)GetProcessHeap();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+	GetSystemInfo(&si);
+	memcpy(&m_pPseudoRandom[inx], &si, sizeof(SYSTEM_INFO));
+	inx += sizeof(SYSTEM_INFO);
+
+	dw = (DWORD)randXorShift();
+	memcpy(&m_pPseudoRandom[inx], &dw, 4); inx += 4;
+
+#ifndef _WIN32_WCE
+	GetStartupInfo(&sui);
+	memcpy(&m_pPseudoRandom[inx], &sui, sizeof(STARTUPINFO));
+#else
+	// Leave the stack data - random :)
+#endif
+	inx += sizeof(STARTUPINFO);
+
+	memcpy(&m_pPseudoRandom[inx], &g_dwNewRandomInstanceCounter, 4);
+	inx += 4;
+
+	ASSERT(inx <= INTRAND_SIZE);
+}
+
+void CNewRandom::GetRandomBuffer(BYTE *pBuf, DWORD dwSize)
+{
+	sha256_ctx hashctx;
+	BYTE aTemp[32];
+	DWORD dw;
+
+	ASSERT(pBuf != NULL);
+
+	while(dwSize != 0)
+	{
+		m_dwCounter++;
+		sha256_begin(&hashctx);
+		sha256_hash(m_pPseudoRandom, INTRAND_SIZE, &hashctx);
+		sha256_hash((BYTE *)&m_dwCounter, 4, &hashctx);
+		sha256_end(aTemp, &hashctx);
+
+		dw = (dwSize < 32) ? dwSize : 32;
+		memcpy(pBuf, aTemp, dw);
+		pBuf += dw;
+		dwSize -= dw;
+	}
+}
+
+// Seed the xorshift random number generator
+void srandXorShift(unsigned long *pSeed128)
+{
+	ASSERT(pSeed128 != NULL); // No NULL parameter allowed
+
+	if((g_xorW == 0) && (g_xorX == 0) && (g_xorY == 0) && (g_xorZ == 0))
+	{
+		g_xorW = pSeed128[0];
+		g_xorX = pSeed128[1];
+		g_xorY = pSeed128[2];
+		g_xorZ = pSeed128[3];
+
+		if((g_xorW + g_xorX + g_xorY + g_xorZ) == 0) g_xorX += 0xB7E15163;
+	}
+}
+
+// Fast XorShift random number generator
+unsigned long randXorShift()
+{
+	unsigned long tmp;
+
+	tmp = (g_xorX ^ (g_xorX << 15));
+	g_xorX = g_xorY; g_xorY = g_xorZ; g_xorZ = g_xorW;
+	g_xorW = (g_xorW ^ (g_xorW >> 21)) ^ (tmp ^ (tmp >> 4));
+
+	return g_xorW;
+}
+
+void randCreateUUID(BYTE *pUUID16, CNewRandom *pRandomSource)
+{
+	SYSTEMTIME st;
+	BYTE *p = pUUID16;
+	DWORD *pdw1 = (DWORD *)pUUID16, *pdw2 = (DWORD *)&pUUID16[4],
+		*pdw3 = (DWORD *)&pUUID16[8], *pdw4 = (DWORD *)&pUUID16[12];
+
+	ASSERT(pRandomSource != NULL);
+
+	ASSERT((sizeof(DWORD) == 4) && (sizeof(USHORT) == 2) && (pUUID16 != NULL));
+	if(pUUID16 == NULL) return;
+
+	ZeroMemory(&st, sizeof(SYSTEMTIME));
+	GetSystemTime(&st);
+
+	_PackTimeToStruct(p, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+	p += 5; // +5 => 5 bytes filled
+	*p = (BYTE)((st.wMilliseconds >> 2) & 0xFF); // Store milliseconds
+	p++; // +1 => 6 bytes filled
+
+	// Use the xorshift random number generator as pseudo-counter
+	DWORD dwPseudoCounter = randXorShift();
+	memcpy(p, &dwPseudoCounter, 2); // Use only 2/4 bytes
+	p += 2; // +2 => 8 bytes filled
+
+	pRandomSource->GetRandomBuffer(p, 8); // +8 => 16 bytes filled
+
+	// Mix buffer for better read- and processability using PHTs
+	*pdw1 += *pdw2; *pdw2 += *pdw1; *pdw3 += *pdw4; *pdw4 += *pdw3;
+	*pdw2 += *pdw3; *pdw3 += *pdw2; *pdw1 += *pdw4; *pdw4 += *pdw1;
+	*pdw1 += *pdw3; *pdw3 += *pdw1; *pdw2 += *pdw4; *pdw4 += *pdw2;
+	*pdw1 += *pdw2; *pdw2 += *pdw1; *pdw3 += *pdw4; *pdw4 += *pdw3;
+	*pdw2 += *pdw3; *pdw3 += *pdw2; *pdw1 += *pdw4; *pdw4 += *pdw1;
+	*pdw1 += *pdw3; *pdw3 += *pdw1; *pdw2 += *pdw4; *pdw4 += *pdw2;
+}

+ 71 - 0
EncryptDecrypt/NewRandom.h

@@ -0,0 +1,71 @@
+/*
+  Copyright (c) 2003/2004, Dominik Reichl <[email protected]>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer. 
+  - Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  - Neither the name of ReichlSoft nor the names of its contributors may be
+    used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ___NEW_RANDOM_H___
+#define ___NEW_RANDOM_H___
+
+#include <windows.h>
+#include <stdlib.h>
+#include "sha2.h"
+
+#define INTRAND_SIZE 264
+
+class CNewRandom
+{
+public:
+	CNewRandom();
+	virtual ~CNewRandom();
+
+	void Reset();
+	void Initialize();
+
+	void GetRandomBuffer(BYTE *pBuf, DWORD dwSize);
+
+private:
+	BYTE m_pPseudoRandom[INTRAND_SIZE];
+	DWORD m_dwCounter;
+};
+
+class CNewRandomInterface
+{
+public:
+	virtual ~CNewRandomInterface() { }
+
+	virtual BOOL GenerateRandomSequence(unsigned long uRandomSeqSize, unsigned char *pBuffer) const = 0;
+};
+
+// Seed is 128 bits = 4 32-bit DWORDS
+void srandXorShift(unsigned long *pSeed128);
+
+unsigned long randXorShift();
+
+// Must be able to hold at least 16 bytes
+void randCreateUUID(BYTE *pUUID16, CNewRandom *pRandomSource);
+
+#endif

+ 33 - 0
EncryptDecrypt/Readme.txt

@@ -0,0 +1,33 @@
+========================================================================
+       STATIC LIBRARY : EncryptDecrypt
+========================================================================
+
+
+AppWizard has created this EncryptDecrypt library for you.  
+
+This file contains a summary of what you will find in each of the files that
+make up your EncryptDecrypt application.
+
+/////////////////////////////////////////////////////////////////////////////
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named EncryptDecrypt.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+The compiler and linker switches have been modified to support MFC. Using the
+MFC ClassWizard with this project requires that you add several files to the 
+project, including "resource.h", "EncryptDecrypt.rc" and a "EncryptDecrypt.h" that 
+includes resource.h. If you add an rc file to a static library, you may 
+experience difficulties due to the limitation that only one rc file may be 
+present in a Dll or Exe. This problem may be overcome by including the 
+library's .rc file into the parent project's .rc file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+
+/////////////////////////////////////////////////////////////////////////////

+ 6 - 0
EncryptDecrypt/StdAfx.cpp

@@ -0,0 +1,6 @@
+// stdafx.cpp : source file that includes just the standard includes
+//	EncryptDecrypt.pch will be the pre-compiled header
+//	stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+

+ 23 - 0
EncryptDecrypt/StdAfx.h

@@ -0,0 +1,23 @@
+// stdafx.h : include file for standard system include files,
+//  or project specific include files that are used frequently, but
+//      are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__49D78360_AC70_4F25_AF8A_3CDB3BA0CC86__INCLUDED_)
+#define AFX_STDAFX_H__49D78360_AC70_4F25_AF8A_3CDB3BA0CC86__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+
+#include <afx.h>
+#include <afxwin.h>
+
+// TODO: reference additional headers your program requires here
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__49D78360_AC70_4F25_AF8A_3CDB3BA0CC86__INCLUDED_)

+ 1610 - 0
EncryptDecrypt/rijndael.cpp

@@ -0,0 +1,1610 @@
+// Slightly modified version of Szymon Stefanek's implementation of
+// the Rijndael block cipher.
+
+//
+// File : rijndael.cpp
+// Creation date : Sun Nov 5 2000 03:22:10 CEST
+// Author : Szymon Stefanek ([email protected])
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// This code is public domain.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+//    rijndael-alg-fst.c   v2.4   April '2000
+//    rijndael-alg-fst.h
+//    rijndael-api-fst.c
+//    rijndael-api-fst.h
+//
+//    Optimised ANSI C code
+//
+//    authors: v1.0: Antoon Bosselaers
+//             v2.0: Vincent Rijmen, K.U.Leuven
+//             v2.3: Paulo Barreto
+//             v2.4: Vincent Rijmen, K.U.Leuven
+//
+//    This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+// Added by Dominik Reichl to compile with MFC
+#include "StdAfx.h"
+
+#define _RIJNDAEL_CPP_
+
+#include "rijndael.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static RD_UINT8 S[256]=
+{
+	 99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118,
+	202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
+	183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21,
+	  4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117,
+	  9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132,
+	 83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207,
+	208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
+	 81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210,
+	205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115,
+	 96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219,
+	224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121,
+	231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8,
+	186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138,
+	112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
+	225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
+	140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22
+};
+
+
+static RD_UINT8 T1[256][4]=
+{
+	0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84, 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d,
+	0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd, 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54,
+	0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03, 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d,
+	0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62, 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a,
+	0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d, 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87,
+	0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb, 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b,
+	0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67, 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea,
+	0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7, 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b,
+	0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c, 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a,
+	0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41, 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f,
+	0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4, 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08,
+	0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73, 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f,
+	0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52, 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e,
+	0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1, 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5,
+	0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36, 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d,
+	0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69, 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f,
+	0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e, 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e,
+	0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2, 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb,
+	0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d, 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce,
+	0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e, 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97,
+	0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68, 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c,
+	0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f, 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed,
+	0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46, 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b,
+	0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4, 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a,
+	0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a, 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16,
+	0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7, 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94,
+	0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10, 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81,
+	0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44, 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3,
+	0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe, 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a,
+	0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc, 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04,
+	0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1, 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63,
+	0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a, 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d,
+	0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14, 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f,
+	0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2, 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39,
+	0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2, 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47,
+	0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7, 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95,
+	0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98, 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f,
+	0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e, 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83,
+	0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29, 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c,
+	0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2, 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76,
+	0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56, 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e,
+	0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a, 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4,
+	0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e, 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6,
+	0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4, 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b,
+	0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43, 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7,
+	0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64, 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0,
+	0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa, 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25,
+	0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e, 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18,
+	0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88, 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72,
+	0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1, 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51,
+	0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c, 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21,
+	0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc, 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85,
+	0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42, 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa,
+	0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05, 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12,
+	0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f, 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0,
+	0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58, 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9,
+	0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13, 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33,
+	0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70, 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7,
+	0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22, 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20,
+	0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff, 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a,
+	0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8, 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17,
+	0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31, 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8,
+	0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0, 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11,
+	0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc, 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a
+};
+
+static RD_UINT8 T2[256][4]=
+{
+	0xa5,0xc6,0x63,0x63, 0x84,0xf8,0x7c,0x7c, 0x99,0xee,0x77,0x77, 0x8d,0xf6,0x7b,0x7b,
+	0x0d,0xff,0xf2,0xf2, 0xbd,0xd6,0x6b,0x6b, 0xb1,0xde,0x6f,0x6f, 0x54,0x91,0xc5,0xc5,
+	0x50,0x60,0x30,0x30, 0x03,0x02,0x01,0x01, 0xa9,0xce,0x67,0x67, 0x7d,0x56,0x2b,0x2b,
+	0x19,0xe7,0xfe,0xfe, 0x62,0xb5,0xd7,0xd7, 0xe6,0x4d,0xab,0xab, 0x9a,0xec,0x76,0x76,
+	0x45,0x8f,0xca,0xca, 0x9d,0x1f,0x82,0x82, 0x40,0x89,0xc9,0xc9, 0x87,0xfa,0x7d,0x7d,
+	0x15,0xef,0xfa,0xfa, 0xeb,0xb2,0x59,0x59, 0xc9,0x8e,0x47,0x47, 0x0b,0xfb,0xf0,0xf0,
+	0xec,0x41,0xad,0xad, 0x67,0xb3,0xd4,0xd4, 0xfd,0x5f,0xa2,0xa2, 0xea,0x45,0xaf,0xaf,
+	0xbf,0x23,0x9c,0x9c, 0xf7,0x53,0xa4,0xa4, 0x96,0xe4,0x72,0x72, 0x5b,0x9b,0xc0,0xc0,
+	0xc2,0x75,0xb7,0xb7, 0x1c,0xe1,0xfd,0xfd, 0xae,0x3d,0x93,0x93, 0x6a,0x4c,0x26,0x26,
+	0x5a,0x6c,0x36,0x36, 0x41,0x7e,0x3f,0x3f, 0x02,0xf5,0xf7,0xf7, 0x4f,0x83,0xcc,0xcc,
+	0x5c,0x68,0x34,0x34, 0xf4,0x51,0xa5,0xa5, 0x34,0xd1,0xe5,0xe5, 0x08,0xf9,0xf1,0xf1,
+	0x93,0xe2,0x71,0x71, 0x73,0xab,0xd8,0xd8, 0x53,0x62,0x31,0x31, 0x3f,0x2a,0x15,0x15,
+	0x0c,0x08,0x04,0x04, 0x52,0x95,0xc7,0xc7, 0x65,0x46,0x23,0x23, 0x5e,0x9d,0xc3,0xc3,
+	0x28,0x30,0x18,0x18, 0xa1,0x37,0x96,0x96, 0x0f,0x0a,0x05,0x05, 0xb5,0x2f,0x9a,0x9a,
+	0x09,0x0e,0x07,0x07, 0x36,0x24,0x12,0x12, 0x9b,0x1b,0x80,0x80, 0x3d,0xdf,0xe2,0xe2,
+	0x26,0xcd,0xeb,0xeb, 0x69,0x4e,0x27,0x27, 0xcd,0x7f,0xb2,0xb2, 0x9f,0xea,0x75,0x75,
+	0x1b,0x12,0x09,0x09, 0x9e,0x1d,0x83,0x83, 0x74,0x58,0x2c,0x2c, 0x2e,0x34,0x1a,0x1a,
+	0x2d,0x36,0x1b,0x1b, 0xb2,0xdc,0x6e,0x6e, 0xee,0xb4,0x5a,0x5a, 0xfb,0x5b,0xa0,0xa0,
+	0xf6,0xa4,0x52,0x52, 0x4d,0x76,0x3b,0x3b, 0x61,0xb7,0xd6,0xd6, 0xce,0x7d,0xb3,0xb3,
+	0x7b,0x52,0x29,0x29, 0x3e,0xdd,0xe3,0xe3, 0x71,0x5e,0x2f,0x2f, 0x97,0x13,0x84,0x84,
+	0xf5,0xa6,0x53,0x53, 0x68,0xb9,0xd1,0xd1, 0x00,0x00,0x00,0x00, 0x2c,0xc1,0xed,0xed,
+	0x60,0x40,0x20,0x20, 0x1f,0xe3,0xfc,0xfc, 0xc8,0x79,0xb1,0xb1, 0xed,0xb6,0x5b,0x5b,
+	0xbe,0xd4,0x6a,0x6a, 0x46,0x8d,0xcb,0xcb, 0xd9,0x67,0xbe,0xbe, 0x4b,0x72,0x39,0x39,
+	0xde,0x94,0x4a,0x4a, 0xd4,0x98,0x4c,0x4c, 0xe8,0xb0,0x58,0x58, 0x4a,0x85,0xcf,0xcf,
+	0x6b,0xbb,0xd0,0xd0, 0x2a,0xc5,0xef,0xef, 0xe5,0x4f,0xaa,0xaa, 0x16,0xed,0xfb,0xfb,
+	0xc5,0x86,0x43,0x43, 0xd7,0x9a,0x4d,0x4d, 0x55,0x66,0x33,0x33, 0x94,0x11,0x85,0x85,
+	0xcf,0x8a,0x45,0x45, 0x10,0xe9,0xf9,0xf9, 0x06,0x04,0x02,0x02, 0x81,0xfe,0x7f,0x7f,
+	0xf0,0xa0,0x50,0x50, 0x44,0x78,0x3c,0x3c, 0xba,0x25,0x9f,0x9f, 0xe3,0x4b,0xa8,0xa8,
+	0xf3,0xa2,0x51,0x51, 0xfe,0x5d,0xa3,0xa3, 0xc0,0x80,0x40,0x40, 0x8a,0x05,0x8f,0x8f,
+	0xad,0x3f,0x92,0x92, 0xbc,0x21,0x9d,0x9d, 0x48,0x70,0x38,0x38, 0x04,0xf1,0xf5,0xf5,
+	0xdf,0x63,0xbc,0xbc, 0xc1,0x77,0xb6,0xb6, 0x75,0xaf,0xda,0xda, 0x63,0x42,0x21,0x21,
+	0x30,0x20,0x10,0x10, 0x1a,0xe5,0xff,0xff, 0x0e,0xfd,0xf3,0xf3, 0x6d,0xbf,0xd2,0xd2,
+	0x4c,0x81,0xcd,0xcd, 0x14,0x18,0x0c,0x0c, 0x35,0x26,0x13,0x13, 0x2f,0xc3,0xec,0xec,
+	0xe1,0xbe,0x5f,0x5f, 0xa2,0x35,0x97,0x97, 0xcc,0x88,0x44,0x44, 0x39,0x2e,0x17,0x17,
+	0x57,0x93,0xc4,0xc4, 0xf2,0x55,0xa7,0xa7, 0x82,0xfc,0x7e,0x7e, 0x47,0x7a,0x3d,0x3d,
+	0xac,0xc8,0x64,0x64, 0xe7,0xba,0x5d,0x5d, 0x2b,0x32,0x19,0x19, 0x95,0xe6,0x73,0x73,
+	0xa0,0xc0,0x60,0x60, 0x98,0x19,0x81,0x81, 0xd1,0x9e,0x4f,0x4f, 0x7f,0xa3,0xdc,0xdc,
+	0x66,0x44,0x22,0x22, 0x7e,0x54,0x2a,0x2a, 0xab,0x3b,0x90,0x90, 0x83,0x0b,0x88,0x88,
+	0xca,0x8c,0x46,0x46, 0x29,0xc7,0xee,0xee, 0xd3,0x6b,0xb8,0xb8, 0x3c,0x28,0x14,0x14,
+	0x79,0xa7,0xde,0xde, 0xe2,0xbc,0x5e,0x5e, 0x1d,0x16,0x0b,0x0b, 0x76,0xad,0xdb,0xdb,
+	0x3b,0xdb,0xe0,0xe0, 0x56,0x64,0x32,0x32, 0x4e,0x74,0x3a,0x3a, 0x1e,0x14,0x0a,0x0a,
+	0xdb,0x92,0x49,0x49, 0x0a,0x0c,0x06,0x06, 0x6c,0x48,0x24,0x24, 0xe4,0xb8,0x5c,0x5c,
+	0x5d,0x9f,0xc2,0xc2, 0x6e,0xbd,0xd3,0xd3, 0xef,0x43,0xac,0xac, 0xa6,0xc4,0x62,0x62,
+	0xa8,0x39,0x91,0x91, 0xa4,0x31,0x95,0x95, 0x37,0xd3,0xe4,0xe4, 0x8b,0xf2,0x79,0x79,
+	0x32,0xd5,0xe7,0xe7, 0x43,0x8b,0xc8,0xc8, 0x59,0x6e,0x37,0x37, 0xb7,0xda,0x6d,0x6d,
+	0x8c,0x01,0x8d,0x8d, 0x64,0xb1,0xd5,0xd5, 0xd2,0x9c,0x4e,0x4e, 0xe0,0x49,0xa9,0xa9,
+	0xb4,0xd8,0x6c,0x6c, 0xfa,0xac,0x56,0x56, 0x07,0xf3,0xf4,0xf4, 0x25,0xcf,0xea,0xea,
+	0xaf,0xca,0x65,0x65, 0x8e,0xf4,0x7a,0x7a, 0xe9,0x47,0xae,0xae, 0x18,0x10,0x08,0x08,
+	0xd5,0x6f,0xba,0xba, 0x88,0xf0,0x78,0x78, 0x6f,0x4a,0x25,0x25, 0x72,0x5c,0x2e,0x2e,
+	0x24,0x38,0x1c,0x1c, 0xf1,0x57,0xa6,0xa6, 0xc7,0x73,0xb4,0xb4, 0x51,0x97,0xc6,0xc6,
+	0x23,0xcb,0xe8,0xe8, 0x7c,0xa1,0xdd,0xdd, 0x9c,0xe8,0x74,0x74, 0x21,0x3e,0x1f,0x1f,
+	0xdd,0x96,0x4b,0x4b, 0xdc,0x61,0xbd,0xbd, 0x86,0x0d,0x8b,0x8b, 0x85,0x0f,0x8a,0x8a,
+	0x90,0xe0,0x70,0x70, 0x42,0x7c,0x3e,0x3e, 0xc4,0x71,0xb5,0xb5, 0xaa,0xcc,0x66,0x66,
+	0xd8,0x90,0x48,0x48, 0x05,0x06,0x03,0x03, 0x01,0xf7,0xf6,0xf6, 0x12,0x1c,0x0e,0x0e,
+	0xa3,0xc2,0x61,0x61, 0x5f,0x6a,0x35,0x35, 0xf9,0xae,0x57,0x57, 0xd0,0x69,0xb9,0xb9,
+	0x91,0x17,0x86,0x86, 0x58,0x99,0xc1,0xc1, 0x27,0x3a,0x1d,0x1d, 0xb9,0x27,0x9e,0x9e,
+	0x38,0xd9,0xe1,0xe1, 0x13,0xeb,0xf8,0xf8, 0xb3,0x2b,0x98,0x98, 0x33,0x22,0x11,0x11,
+	0xbb,0xd2,0x69,0x69, 0x70,0xa9,0xd9,0xd9, 0x89,0x07,0x8e,0x8e, 0xa7,0x33,0x94,0x94,
+	0xb6,0x2d,0x9b,0x9b, 0x22,0x3c,0x1e,0x1e, 0x92,0x15,0x87,0x87, 0x20,0xc9,0xe9,0xe9,
+	0x49,0x87,0xce,0xce, 0xff,0xaa,0x55,0x55, 0x78,0x50,0x28,0x28, 0x7a,0xa5,0xdf,0xdf,
+	0x8f,0x03,0x8c,0x8c, 0xf8,0x59,0xa1,0xa1, 0x80,0x09,0x89,0x89, 0x17,0x1a,0x0d,0x0d,
+	0xda,0x65,0xbf,0xbf, 0x31,0xd7,0xe6,0xe6, 0xc6,0x84,0x42,0x42, 0xb8,0xd0,0x68,0x68,
+	0xc3,0x82,0x41,0x41, 0xb0,0x29,0x99,0x99, 0x77,0x5a,0x2d,0x2d, 0x11,0x1e,0x0f,0x0f,
+	0xcb,0x7b,0xb0,0xb0, 0xfc,0xa8,0x54,0x54, 0xd6,0x6d,0xbb,0xbb, 0x3a,0x2c,0x16,0x16
+};
+
+static RD_UINT8 T3[256][4]=
+{
+	0x63,0xa5,0xc6,0x63, 0x7c,0x84,0xf8,0x7c, 0x77,0x99,0xee,0x77, 0x7b,0x8d,0xf6,0x7b,
+	0xf2,0x0d,0xff,0xf2, 0x6b,0xbd,0xd6,0x6b, 0x6f,0xb1,0xde,0x6f, 0xc5,0x54,0x91,0xc5,
+	0x30,0x50,0x60,0x30, 0x01,0x03,0x02,0x01, 0x67,0xa9,0xce,0x67, 0x2b,0x7d,0x56,0x2b,
+	0xfe,0x19,0xe7,0xfe, 0xd7,0x62,0xb5,0xd7, 0xab,0xe6,0x4d,0xab, 0x76,0x9a,0xec,0x76,
+	0xca,0x45,0x8f,0xca, 0x82,0x9d,0x1f,0x82, 0xc9,0x40,0x89,0xc9, 0x7d,0x87,0xfa,0x7d,
+	0xfa,0x15,0xef,0xfa, 0x59,0xeb,0xb2,0x59, 0x47,0xc9,0x8e,0x47, 0xf0,0x0b,0xfb,0xf0,
+	0xad,0xec,0x41,0xad, 0xd4,0x67,0xb3,0xd4, 0xa2,0xfd,0x5f,0xa2, 0xaf,0xea,0x45,0xaf,
+	0x9c,0xbf,0x23,0x9c, 0xa4,0xf7,0x53,0xa4, 0x72,0x96,0xe4,0x72, 0xc0,0x5b,0x9b,0xc0,
+	0xb7,0xc2,0x75,0xb7, 0xfd,0x1c,0xe1,0xfd, 0x93,0xae,0x3d,0x93, 0x26,0x6a,0x4c,0x26,
+	0x36,0x5a,0x6c,0x36, 0x3f,0x41,0x7e,0x3f, 0xf7,0x02,0xf5,0xf7, 0xcc,0x4f,0x83,0xcc,
+	0x34,0x5c,0x68,0x34, 0xa5,0xf4,0x51,0xa5, 0xe5,0x34,0xd1,0xe5, 0xf1,0x08,0xf9,0xf1,
+	0x71,0x93,0xe2,0x71, 0xd8,0x73,0xab,0xd8, 0x31,0x53,0x62,0x31, 0x15,0x3f,0x2a,0x15,
+	0x04,0x0c,0x08,0x04, 0xc7,0x52,0x95,0xc7, 0x23,0x65,0x46,0x23, 0xc3,0x5e,0x9d,0xc3,
+	0x18,0x28,0x30,0x18, 0x96,0xa1,0x37,0x96, 0x05,0x0f,0x0a,0x05, 0x9a,0xb5,0x2f,0x9a,
+	0x07,0x09,0x0e,0x07, 0x12,0x36,0x24,0x12, 0x80,0x9b,0x1b,0x80, 0xe2,0x3d,0xdf,0xe2,
+	0xeb,0x26,0xcd,0xeb, 0x27,0x69,0x4e,0x27, 0xb2,0xcd,0x7f,0xb2, 0x75,0x9f,0xea,0x75,
+	0x09,0x1b,0x12,0x09, 0x83,0x9e,0x1d,0x83, 0x2c,0x74,0x58,0x2c, 0x1a,0x2e,0x34,0x1a,
+	0x1b,0x2d,0x36,0x1b, 0x6e,0xb2,0xdc,0x6e, 0x5a,0xee,0xb4,0x5a, 0xa0,0xfb,0x5b,0xa0,
+	0x52,0xf6,0xa4,0x52, 0x3b,0x4d,0x76,0x3b, 0xd6,0x61,0xb7,0xd6, 0xb3,0xce,0x7d,0xb3,
+	0x29,0x7b,0x52,0x29, 0xe3,0x3e,0xdd,0xe3, 0x2f,0x71,0x5e,0x2f, 0x84,0x97,0x13,0x84,
+	0x53,0xf5,0xa6,0x53, 0xd1,0x68,0xb9,0xd1, 0x00,0x00,0x00,0x00, 0xed,0x2c,0xc1,0xed,
+	0x20,0x60,0x40,0x20, 0xfc,0x1f,0xe3,0xfc, 0xb1,0xc8,0x79,0xb1, 0x5b,0xed,0xb6,0x5b,
+	0x6a,0xbe,0xd4,0x6a, 0xcb,0x46,0x8d,0xcb, 0xbe,0xd9,0x67,0xbe, 0x39,0x4b,0x72,0x39,
+	0x4a,0xde,0x94,0x4a, 0x4c,0xd4,0x98,0x4c, 0x58,0xe8,0xb0,0x58, 0xcf,0x4a,0x85,0xcf,
+	0xd0,0x6b,0xbb,0xd0, 0xef,0x2a,0xc5,0xef, 0xaa,0xe5,0x4f,0xaa, 0xfb,0x16,0xed,0xfb,
+	0x43,0xc5,0x86,0x43, 0x4d,0xd7,0x9a,0x4d, 0x33,0x55,0x66,0x33, 0x85,0x94,0x11,0x85,
+	0x45,0xcf,0x8a,0x45, 0xf9,0x10,0xe9,0xf9, 0x02,0x06,0x04,0x02, 0x7f,0x81,0xfe,0x7f,
+	0x50,0xf0,0xa0,0x50, 0x3c,0x44,0x78,0x3c, 0x9f,0xba,0x25,0x9f, 0xa8,0xe3,0x4b,0xa8,
+	0x51,0xf3,0xa2,0x51, 0xa3,0xfe,0x5d,0xa3, 0x40,0xc0,0x80,0x40, 0x8f,0x8a,0x05,0x8f,
+	0x92,0xad,0x3f,0x92, 0x9d,0xbc,0x21,0x9d, 0x38,0x48,0x70,0x38, 0xf5,0x04,0xf1,0xf5,
+	0xbc,0xdf,0x63,0xbc, 0xb6,0xc1,0x77,0xb6, 0xda,0x75,0xaf,0xda, 0x21,0x63,0x42,0x21,
+	0x10,0x30,0x20,0x10, 0xff,0x1a,0xe5,0xff, 0xf3,0x0e,0xfd,0xf3, 0xd2,0x6d,0xbf,0xd2,
+	0xcd,0x4c,0x81,0xcd, 0x0c,0x14,0x18,0x0c, 0x13,0x35,0x26,0x13, 0xec,0x2f,0xc3,0xec,
+	0x5f,0xe1,0xbe,0x5f, 0x97,0xa2,0x35,0x97, 0x44,0xcc,0x88,0x44, 0x17,0x39,0x2e,0x17,
+	0xc4,0x57,0x93,0xc4, 0xa7,0xf2,0x55,0xa7, 0x7e,0x82,0xfc,0x7e, 0x3d,0x47,0x7a,0x3d,
+	0x64,0xac,0xc8,0x64, 0x5d,0xe7,0xba,0x5d, 0x19,0x2b,0x32,0x19, 0x73,0x95,0xe6,0x73,
+	0x60,0xa0,0xc0,0x60, 0x81,0x98,0x19,0x81, 0x4f,0xd1,0x9e,0x4f, 0xdc,0x7f,0xa3,0xdc,
+	0x22,0x66,0x44,0x22, 0x2a,0x7e,0x54,0x2a, 0x90,0xab,0x3b,0x90, 0x88,0x83,0x0b,0x88,
+	0x46,0xca,0x8c,0x46, 0xee,0x29,0xc7,0xee, 0xb8,0xd3,0x6b,0xb8, 0x14,0x3c,0x28,0x14,
+	0xde,0x79,0xa7,0xde, 0x5e,0xe2,0xbc,0x5e, 0x0b,0x1d,0x16,0x0b, 0xdb,0x76,0xad,0xdb,
+	0xe0,0x3b,0xdb,0xe0, 0x32,0x56,0x64,0x32, 0x3a,0x4e,0x74,0x3a, 0x0a,0x1e,0x14,0x0a,
+	0x49,0xdb,0x92,0x49, 0x06,0x0a,0x0c,0x06, 0x24,0x6c,0x48,0x24, 0x5c,0xe4,0xb8,0x5c,
+	0xc2,0x5d,0x9f,0xc2, 0xd3,0x6e,0xbd,0xd3, 0xac,0xef,0x43,0xac, 0x62,0xa6,0xc4,0x62,
+	0x91,0xa8,0x39,0x91, 0x95,0xa4,0x31,0x95, 0xe4,0x37,0xd3,0xe4, 0x79,0x8b,0xf2,0x79,
+	0xe7,0x32,0xd5,0xe7, 0xc8,0x43,0x8b,0xc8, 0x37,0x59,0x6e,0x37, 0x6d,0xb7,0xda,0x6d,
+	0x8d,0x8c,0x01,0x8d, 0xd5,0x64,0xb1,0xd5, 0x4e,0xd2,0x9c,0x4e, 0xa9,0xe0,0x49,0xa9,
+	0x6c,0xb4,0xd8,0x6c, 0x56,0xfa,0xac,0x56, 0xf4,0x07,0xf3,0xf4, 0xea,0x25,0xcf,0xea,
+	0x65,0xaf,0xca,0x65, 0x7a,0x8e,0xf4,0x7a, 0xae,0xe9,0x47,0xae, 0x08,0x18,0x10,0x08,
+	0xba,0xd5,0x6f,0xba, 0x78,0x88,0xf0,0x78, 0x25,0x6f,0x4a,0x25, 0x2e,0x72,0x5c,0x2e,
+	0x1c,0x24,0x38,0x1c, 0xa6,0xf1,0x57,0xa6, 0xb4,0xc7,0x73,0xb4, 0xc6,0x51,0x97,0xc6,
+	0xe8,0x23,0xcb,0xe8, 0xdd,0x7c,0xa1,0xdd, 0x74,0x9c,0xe8,0x74, 0x1f,0x21,0x3e,0x1f,
+	0x4b,0xdd,0x96,0x4b, 0xbd,0xdc,0x61,0xbd, 0x8b,0x86,0x0d,0x8b, 0x8a,0x85,0x0f,0x8a,
+	0x70,0x90,0xe0,0x70, 0x3e,0x42,0x7c,0x3e, 0xb5,0xc4,0x71,0xb5, 0x66,0xaa,0xcc,0x66,
+	0x48,0xd8,0x90,0x48, 0x03,0x05,0x06,0x03, 0xf6,0x01,0xf7,0xf6, 0x0e,0x12,0x1c,0x0e,
+	0x61,0xa3,0xc2,0x61, 0x35,0x5f,0x6a,0x35, 0x57,0xf9,0xae,0x57, 0xb9,0xd0,0x69,0xb9,
+	0x86,0x91,0x17,0x86, 0xc1,0x58,0x99,0xc1, 0x1d,0x27,0x3a,0x1d, 0x9e,0xb9,0x27,0x9e,
+	0xe1,0x38,0xd9,0xe1, 0xf8,0x13,0xeb,0xf8, 0x98,0xb3,0x2b,0x98, 0x11,0x33,0x22,0x11,
+	0x69,0xbb,0xd2,0x69, 0xd9,0x70,0xa9,0xd9, 0x8e,0x89,0x07,0x8e, 0x94,0xa7,0x33,0x94,
+	0x9b,0xb6,0x2d,0x9b, 0x1e,0x22,0x3c,0x1e, 0x87,0x92,0x15,0x87, 0xe9,0x20,0xc9,0xe9,
+	0xce,0x49,0x87,0xce, 0x55,0xff,0xaa,0x55, 0x28,0x78,0x50,0x28, 0xdf,0x7a,0xa5,0xdf,
+	0x8c,0x8f,0x03,0x8c, 0xa1,0xf8,0x59,0xa1, 0x89,0x80,0x09,0x89, 0x0d,0x17,0x1a,0x0d,
+	0xbf,0xda,0x65,0xbf, 0xe6,0x31,0xd7,0xe6, 0x42,0xc6,0x84,0x42, 0x68,0xb8,0xd0,0x68,
+	0x41,0xc3,0x82,0x41, 0x99,0xb0,0x29,0x99, 0x2d,0x77,0x5a,0x2d, 0x0f,0x11,0x1e,0x0f,
+	0xb0,0xcb,0x7b,0xb0, 0x54,0xfc,0xa8,0x54, 0xbb,0xd6,0x6d,0xbb, 0x16,0x3a,0x2c,0x16
+};
+
+static RD_UINT8 T4[256][4]=
+{
+	0x63,0x63,0xa5,0xc6, 0x7c,0x7c,0x84,0xf8, 0x77,0x77,0x99,0xee, 0x7b,0x7b,0x8d,0xf6,
+	0xf2,0xf2,0x0d,0xff, 0x6b,0x6b,0xbd,0xd6, 0x6f,0x6f,0xb1,0xde, 0xc5,0xc5,0x54,0x91,
+	0x30,0x30,0x50,0x60, 0x01,0x01,0x03,0x02, 0x67,0x67,0xa9,0xce, 0x2b,0x2b,0x7d,0x56,
+	0xfe,0xfe,0x19,0xe7, 0xd7,0xd7,0x62,0xb5, 0xab,0xab,0xe6,0x4d, 0x76,0x76,0x9a,0xec,
+	0xca,0xca,0x45,0x8f, 0x82,0x82,0x9d,0x1f, 0xc9,0xc9,0x40,0x89, 0x7d,0x7d,0x87,0xfa,
+	0xfa,0xfa,0x15,0xef, 0x59,0x59,0xeb,0xb2, 0x47,0x47,0xc9,0x8e, 0xf0,0xf0,0x0b,0xfb,
+	0xad,0xad,0xec,0x41, 0xd4,0xd4,0x67,0xb3, 0xa2,0xa2,0xfd,0x5f, 0xaf,0xaf,0xea,0x45,
+	0x9c,0x9c,0xbf,0x23, 0xa4,0xa4,0xf7,0x53, 0x72,0x72,0x96,0xe4, 0xc0,0xc0,0x5b,0x9b,
+	0xb7,0xb7,0xc2,0x75, 0xfd,0xfd,0x1c,0xe1, 0x93,0x93,0xae,0x3d, 0x26,0x26,0x6a,0x4c,
+	0x36,0x36,0x5a,0x6c, 0x3f,0x3f,0x41,0x7e, 0xf7,0xf7,0x02,0xf5, 0xcc,0xcc,0x4f,0x83,
+	0x34,0x34,0x5c,0x68, 0xa5,0xa5,0xf4,0x51, 0xe5,0xe5,0x34,0xd1, 0xf1,0xf1,0x08,0xf9,
+	0x71,0x71,0x93,0xe2, 0xd8,0xd8,0x73,0xab, 0x31,0x31,0x53,0x62, 0x15,0x15,0x3f,0x2a,
+	0x04,0x04,0x0c,0x08, 0xc7,0xc7,0x52,0x95, 0x23,0x23,0x65,0x46, 0xc3,0xc3,0x5e,0x9d,
+	0x18,0x18,0x28,0x30, 0x96,0x96,0xa1,0x37, 0x05,0x05,0x0f,0x0a, 0x9a,0x9a,0xb5,0x2f,
+	0x07,0x07,0x09,0x0e, 0x12,0x12,0x36,0x24, 0x80,0x80,0x9b,0x1b, 0xe2,0xe2,0x3d,0xdf,
+	0xeb,0xeb,0x26,0xcd, 0x27,0x27,0x69,0x4e, 0xb2,0xb2,0xcd,0x7f, 0x75,0x75,0x9f,0xea,
+	0x09,0x09,0x1b,0x12, 0x83,0x83,0x9e,0x1d, 0x2c,0x2c,0x74,0x58, 0x1a,0x1a,0x2e,0x34,
+	0x1b,0x1b,0x2d,0x36, 0x6e,0x6e,0xb2,0xdc, 0x5a,0x5a,0xee,0xb4, 0xa0,0xa0,0xfb,0x5b,
+	0x52,0x52,0xf6,0xa4, 0x3b,0x3b,0x4d,0x76, 0xd6,0xd6,0x61,0xb7, 0xb3,0xb3,0xce,0x7d,
+	0x29,0x29,0x7b,0x52, 0xe3,0xe3,0x3e,0xdd, 0x2f,0x2f,0x71,0x5e, 0x84,0x84,0x97,0x13,
+	0x53,0x53,0xf5,0xa6, 0xd1,0xd1,0x68,0xb9, 0x00,0x00,0x00,0x00, 0xed,0xed,0x2c,0xc1,
+	0x20,0x20,0x60,0x40, 0xfc,0xfc,0x1f,0xe3, 0xb1,0xb1,0xc8,0x79, 0x5b,0x5b,0xed,0xb6,
+	0x6a,0x6a,0xbe,0xd4, 0xcb,0xcb,0x46,0x8d, 0xbe,0xbe,0xd9,0x67, 0x39,0x39,0x4b,0x72,
+	0x4a,0x4a,0xde,0x94, 0x4c,0x4c,0xd4,0x98, 0x58,0x58,0xe8,0xb0, 0xcf,0xcf,0x4a,0x85,
+	0xd0,0xd0,0x6b,0xbb, 0xef,0xef,0x2a,0xc5, 0xaa,0xaa,0xe5,0x4f, 0xfb,0xfb,0x16,0xed,
+	0x43,0x43,0xc5,0x86, 0x4d,0x4d,0xd7,0x9a, 0x33,0x33,0x55,0x66, 0x85,0x85,0x94,0x11,
+	0x45,0x45,0xcf,0x8a, 0xf9,0xf9,0x10,0xe9, 0x02,0x02,0x06,0x04, 0x7f,0x7f,0x81,0xfe,
+	0x50,0x50,0xf0,0xa0, 0x3c,0x3c,0x44,0x78, 0x9f,0x9f,0xba,0x25, 0xa8,0xa8,0xe3,0x4b,
+	0x51,0x51,0xf3,0xa2, 0xa3,0xa3,0xfe,0x5d, 0x40,0x40,0xc0,0x80, 0x8f,0x8f,0x8a,0x05,
+	0x92,0x92,0xad,0x3f, 0x9d,0x9d,0xbc,0x21, 0x38,0x38,0x48,0x70, 0xf5,0xf5,0x04,0xf1,
+	0xbc,0xbc,0xdf,0x63, 0xb6,0xb6,0xc1,0x77, 0xda,0xda,0x75,0xaf, 0x21,0x21,0x63,0x42,
+	0x10,0x10,0x30,0x20, 0xff,0xff,0x1a,0xe5, 0xf3,0xf3,0x0e,0xfd, 0xd2,0xd2,0x6d,0xbf,
+	0xcd,0xcd,0x4c,0x81, 0x0c,0x0c,0x14,0x18, 0x13,0x13,0x35,0x26, 0xec,0xec,0x2f,0xc3,
+	0x5f,0x5f,0xe1,0xbe, 0x97,0x97,0xa2,0x35, 0x44,0x44,0xcc,0x88, 0x17,0x17,0x39,0x2e,
+	0xc4,0xc4,0x57,0x93, 0xa7,0xa7,0xf2,0x55, 0x7e,0x7e,0x82,0xfc, 0x3d,0x3d,0x47,0x7a,
+	0x64,0x64,0xac,0xc8, 0x5d,0x5d,0xe7,0xba, 0x19,0x19,0x2b,0x32, 0x73,0x73,0x95,0xe6,
+	0x60,0x60,0xa0,0xc0, 0x81,0x81,0x98,0x19, 0x4f,0x4f,0xd1,0x9e, 0xdc,0xdc,0x7f,0xa3,
+	0x22,0x22,0x66,0x44, 0x2a,0x2a,0x7e,0x54, 0x90,0x90,0xab,0x3b, 0x88,0x88,0x83,0x0b,
+	0x46,0x46,0xca,0x8c, 0xee,0xee,0x29,0xc7, 0xb8,0xb8,0xd3,0x6b, 0x14,0x14,0x3c,0x28,
+	0xde,0xde,0x79,0xa7, 0x5e,0x5e,0xe2,0xbc, 0x0b,0x0b,0x1d,0x16, 0xdb,0xdb,0x76,0xad,
+	0xe0,0xe0,0x3b,0xdb, 0x32,0x32,0x56,0x64, 0x3a,0x3a,0x4e,0x74, 0x0a,0x0a,0x1e,0x14,
+	0x49,0x49,0xdb,0x92, 0x06,0x06,0x0a,0x0c, 0x24,0x24,0x6c,0x48, 0x5c,0x5c,0xe4,0xb8,
+	0xc2,0xc2,0x5d,0x9f, 0xd3,0xd3,0x6e,0xbd, 0xac,0xac,0xef,0x43, 0x62,0x62,0xa6,0xc4,
+	0x91,0x91,0xa8,0x39, 0x95,0x95,0xa4,0x31, 0xe4,0xe4,0x37,0xd3, 0x79,0x79,0x8b,0xf2,
+	0xe7,0xe7,0x32,0xd5, 0xc8,0xc8,0x43,0x8b, 0x37,0x37,0x59,0x6e, 0x6d,0x6d,0xb7,0xda,
+	0x8d,0x8d,0x8c,0x01, 0xd5,0xd5,0x64,0xb1, 0x4e,0x4e,0xd2,0x9c, 0xa9,0xa9,0xe0,0x49,
+	0x6c,0x6c,0xb4,0xd8, 0x56,0x56,0xfa,0xac, 0xf4,0xf4,0x07,0xf3, 0xea,0xea,0x25,0xcf,
+	0x65,0x65,0xaf,0xca, 0x7a,0x7a,0x8e,0xf4, 0xae,0xae,0xe9,0x47, 0x08,0x08,0x18,0x10,
+	0xba,0xba,0xd5,0x6f, 0x78,0x78,0x88,0xf0, 0x25,0x25,0x6f,0x4a, 0x2e,0x2e,0x72,0x5c,
+	0x1c,0x1c,0x24,0x38, 0xa6,0xa6,0xf1,0x57, 0xb4,0xb4,0xc7,0x73, 0xc6,0xc6,0x51,0x97,
+	0xe8,0xe8,0x23,0xcb, 0xdd,0xdd,0x7c,0xa1, 0x74,0x74,0x9c,0xe8, 0x1f,0x1f,0x21,0x3e,
+	0x4b,0x4b,0xdd,0x96, 0xbd,0xbd,0xdc,0x61, 0x8b,0x8b,0x86,0x0d, 0x8a,0x8a,0x85,0x0f,
+	0x70,0x70,0x90,0xe0, 0x3e,0x3e,0x42,0x7c, 0xb5,0xb5,0xc4,0x71, 0x66,0x66,0xaa,0xcc,
+	0x48,0x48,0xd8,0x90, 0x03,0x03,0x05,0x06, 0xf6,0xf6,0x01,0xf7, 0x0e,0x0e,0x12,0x1c,
+	0x61,0x61,0xa3,0xc2, 0x35,0x35,0x5f,0x6a, 0x57,0x57,0xf9,0xae, 0xb9,0xb9,0xd0,0x69,
+	0x86,0x86,0x91,0x17, 0xc1,0xc1,0x58,0x99, 0x1d,0x1d,0x27,0x3a, 0x9e,0x9e,0xb9,0x27,
+	0xe1,0xe1,0x38,0xd9, 0xf8,0xf8,0x13,0xeb, 0x98,0x98,0xb3,0x2b, 0x11,0x11,0x33,0x22,
+	0x69,0x69,0xbb,0xd2, 0xd9,0xd9,0x70,0xa9, 0x8e,0x8e,0x89,0x07, 0x94,0x94,0xa7,0x33,
+	0x9b,0x9b,0xb6,0x2d, 0x1e,0x1e,0x22,0x3c, 0x87,0x87,0x92,0x15, 0xe9,0xe9,0x20,0xc9,
+	0xce,0xce,0x49,0x87, 0x55,0x55,0xff,0xaa, 0x28,0x28,0x78,0x50, 0xdf,0xdf,0x7a,0xa5,
+	0x8c,0x8c,0x8f,0x03, 0xa1,0xa1,0xf8,0x59, 0x89,0x89,0x80,0x09, 0x0d,0x0d,0x17,0x1a,
+	0xbf,0xbf,0xda,0x65, 0xe6,0xe6,0x31,0xd7, 0x42,0x42,0xc6,0x84, 0x68,0x68,0xb8,0xd0,
+	0x41,0x41,0xc3,0x82, 0x99,0x99,0xb0,0x29, 0x2d,0x2d,0x77,0x5a, 0x0f,0x0f,0x11,0x1e,
+	0xb0,0xb0,0xcb,0x7b, 0x54,0x54,0xfc,0xa8, 0xbb,0xbb,0xd6,0x6d, 0x16,0x16,0x3a,0x2c
+};
+
+static RD_UINT8 T5[256][4]=
+{
+	0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53, 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96,
+	0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1, 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93,
+	0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6, 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25,
+	0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7, 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f,
+	0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67, 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1,
+	0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12, 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6,
+	0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95, 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda,
+	0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3, 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44,
+	0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78, 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd,
+	0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17, 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4,
+	0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82, 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45,
+	0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84, 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94,
+	0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19, 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7,
+	0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2, 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a,
+	0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03, 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5,
+	0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2, 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c,
+	0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92, 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1,
+	0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5, 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a,
+	0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0, 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75,
+	0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa, 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51,
+	0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d, 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46,
+	0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05, 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff,
+	0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97, 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77,
+	0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88, 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb,
+	0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9, 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00,
+	0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48, 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e,
+	0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56, 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27,
+	0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21, 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a,
+	0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f, 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e,
+	0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2, 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16,
+	0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5, 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d,
+	0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad, 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8,
+	0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c, 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd,
+	0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc, 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34,
+	0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc, 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63,
+	0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10, 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20,
+	0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8, 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d,
+	0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3, 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0,
+	0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99, 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22,
+	0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a, 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef,
+	0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1, 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36,
+	0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28, 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4,
+	0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d, 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62,
+	0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8, 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5,
+	0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c, 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3,
+	0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7, 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b,
+	0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4, 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8,
+	0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e, 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6,
+	0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce, 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6,
+	0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31, 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0,
+	0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6, 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15,
+	0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7, 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f,
+	0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d, 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf,
+	0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b, 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f,
+	0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d, 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e,
+	0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52, 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13,
+	0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a, 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89,
+	0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35, 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c,
+	0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f, 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf,
+	0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b, 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86,
+	0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e, 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f,
+	0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c, 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41,
+	0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde, 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90,
+	0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70, 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42
+};
+
+static RD_UINT8 T6[256][4]=
+{
+	0x50,0x51,0xf4,0xa7, 0x53,0x7e,0x41,0x65, 0xc3,0x1a,0x17,0xa4, 0x96,0x3a,0x27,0x5e,
+	0xcb,0x3b,0xab,0x6b, 0xf1,0x1f,0x9d,0x45, 0xab,0xac,0xfa,0x58, 0x93,0x4b,0xe3,0x03,
+	0x55,0x20,0x30,0xfa, 0xf6,0xad,0x76,0x6d, 0x91,0x88,0xcc,0x76, 0x25,0xf5,0x02,0x4c,
+	0xfc,0x4f,0xe5,0xd7, 0xd7,0xc5,0x2a,0xcb, 0x80,0x26,0x35,0x44, 0x8f,0xb5,0x62,0xa3,
+	0x49,0xde,0xb1,0x5a, 0x67,0x25,0xba,0x1b, 0x98,0x45,0xea,0x0e, 0xe1,0x5d,0xfe,0xc0,
+	0x02,0xc3,0x2f,0x75, 0x12,0x81,0x4c,0xf0, 0xa3,0x8d,0x46,0x97, 0xc6,0x6b,0xd3,0xf9,
+	0xe7,0x03,0x8f,0x5f, 0x95,0x15,0x92,0x9c, 0xeb,0xbf,0x6d,0x7a, 0xda,0x95,0x52,0x59,
+	0x2d,0xd4,0xbe,0x83, 0xd3,0x58,0x74,0x21, 0x29,0x49,0xe0,0x69, 0x44,0x8e,0xc9,0xc8,
+	0x6a,0x75,0xc2,0x89, 0x78,0xf4,0x8e,0x79, 0x6b,0x99,0x58,0x3e, 0xdd,0x27,0xb9,0x71,
+	0xb6,0xbe,0xe1,0x4f, 0x17,0xf0,0x88,0xad, 0x66,0xc9,0x20,0xac, 0xb4,0x7d,0xce,0x3a,
+	0x18,0x63,0xdf,0x4a, 0x82,0xe5,0x1a,0x31, 0x60,0x97,0x51,0x33, 0x45,0x62,0x53,0x7f,
+	0xe0,0xb1,0x64,0x77, 0x84,0xbb,0x6b,0xae, 0x1c,0xfe,0x81,0xa0, 0x94,0xf9,0x08,0x2b,
+	0x58,0x70,0x48,0x68, 0x19,0x8f,0x45,0xfd, 0x87,0x94,0xde,0x6c, 0xb7,0x52,0x7b,0xf8,
+	0x23,0xab,0x73,0xd3, 0xe2,0x72,0x4b,0x02, 0x57,0xe3,0x1f,0x8f, 0x2a,0x66,0x55,0xab,
+	0x07,0xb2,0xeb,0x28, 0x03,0x2f,0xb5,0xc2, 0x9a,0x86,0xc5,0x7b, 0xa5,0xd3,0x37,0x08,
+	0xf2,0x30,0x28,0x87, 0xb2,0x23,0xbf,0xa5, 0xba,0x02,0x03,0x6a, 0x5c,0xed,0x16,0x82,
+	0x2b,0x8a,0xcf,0x1c, 0x92,0xa7,0x79,0xb4, 0xf0,0xf3,0x07,0xf2, 0xa1,0x4e,0x69,0xe2,
+	0xcd,0x65,0xda,0xf4, 0xd5,0x06,0x05,0xbe, 0x1f,0xd1,0x34,0x62, 0x8a,0xc4,0xa6,0xfe,
+	0x9d,0x34,0x2e,0x53, 0xa0,0xa2,0xf3,0x55, 0x32,0x05,0x8a,0xe1, 0x75,0xa4,0xf6,0xeb,
+	0x39,0x0b,0x83,0xec, 0xaa,0x40,0x60,0xef, 0x06,0x5e,0x71,0x9f, 0x51,0xbd,0x6e,0x10,
+	0xf9,0x3e,0x21,0x8a, 0x3d,0x96,0xdd,0x06, 0xae,0xdd,0x3e,0x05, 0x46,0x4d,0xe6,0xbd,
+	0xb5,0x91,0x54,0x8d, 0x05,0x71,0xc4,0x5d, 0x6f,0x04,0x06,0xd4, 0xff,0x60,0x50,0x15,
+	0x24,0x19,0x98,0xfb, 0x97,0xd6,0xbd,0xe9, 0xcc,0x89,0x40,0x43, 0x77,0x67,0xd9,0x9e,
+	0xbd,0xb0,0xe8,0x42, 0x88,0x07,0x89,0x8b, 0x38,0xe7,0x19,0x5b, 0xdb,0x79,0xc8,0xee,
+	0x47,0xa1,0x7c,0x0a, 0xe9,0x7c,0x42,0x0f, 0xc9,0xf8,0x84,0x1e, 0x00,0x00,0x00,0x00,
+	0x83,0x09,0x80,0x86, 0x48,0x32,0x2b,0xed, 0xac,0x1e,0x11,0x70, 0x4e,0x6c,0x5a,0x72,
+	0xfb,0xfd,0x0e,0xff, 0x56,0x0f,0x85,0x38, 0x1e,0x3d,0xae,0xd5, 0x27,0x36,0x2d,0x39,
+	0x64,0x0a,0x0f,0xd9, 0x21,0x68,0x5c,0xa6, 0xd1,0x9b,0x5b,0x54, 0x3a,0x24,0x36,0x2e,
+	0xb1,0x0c,0x0a,0x67, 0x0f,0x93,0x57,0xe7, 0xd2,0xb4,0xee,0x96, 0x9e,0x1b,0x9b,0x91,
+	0x4f,0x80,0xc0,0xc5, 0xa2,0x61,0xdc,0x20, 0x69,0x5a,0x77,0x4b, 0x16,0x1c,0x12,0x1a,
+	0x0a,0xe2,0x93,0xba, 0xe5,0xc0,0xa0,0x2a, 0x43,0x3c,0x22,0xe0, 0x1d,0x12,0x1b,0x17,
+	0x0b,0x0e,0x09,0x0d, 0xad,0xf2,0x8b,0xc7, 0xb9,0x2d,0xb6,0xa8, 0xc8,0x14,0x1e,0xa9,
+	0x85,0x57,0xf1,0x19, 0x4c,0xaf,0x75,0x07, 0xbb,0xee,0x99,0xdd, 0xfd,0xa3,0x7f,0x60,
+	0x9f,0xf7,0x01,0x26, 0xbc,0x5c,0x72,0xf5, 0xc5,0x44,0x66,0x3b, 0x34,0x5b,0xfb,0x7e,
+	0x76,0x8b,0x43,0x29, 0xdc,0xcb,0x23,0xc6, 0x68,0xb6,0xed,0xfc, 0x63,0xb8,0xe4,0xf1,
+	0xca,0xd7,0x31,0xdc, 0x10,0x42,0x63,0x85, 0x40,0x13,0x97,0x22, 0x20,0x84,0xc6,0x11,
+	0x7d,0x85,0x4a,0x24, 0xf8,0xd2,0xbb,0x3d, 0x11,0xae,0xf9,0x32, 0x6d,0xc7,0x29,0xa1,
+	0x4b,0x1d,0x9e,0x2f, 0xf3,0xdc,0xb2,0x30, 0xec,0x0d,0x86,0x52, 0xd0,0x77,0xc1,0xe3,
+	0x6c,0x2b,0xb3,0x16, 0x99,0xa9,0x70,0xb9, 0xfa,0x11,0x94,0x48, 0x22,0x47,0xe9,0x64,
+	0xc4,0xa8,0xfc,0x8c, 0x1a,0xa0,0xf0,0x3f, 0xd8,0x56,0x7d,0x2c, 0xef,0x22,0x33,0x90,
+	0xc7,0x87,0x49,0x4e, 0xc1,0xd9,0x38,0xd1, 0xfe,0x8c,0xca,0xa2, 0x36,0x98,0xd4,0x0b,
+	0xcf,0xa6,0xf5,0x81, 0x28,0xa5,0x7a,0xde, 0x26,0xda,0xb7,0x8e, 0xa4,0x3f,0xad,0xbf,
+	0xe4,0x2c,0x3a,0x9d, 0x0d,0x50,0x78,0x92, 0x9b,0x6a,0x5f,0xcc, 0x62,0x54,0x7e,0x46,
+	0xc2,0xf6,0x8d,0x13, 0xe8,0x90,0xd8,0xb8, 0x5e,0x2e,0x39,0xf7, 0xf5,0x82,0xc3,0xaf,
+	0xbe,0x9f,0x5d,0x80, 0x7c,0x69,0xd0,0x93, 0xa9,0x6f,0xd5,0x2d, 0xb3,0xcf,0x25,0x12,
+	0x3b,0xc8,0xac,0x99, 0xa7,0x10,0x18,0x7d, 0x6e,0xe8,0x9c,0x63, 0x7b,0xdb,0x3b,0xbb,
+	0x09,0xcd,0x26,0x78, 0xf4,0x6e,0x59,0x18, 0x01,0xec,0x9a,0xb7, 0xa8,0x83,0x4f,0x9a,
+	0x65,0xe6,0x95,0x6e, 0x7e,0xaa,0xff,0xe6, 0x08,0x21,0xbc,0xcf, 0xe6,0xef,0x15,0xe8,
+	0xd9,0xba,0xe7,0x9b, 0xce,0x4a,0x6f,0x36, 0xd4,0xea,0x9f,0x09, 0xd6,0x29,0xb0,0x7c,
+	0xaf,0x31,0xa4,0xb2, 0x31,0x2a,0x3f,0x23, 0x30,0xc6,0xa5,0x94, 0xc0,0x35,0xa2,0x66,
+	0x37,0x74,0x4e,0xbc, 0xa6,0xfc,0x82,0xca, 0xb0,0xe0,0x90,0xd0, 0x15,0x33,0xa7,0xd8,
+	0x4a,0xf1,0x04,0x98, 0xf7,0x41,0xec,0xda, 0x0e,0x7f,0xcd,0x50, 0x2f,0x17,0x91,0xf6,
+	0x8d,0x76,0x4d,0xd6, 0x4d,0x43,0xef,0xb0, 0x54,0xcc,0xaa,0x4d, 0xdf,0xe4,0x96,0x04,
+	0xe3,0x9e,0xd1,0xb5, 0x1b,0x4c,0x6a,0x88, 0xb8,0xc1,0x2c,0x1f, 0x7f,0x46,0x65,0x51,
+	0x04,0x9d,0x5e,0xea, 0x5d,0x01,0x8c,0x35, 0x73,0xfa,0x87,0x74, 0x2e,0xfb,0x0b,0x41,
+	0x5a,0xb3,0x67,0x1d, 0x52,0x92,0xdb,0xd2, 0x33,0xe9,0x10,0x56, 0x13,0x6d,0xd6,0x47,
+	0x8c,0x9a,0xd7,0x61, 0x7a,0x37,0xa1,0x0c, 0x8e,0x59,0xf8,0x14, 0x89,0xeb,0x13,0x3c,
+	0xee,0xce,0xa9,0x27, 0x35,0xb7,0x61,0xc9, 0xed,0xe1,0x1c,0xe5, 0x3c,0x7a,0x47,0xb1,
+	0x59,0x9c,0xd2,0xdf, 0x3f,0x55,0xf2,0x73, 0x79,0x18,0x14,0xce, 0xbf,0x73,0xc7,0x37,
+	0xea,0x53,0xf7,0xcd, 0x5b,0x5f,0xfd,0xaa, 0x14,0xdf,0x3d,0x6f, 0x86,0x78,0x44,0xdb,
+	0x81,0xca,0xaf,0xf3, 0x3e,0xb9,0x68,0xc4, 0x2c,0x38,0x24,0x34, 0x5f,0xc2,0xa3,0x40,
+	0x72,0x16,0x1d,0xc3, 0x0c,0xbc,0xe2,0x25, 0x8b,0x28,0x3c,0x49, 0x41,0xff,0x0d,0x95,
+	0x71,0x39,0xa8,0x01, 0xde,0x08,0x0c,0xb3, 0x9c,0xd8,0xb4,0xe4, 0x90,0x64,0x56,0xc1,
+	0x61,0x7b,0xcb,0x84, 0x70,0xd5,0x32,0xb6, 0x74,0x48,0x6c,0x5c, 0x42,0xd0,0xb8,0x57
+};
+
+static RD_UINT8 T7[256][4]=
+{
+	0xa7,0x50,0x51,0xf4, 0x65,0x53,0x7e,0x41, 0xa4,0xc3,0x1a,0x17, 0x5e,0x96,0x3a,0x27,
+	0x6b,0xcb,0x3b,0xab, 0x45,0xf1,0x1f,0x9d, 0x58,0xab,0xac,0xfa, 0x03,0x93,0x4b,0xe3,
+	0xfa,0x55,0x20,0x30, 0x6d,0xf6,0xad,0x76, 0x76,0x91,0x88,0xcc, 0x4c,0x25,0xf5,0x02,
+	0xd7,0xfc,0x4f,0xe5, 0xcb,0xd7,0xc5,0x2a, 0x44,0x80,0x26,0x35, 0xa3,0x8f,0xb5,0x62,
+	0x5a,0x49,0xde,0xb1, 0x1b,0x67,0x25,0xba, 0x0e,0x98,0x45,0xea, 0xc0,0xe1,0x5d,0xfe,
+	0x75,0x02,0xc3,0x2f, 0xf0,0x12,0x81,0x4c, 0x97,0xa3,0x8d,0x46, 0xf9,0xc6,0x6b,0xd3,
+	0x5f,0xe7,0x03,0x8f, 0x9c,0x95,0x15,0x92, 0x7a,0xeb,0xbf,0x6d, 0x59,0xda,0x95,0x52,
+	0x83,0x2d,0xd4,0xbe, 0x21,0xd3,0x58,0x74, 0x69,0x29,0x49,0xe0, 0xc8,0x44,0x8e,0xc9,
+	0x89,0x6a,0x75,0xc2, 0x79,0x78,0xf4,0x8e, 0x3e,0x6b,0x99,0x58, 0x71,0xdd,0x27,0xb9,
+	0x4f,0xb6,0xbe,0xe1, 0xad,0x17,0xf0,0x88, 0xac,0x66,0xc9,0x20, 0x3a,0xb4,0x7d,0xce,
+	0x4a,0x18,0x63,0xdf, 0x31,0x82,0xe5,0x1a, 0x33,0x60,0x97,0x51, 0x7f,0x45,0x62,0x53,
+	0x77,0xe0,0xb1,0x64, 0xae,0x84,0xbb,0x6b, 0xa0,0x1c,0xfe,0x81, 0x2b,0x94,0xf9,0x08,
+	0x68,0x58,0x70,0x48, 0xfd,0x19,0x8f,0x45, 0x6c,0x87,0x94,0xde, 0xf8,0xb7,0x52,0x7b,
+	0xd3,0x23,0xab,0x73, 0x02,0xe2,0x72,0x4b, 0x8f,0x57,0xe3,0x1f, 0xab,0x2a,0x66,0x55,
+	0x28,0x07,0xb2,0xeb, 0xc2,0x03,0x2f,0xb5, 0x7b,0x9a,0x86,0xc5, 0x08,0xa5,0xd3,0x37,
+	0x87,0xf2,0x30,0x28, 0xa5,0xb2,0x23,0xbf, 0x6a,0xba,0x02,0x03, 0x82,0x5c,0xed,0x16,
+	0x1c,0x2b,0x8a,0xcf, 0xb4,0x92,0xa7,0x79, 0xf2,0xf0,0xf3,0x07, 0xe2,0xa1,0x4e,0x69,
+	0xf4,0xcd,0x65,0xda, 0xbe,0xd5,0x06,0x05, 0x62,0x1f,0xd1,0x34, 0xfe,0x8a,0xc4,0xa6,
+	0x53,0x9d,0x34,0x2e, 0x55,0xa0,0xa2,0xf3, 0xe1,0x32,0x05,0x8a, 0xeb,0x75,0xa4,0xf6,
+	0xec,0x39,0x0b,0x83, 0xef,0xaa,0x40,0x60, 0x9f,0x06,0x5e,0x71, 0x10,0x51,0xbd,0x6e,
+	0x8a,0xf9,0x3e,0x21, 0x06,0x3d,0x96,0xdd, 0x05,0xae,0xdd,0x3e, 0xbd,0x46,0x4d,0xe6,
+	0x8d,0xb5,0x91,0x54, 0x5d,0x05,0x71,0xc4, 0xd4,0x6f,0x04,0x06, 0x15,0xff,0x60,0x50,
+	0xfb,0x24,0x19,0x98, 0xe9,0x97,0xd6,0xbd, 0x43,0xcc,0x89,0x40, 0x9e,0x77,0x67,0xd9,
+	0x42,0xbd,0xb0,0xe8, 0x8b,0x88,0x07,0x89, 0x5b,0x38,0xe7,0x19, 0xee,0xdb,0x79,0xc8,
+	0x0a,0x47,0xa1,0x7c, 0x0f,0xe9,0x7c,0x42, 0x1e,0xc9,0xf8,0x84, 0x00,0x00,0x00,0x00,
+	0x86,0x83,0x09,0x80, 0xed,0x48,0x32,0x2b, 0x70,0xac,0x1e,0x11, 0x72,0x4e,0x6c,0x5a,
+	0xff,0xfb,0xfd,0x0e, 0x38,0x56,0x0f,0x85, 0xd5,0x1e,0x3d,0xae, 0x39,0x27,0x36,0x2d,
+	0xd9,0x64,0x0a,0x0f, 0xa6,0x21,0x68,0x5c, 0x54,0xd1,0x9b,0x5b, 0x2e,0x3a,0x24,0x36,
+	0x67,0xb1,0x0c,0x0a, 0xe7,0x0f,0x93,0x57, 0x96,0xd2,0xb4,0xee, 0x91,0x9e,0x1b,0x9b,
+	0xc5,0x4f,0x80,0xc0, 0x20,0xa2,0x61,0xdc, 0x4b,0x69,0x5a,0x77, 0x1a,0x16,0x1c,0x12,
+	0xba,0x0a,0xe2,0x93, 0x2a,0xe5,0xc0,0xa0, 0xe0,0x43,0x3c,0x22, 0x17,0x1d,0x12,0x1b,
+	0x0d,0x0b,0x0e,0x09, 0xc7,0xad,0xf2,0x8b, 0xa8,0xb9,0x2d,0xb6, 0xa9,0xc8,0x14,0x1e,
+	0x19,0x85,0x57,0xf1, 0x07,0x4c,0xaf,0x75, 0xdd,0xbb,0xee,0x99, 0x60,0xfd,0xa3,0x7f,
+	0x26,0x9f,0xf7,0x01, 0xf5,0xbc,0x5c,0x72, 0x3b,0xc5,0x44,0x66, 0x7e,0x34,0x5b,0xfb,
+	0x29,0x76,0x8b,0x43, 0xc6,0xdc,0xcb,0x23, 0xfc,0x68,0xb6,0xed, 0xf1,0x63,0xb8,0xe4,
+	0xdc,0xca,0xd7,0x31, 0x85,0x10,0x42,0x63, 0x22,0x40,0x13,0x97, 0x11,0x20,0x84,0xc6,
+	0x24,0x7d,0x85,0x4a, 0x3d,0xf8,0xd2,0xbb, 0x32,0x11,0xae,0xf9, 0xa1,0x6d,0xc7,0x29,
+	0x2f,0x4b,0x1d,0x9e, 0x30,0xf3,0xdc,0xb2, 0x52,0xec,0x0d,0x86, 0xe3,0xd0,0x77,0xc1,
+	0x16,0x6c,0x2b,0xb3, 0xb9,0x99,0xa9,0x70, 0x48,0xfa,0x11,0x94, 0x64,0x22,0x47,0xe9,
+	0x8c,0xc4,0xa8,0xfc, 0x3f,0x1a,0xa0,0xf0, 0x2c,0xd8,0x56,0x7d, 0x90,0xef,0x22,0x33,
+	0x4e,0xc7,0x87,0x49, 0xd1,0xc1,0xd9,0x38, 0xa2,0xfe,0x8c,0xca, 0x0b,0x36,0x98,0xd4,
+	0x81,0xcf,0xa6,0xf5, 0xde,0x28,0xa5,0x7a, 0x8e,0x26,0xda,0xb7, 0xbf,0xa4,0x3f,0xad,
+	0x9d,0xe4,0x2c,0x3a, 0x92,0x0d,0x50,0x78, 0xcc,0x9b,0x6a,0x5f, 0x46,0x62,0x54,0x7e,
+	0x13,0xc2,0xf6,0x8d, 0xb8,0xe8,0x90,0xd8, 0xf7,0x5e,0x2e,0x39, 0xaf,0xf5,0x82,0xc3,
+	0x80,0xbe,0x9f,0x5d, 0x93,0x7c,0x69,0xd0, 0x2d,0xa9,0x6f,0xd5, 0x12,0xb3,0xcf,0x25,
+	0x99,0x3b,0xc8,0xac, 0x7d,0xa7,0x10,0x18, 0x63,0x6e,0xe8,0x9c, 0xbb,0x7b,0xdb,0x3b,
+	0x78,0x09,0xcd,0x26, 0x18,0xf4,0x6e,0x59, 0xb7,0x01,0xec,0x9a, 0x9a,0xa8,0x83,0x4f,
+	0x6e,0x65,0xe6,0x95, 0xe6,0x7e,0xaa,0xff, 0xcf,0x08,0x21,0xbc, 0xe8,0xe6,0xef,0x15,
+	0x9b,0xd9,0xba,0xe7, 0x36,0xce,0x4a,0x6f, 0x09,0xd4,0xea,0x9f, 0x7c,0xd6,0x29,0xb0,
+	0xb2,0xaf,0x31,0xa4, 0x23,0x31,0x2a,0x3f, 0x94,0x30,0xc6,0xa5, 0x66,0xc0,0x35,0xa2,
+	0xbc,0x37,0x74,0x4e, 0xca,0xa6,0xfc,0x82, 0xd0,0xb0,0xe0,0x90, 0xd8,0x15,0x33,0xa7,
+	0x98,0x4a,0xf1,0x04, 0xda,0xf7,0x41,0xec, 0x50,0x0e,0x7f,0xcd, 0xf6,0x2f,0x17,0x91,
+	0xd6,0x8d,0x76,0x4d, 0xb0,0x4d,0x43,0xef, 0x4d,0x54,0xcc,0xaa, 0x04,0xdf,0xe4,0x96,
+	0xb5,0xe3,0x9e,0xd1, 0x88,0x1b,0x4c,0x6a, 0x1f,0xb8,0xc1,0x2c, 0x51,0x7f,0x46,0x65,
+	0xea,0x04,0x9d,0x5e, 0x35,0x5d,0x01,0x8c, 0x74,0x73,0xfa,0x87, 0x41,0x2e,0xfb,0x0b,
+	0x1d,0x5a,0xb3,0x67, 0xd2,0x52,0x92,0xdb, 0x56,0x33,0xe9,0x10, 0x47,0x13,0x6d,0xd6,
+	0x61,0x8c,0x9a,0xd7, 0x0c,0x7a,0x37,0xa1, 0x14,0x8e,0x59,0xf8, 0x3c,0x89,0xeb,0x13,
+	0x27,0xee,0xce,0xa9, 0xc9,0x35,0xb7,0x61, 0xe5,0xed,0xe1,0x1c, 0xb1,0x3c,0x7a,0x47,
+	0xdf,0x59,0x9c,0xd2, 0x73,0x3f,0x55,0xf2, 0xce,0x79,0x18,0x14, 0x37,0xbf,0x73,0xc7,
+	0xcd,0xea,0x53,0xf7, 0xaa,0x5b,0x5f,0xfd, 0x6f,0x14,0xdf,0x3d, 0xdb,0x86,0x78,0x44,
+	0xf3,0x81,0xca,0xaf, 0xc4,0x3e,0xb9,0x68, 0x34,0x2c,0x38,0x24, 0x40,0x5f,0xc2,0xa3,
+	0xc3,0x72,0x16,0x1d, 0x25,0x0c,0xbc,0xe2, 0x49,0x8b,0x28,0x3c, 0x95,0x41,0xff,0x0d,
+	0x01,0x71,0x39,0xa8, 0xb3,0xde,0x08,0x0c, 0xe4,0x9c,0xd8,0xb4, 0xc1,0x90,0x64,0x56,
+	0x84,0x61,0x7b,0xcb, 0xb6,0x70,0xd5,0x32, 0x5c,0x74,0x48,0x6c, 0x57,0x42,0xd0,0xb8
+};
+
+static RD_UINT8 T8[256][4]=
+{
+	0xf4,0xa7,0x50,0x51, 0x41,0x65,0x53,0x7e, 0x17,0xa4,0xc3,0x1a, 0x27,0x5e,0x96,0x3a,
+	0xab,0x6b,0xcb,0x3b, 0x9d,0x45,0xf1,0x1f, 0xfa,0x58,0xab,0xac, 0xe3,0x03,0x93,0x4b,
+	0x30,0xfa,0x55,0x20, 0x76,0x6d,0xf6,0xad, 0xcc,0x76,0x91,0x88, 0x02,0x4c,0x25,0xf5,
+	0xe5,0xd7,0xfc,0x4f, 0x2a,0xcb,0xd7,0xc5, 0x35,0x44,0x80,0x26, 0x62,0xa3,0x8f,0xb5,
+	0xb1,0x5a,0x49,0xde, 0xba,0x1b,0x67,0x25, 0xea,0x0e,0x98,0x45, 0xfe,0xc0,0xe1,0x5d,
+	0x2f,0x75,0x02,0xc3, 0x4c,0xf0,0x12,0x81, 0x46,0x97,0xa3,0x8d, 0xd3,0xf9,0xc6,0x6b,
+	0x8f,0x5f,0xe7,0x03, 0x92,0x9c,0x95,0x15, 0x6d,0x7a,0xeb,0xbf, 0x52,0x59,0xda,0x95,
+	0xbe,0x83,0x2d,0xd4, 0x74,0x21,0xd3,0x58, 0xe0,0x69,0x29,0x49, 0xc9,0xc8,0x44,0x8e,
+	0xc2,0x89,0x6a,0x75, 0x8e,0x79,0x78,0xf4, 0x58,0x3e,0x6b,0x99, 0xb9,0x71,0xdd,0x27,
+	0xe1,0x4f,0xb6,0xbe, 0x88,0xad,0x17,0xf0, 0x20,0xac,0x66,0xc9, 0xce,0x3a,0xb4,0x7d,
+	0xdf,0x4a,0x18,0x63, 0x1a,0x31,0x82,0xe5, 0x51,0x33,0x60,0x97, 0x53,0x7f,0x45,0x62,
+	0x64,0x77,0xe0,0xb1, 0x6b,0xae,0x84,0xbb, 0x81,0xa0,0x1c,0xfe, 0x08,0x2b,0x94,0xf9,
+	0x48,0x68,0x58,0x70, 0x45,0xfd,0x19,0x8f, 0xde,0x6c,0x87,0x94, 0x7b,0xf8,0xb7,0x52,
+	0x73,0xd3,0x23,0xab, 0x4b,0x02,0xe2,0x72, 0x1f,0x8f,0x57,0xe3, 0x55,0xab,0x2a,0x66,
+	0xeb,0x28,0x07,0xb2, 0xb5,0xc2,0x03,0x2f, 0xc5,0x7b,0x9a,0x86, 0x37,0x08,0xa5,0xd3,
+	0x28,0x87,0xf2,0x30, 0xbf,0xa5,0xb2,0x23, 0x03,0x6a,0xba,0x02, 0x16,0x82,0x5c,0xed,
+	0xcf,0x1c,0x2b,0x8a, 0x79,0xb4,0x92,0xa7, 0x07,0xf2,0xf0,0xf3, 0x69,0xe2,0xa1,0x4e,
+	0xda,0xf4,0xcd,0x65, 0x05,0xbe,0xd5,0x06, 0x34,0x62,0x1f,0xd1, 0xa6,0xfe,0x8a,0xc4,
+	0x2e,0x53,0x9d,0x34, 0xf3,0x55,0xa0,0xa2, 0x8a,0xe1,0x32,0x05, 0xf6,0xeb,0x75,0xa4,
+	0x83,0xec,0x39,0x0b, 0x60,0xef,0xaa,0x40, 0x71,0x9f,0x06,0x5e, 0x6e,0x10,0x51,0xbd,
+	0x21,0x8a,0xf9,0x3e, 0xdd,0x06,0x3d,0x96, 0x3e,0x05,0xae,0xdd, 0xe6,0xbd,0x46,0x4d,
+	0x54,0x8d,0xb5,0x91, 0xc4,0x5d,0x05,0x71, 0x06,0xd4,0x6f,0x04, 0x50,0x15,0xff,0x60,
+	0x98,0xfb,0x24,0x19, 0xbd,0xe9,0x97,0xd6, 0x40,0x43,0xcc,0x89, 0xd9,0x9e,0x77,0x67,
+	0xe8,0x42,0xbd,0xb0, 0x89,0x8b,0x88,0x07, 0x19,0x5b,0x38,0xe7, 0xc8,0xee,0xdb,0x79,
+	0x7c,0x0a,0x47,0xa1, 0x42,0x0f,0xe9,0x7c, 0x84,0x1e,0xc9,0xf8, 0x00,0x00,0x00,0x00,
+	0x80,0x86,0x83,0x09, 0x2b,0xed,0x48,0x32, 0x11,0x70,0xac,0x1e, 0x5a,0x72,0x4e,0x6c,
+	0x0e,0xff,0xfb,0xfd, 0x85,0x38,0x56,0x0f, 0xae,0xd5,0x1e,0x3d, 0x2d,0x39,0x27,0x36,
+	0x0f,0xd9,0x64,0x0a, 0x5c,0xa6,0x21,0x68, 0x5b,0x54,0xd1,0x9b, 0x36,0x2e,0x3a,0x24,
+	0x0a,0x67,0xb1,0x0c, 0x57,0xe7,0x0f,0x93, 0xee,0x96,0xd2,0xb4, 0x9b,0x91,0x9e,0x1b,
+	0xc0,0xc5,0x4f,0x80, 0xdc,0x20,0xa2,0x61, 0x77,0x4b,0x69,0x5a, 0x12,0x1a,0x16,0x1c,
+	0x93,0xba,0x0a,0xe2, 0xa0,0x2a,0xe5,0xc0, 0x22,0xe0,0x43,0x3c, 0x1b,0x17,0x1d,0x12,
+	0x09,0x0d,0x0b,0x0e, 0x8b,0xc7,0xad,0xf2, 0xb6,0xa8,0xb9,0x2d, 0x1e,0xa9,0xc8,0x14,
+	0xf1,0x19,0x85,0x57, 0x75,0x07,0x4c,0xaf, 0x99,0xdd,0xbb,0xee, 0x7f,0x60,0xfd,0xa3,
+	0x01,0x26,0x9f,0xf7, 0x72,0xf5,0xbc,0x5c, 0x66,0x3b,0xc5,0x44, 0xfb,0x7e,0x34,0x5b,
+	0x43,0x29,0x76,0x8b, 0x23,0xc6,0xdc,0xcb, 0xed,0xfc,0x68,0xb6, 0xe4,0xf1,0x63,0xb8,
+	0x31,0xdc,0xca,0xd7, 0x63,0x85,0x10,0x42, 0x97,0x22,0x40,0x13, 0xc6,0x11,0x20,0x84,
+	0x4a,0x24,0x7d,0x85, 0xbb,0x3d,0xf8,0xd2, 0xf9,0x32,0x11,0xae, 0x29,0xa1,0x6d,0xc7,
+	0x9e,0x2f,0x4b,0x1d, 0xb2,0x30,0xf3,0xdc, 0x86,0x52,0xec,0x0d, 0xc1,0xe3,0xd0,0x77,
+	0xb3,0x16,0x6c,0x2b, 0x70,0xb9,0x99,0xa9, 0x94,0x48,0xfa,0x11, 0xe9,0x64,0x22,0x47,
+	0xfc,0x8c,0xc4,0xa8, 0xf0,0x3f,0x1a,0xa0, 0x7d,0x2c,0xd8,0x56, 0x33,0x90,0xef,0x22,
+	0x49,0x4e,0xc7,0x87, 0x38,0xd1,0xc1,0xd9, 0xca,0xa2,0xfe,0x8c, 0xd4,0x0b,0x36,0x98,
+	0xf5,0x81,0xcf,0xa6, 0x7a,0xde,0x28,0xa5, 0xb7,0x8e,0x26,0xda, 0xad,0xbf,0xa4,0x3f,
+	0x3a,0x9d,0xe4,0x2c, 0x78,0x92,0x0d,0x50, 0x5f,0xcc,0x9b,0x6a, 0x7e,0x46,0x62,0x54,
+	0x8d,0x13,0xc2,0xf6, 0xd8,0xb8,0xe8,0x90, 0x39,0xf7,0x5e,0x2e, 0xc3,0xaf,0xf5,0x82,
+	0x5d,0x80,0xbe,0x9f, 0xd0,0x93,0x7c,0x69, 0xd5,0x2d,0xa9,0x6f, 0x25,0x12,0xb3,0xcf,
+	0xac,0x99,0x3b,0xc8, 0x18,0x7d,0xa7,0x10, 0x9c,0x63,0x6e,0xe8, 0x3b,0xbb,0x7b,0xdb,
+	0x26,0x78,0x09,0xcd, 0x59,0x18,0xf4,0x6e, 0x9a,0xb7,0x01,0xec, 0x4f,0x9a,0xa8,0x83,
+	0x95,0x6e,0x65,0xe6, 0xff,0xe6,0x7e,0xaa, 0xbc,0xcf,0x08,0x21, 0x15,0xe8,0xe6,0xef,
+	0xe7,0x9b,0xd9,0xba, 0x6f,0x36,0xce,0x4a, 0x9f,0x09,0xd4,0xea, 0xb0,0x7c,0xd6,0x29,
+	0xa4,0xb2,0xaf,0x31, 0x3f,0x23,0x31,0x2a, 0xa5,0x94,0x30,0xc6, 0xa2,0x66,0xc0,0x35,
+	0x4e,0xbc,0x37,0x74, 0x82,0xca,0xa6,0xfc, 0x90,0xd0,0xb0,0xe0, 0xa7,0xd8,0x15,0x33,
+	0x04,0x98,0x4a,0xf1, 0xec,0xda,0xf7,0x41, 0xcd,0x50,0x0e,0x7f, 0x91,0xf6,0x2f,0x17,
+	0x4d,0xd6,0x8d,0x76, 0xef,0xb0,0x4d,0x43, 0xaa,0x4d,0x54,0xcc, 0x96,0x04,0xdf,0xe4,
+	0xd1,0xb5,0xe3,0x9e, 0x6a,0x88,0x1b,0x4c, 0x2c,0x1f,0xb8,0xc1, 0x65,0x51,0x7f,0x46,
+	0x5e,0xea,0x04,0x9d, 0x8c,0x35,0x5d,0x01, 0x87,0x74,0x73,0xfa, 0x0b,0x41,0x2e,0xfb,
+	0x67,0x1d,0x5a,0xb3, 0xdb,0xd2,0x52,0x92, 0x10,0x56,0x33,0xe9, 0xd6,0x47,0x13,0x6d,
+	0xd7,0x61,0x8c,0x9a, 0xa1,0x0c,0x7a,0x37, 0xf8,0x14,0x8e,0x59, 0x13,0x3c,0x89,0xeb,
+	0xa9,0x27,0xee,0xce, 0x61,0xc9,0x35,0xb7, 0x1c,0xe5,0xed,0xe1, 0x47,0xb1,0x3c,0x7a,
+	0xd2,0xdf,0x59,0x9c, 0xf2,0x73,0x3f,0x55, 0x14,0xce,0x79,0x18, 0xc7,0x37,0xbf,0x73,
+	0xf7,0xcd,0xea,0x53, 0xfd,0xaa,0x5b,0x5f, 0x3d,0x6f,0x14,0xdf, 0x44,0xdb,0x86,0x78,
+	0xaf,0xf3,0x81,0xca, 0x68,0xc4,0x3e,0xb9, 0x24,0x34,0x2c,0x38, 0xa3,0x40,0x5f,0xc2,
+	0x1d,0xc3,0x72,0x16, 0xe2,0x25,0x0c,0xbc, 0x3c,0x49,0x8b,0x28, 0x0d,0x95,0x41,0xff,
+	0xa8,0x01,0x71,0x39, 0x0c,0xb3,0xde,0x08, 0xb4,0xe4,0x9c,0xd8, 0x56,0xc1,0x90,0x64,
+	0xcb,0x84,0x61,0x7b, 0x32,0xb6,0x70,0xd5, 0x6c,0x5c,0x74,0x48, 0xb8,0x57,0x42,0xd0
+};
+
+static RD_UINT8 S5[256]=
+{
+	0x52,0x09,0x6a,0xd5,
+	0x30,0x36,0xa5,0x38,
+	0xbf,0x40,0xa3,0x9e,
+	0x81,0xf3,0xd7,0xfb,
+	0x7c,0xe3,0x39,0x82,
+	0x9b,0x2f,0xff,0x87,
+	0x34,0x8e,0x43,0x44,
+	0xc4,0xde,0xe9,0xcb,
+	0x54,0x7b,0x94,0x32,
+	0xa6,0xc2,0x23,0x3d,
+	0xee,0x4c,0x95,0x0b,
+	0x42,0xfa,0xc3,0x4e,
+	0x08,0x2e,0xa1,0x66,
+	0x28,0xd9,0x24,0xb2,
+	0x76,0x5b,0xa2,0x49,
+	0x6d,0x8b,0xd1,0x25,
+	0x72,0xf8,0xf6,0x64,
+	0x86,0x68,0x98,0x16,
+	0xd4,0xa4,0x5c,0xcc,
+	0x5d,0x65,0xb6,0x92,
+	0x6c,0x70,0x48,0x50,
+	0xfd,0xed,0xb9,0xda,
+	0x5e,0x15,0x46,0x57,
+	0xa7,0x8d,0x9d,0x84,
+	0x90,0xd8,0xab,0x00,
+	0x8c,0xbc,0xd3,0x0a,
+	0xf7,0xe4,0x58,0x05,
+	0xb8,0xb3,0x45,0x06,
+	0xd0,0x2c,0x1e,0x8f,
+	0xca,0x3f,0x0f,0x02,
+	0xc1,0xaf,0xbd,0x03,
+	0x01,0x13,0x8a,0x6b,
+	0x3a,0x91,0x11,0x41,
+	0x4f,0x67,0xdc,0xea,
+	0x97,0xf2,0xcf,0xce,
+	0xf0,0xb4,0xe6,0x73,
+	0x96,0xac,0x74,0x22,
+	0xe7,0xad,0x35,0x85,
+	0xe2,0xf9,0x37,0xe8,
+	0x1c,0x75,0xdf,0x6e,
+	0x47,0xf1,0x1a,0x71,
+	0x1d,0x29,0xc5,0x89,
+	0x6f,0xb7,0x62,0x0e,
+	0xaa,0x18,0xbe,0x1b,
+	0xfc,0x56,0x3e,0x4b,
+	0xc6,0xd2,0x79,0x20,
+	0x9a,0xdb,0xc0,0xfe,
+	0x78,0xcd,0x5a,0xf4,
+	0x1f,0xdd,0xa8,0x33,
+	0x88,0x07,0xc7,0x31,
+	0xb1,0x12,0x10,0x59,
+	0x27,0x80,0xec,0x5f,
+	0x60,0x51,0x7f,0xa9,
+	0x19,0xb5,0x4a,0x0d,
+	0x2d,0xe5,0x7a,0x9f,
+	0x93,0xc9,0x9c,0xef,
+	0xa0,0xe0,0x3b,0x4d,
+	0xae,0x2a,0xf5,0xb0,
+	0xc8,0xeb,0xbb,0x3c,
+	0x83,0x53,0x99,0x61,
+	0x17,0x2b,0x04,0x7e,
+	0xba,0x77,0xd6,0x26,
+	0xe1,0x69,0x14,0x63,
+	0x55,0x21,0x0c,0x7d
+};
+
+static RD_UINT8 U1[256][4]=
+{
+	0x00,0x00,0x00,0x00, 0x0e,0x09,0x0d,0x0b, 0x1c,0x12,0x1a,0x16, 0x12,0x1b,0x17,0x1d,
+	0x38,0x24,0x34,0x2c, 0x36,0x2d,0x39,0x27, 0x24,0x36,0x2e,0x3a, 0x2a,0x3f,0x23,0x31,
+	0x70,0x48,0x68,0x58, 0x7e,0x41,0x65,0x53, 0x6c,0x5a,0x72,0x4e, 0x62,0x53,0x7f,0x45,
+	0x48,0x6c,0x5c,0x74, 0x46,0x65,0x51,0x7f, 0x54,0x7e,0x46,0x62, 0x5a,0x77,0x4b,0x69,
+	0xe0,0x90,0xd0,0xb0, 0xee,0x99,0xdd,0xbb, 0xfc,0x82,0xca,0xa6, 0xf2,0x8b,0xc7,0xad,
+	0xd8,0xb4,0xe4,0x9c, 0xd6,0xbd,0xe9,0x97, 0xc4,0xa6,0xfe,0x8a, 0xca,0xaf,0xf3,0x81,
+	0x90,0xd8,0xb8,0xe8, 0x9e,0xd1,0xb5,0xe3, 0x8c,0xca,0xa2,0xfe, 0x82,0xc3,0xaf,0xf5,
+	0xa8,0xfc,0x8c,0xc4, 0xa6,0xf5,0x81,0xcf, 0xb4,0xee,0x96,0xd2, 0xba,0xe7,0x9b,0xd9,
+	0xdb,0x3b,0xbb,0x7b, 0xd5,0x32,0xb6,0x70, 0xc7,0x29,0xa1,0x6d, 0xc9,0x20,0xac,0x66,
+	0xe3,0x1f,0x8f,0x57, 0xed,0x16,0x82,0x5c, 0xff,0x0d,0x95,0x41, 0xf1,0x04,0x98,0x4a,
+	0xab,0x73,0xd3,0x23, 0xa5,0x7a,0xde,0x28, 0xb7,0x61,0xc9,0x35, 0xb9,0x68,0xc4,0x3e,
+	0x93,0x57,0xe7,0x0f, 0x9d,0x5e,0xea,0x04, 0x8f,0x45,0xfd,0x19, 0x81,0x4c,0xf0,0x12,
+	0x3b,0xab,0x6b,0xcb, 0x35,0xa2,0x66,0xc0, 0x27,0xb9,0x71,0xdd, 0x29,0xb0,0x7c,0xd6,
+	0x03,0x8f,0x5f,0xe7, 0x0d,0x86,0x52,0xec, 0x1f,0x9d,0x45,0xf1, 0x11,0x94,0x48,0xfa,
+	0x4b,0xe3,0x03,0x93, 0x45,0xea,0x0e,0x98, 0x57,0xf1,0x19,0x85, 0x59,0xf8,0x14,0x8e,
+	0x73,0xc7,0x37,0xbf, 0x7d,0xce,0x3a,0xb4, 0x6f,0xd5,0x2d,0xa9, 0x61,0xdc,0x20,0xa2,
+	0xad,0x76,0x6d,0xf6, 0xa3,0x7f,0x60,0xfd, 0xb1,0x64,0x77,0xe0, 0xbf,0x6d,0x7a,0xeb,
+	0x95,0x52,0x59,0xda, 0x9b,0x5b,0x54,0xd1, 0x89,0x40,0x43,0xcc, 0x87,0x49,0x4e,0xc7,
+	0xdd,0x3e,0x05,0xae, 0xd3,0x37,0x08,0xa5, 0xc1,0x2c,0x1f,0xb8, 0xcf,0x25,0x12,0xb3,
+	0xe5,0x1a,0x31,0x82, 0xeb,0x13,0x3c,0x89, 0xf9,0x08,0x2b,0x94, 0xf7,0x01,0x26,0x9f,
+	0x4d,0xe6,0xbd,0x46, 0x43,0xef,0xb0,0x4d, 0x51,0xf4,0xa7,0x50, 0x5f,0xfd,0xaa,0x5b,
+	0x75,0xc2,0x89,0x6a, 0x7b,0xcb,0x84,0x61, 0x69,0xd0,0x93,0x7c, 0x67,0xd9,0x9e,0x77,
+	0x3d,0xae,0xd5,0x1e, 0x33,0xa7,0xd8,0x15, 0x21,0xbc,0xcf,0x08, 0x2f,0xb5,0xc2,0x03,
+	0x05,0x8a,0xe1,0x32, 0x0b,0x83,0xec,0x39, 0x19,0x98,0xfb,0x24, 0x17,0x91,0xf6,0x2f,
+	0x76,0x4d,0xd6,0x8d, 0x78,0x44,0xdb,0x86, 0x6a,0x5f,0xcc,0x9b, 0x64,0x56,0xc1,0x90,
+	0x4e,0x69,0xe2,0xa1, 0x40,0x60,0xef,0xaa, 0x52,0x7b,0xf8,0xb7, 0x5c,0x72,0xf5,0xbc,
+	0x06,0x05,0xbe,0xd5, 0x08,0x0c,0xb3,0xde, 0x1a,0x17,0xa4,0xc3, 0x14,0x1e,0xa9,0xc8,
+	0x3e,0x21,0x8a,0xf9, 0x30,0x28,0x87,0xf2, 0x22,0x33,0x90,0xef, 0x2c,0x3a,0x9d,0xe4,
+	0x96,0xdd,0x06,0x3d, 0x98,0xd4,0x0b,0x36, 0x8a,0xcf,0x1c,0x2b, 0x84,0xc6,0x11,0x20,
+	0xae,0xf9,0x32,0x11, 0xa0,0xf0,0x3f,0x1a, 0xb2,0xeb,0x28,0x07, 0xbc,0xe2,0x25,0x0c,
+	0xe6,0x95,0x6e,0x65, 0xe8,0x9c,0x63,0x6e, 0xfa,0x87,0x74,0x73, 0xf4,0x8e,0x79,0x78,
+	0xde,0xb1,0x5a,0x49, 0xd0,0xb8,0x57,0x42, 0xc2,0xa3,0x40,0x5f, 0xcc,0xaa,0x4d,0x54,
+	0x41,0xec,0xda,0xf7, 0x4f,0xe5,0xd7,0xfc, 0x5d,0xfe,0xc0,0xe1, 0x53,0xf7,0xcd,0xea,
+	0x79,0xc8,0xee,0xdb, 0x77,0xc1,0xe3,0xd0, 0x65,0xda,0xf4,0xcd, 0x6b,0xd3,0xf9,0xc6,
+	0x31,0xa4,0xb2,0xaf, 0x3f,0xad,0xbf,0xa4, 0x2d,0xb6,0xa8,0xb9, 0x23,0xbf,0xa5,0xb2,
+	0x09,0x80,0x86,0x83, 0x07,0x89,0x8b,0x88, 0x15,0x92,0x9c,0x95, 0x1b,0x9b,0x91,0x9e,
+	0xa1,0x7c,0x0a,0x47, 0xaf,0x75,0x07,0x4c, 0xbd,0x6e,0x10,0x51, 0xb3,0x67,0x1d,0x5a,
+	0x99,0x58,0x3e,0x6b, 0x97,0x51,0x33,0x60, 0x85,0x4a,0x24,0x7d, 0x8b,0x43,0x29,0x76,
+	0xd1,0x34,0x62,0x1f, 0xdf,0x3d,0x6f,0x14, 0xcd,0x26,0x78,0x09, 0xc3,0x2f,0x75,0x02,
+	0xe9,0x10,0x56,0x33, 0xe7,0x19,0x5b,0x38, 0xf5,0x02,0x4c,0x25, 0xfb,0x0b,0x41,0x2e,
+	0x9a,0xd7,0x61,0x8c, 0x94,0xde,0x6c,0x87, 0x86,0xc5,0x7b,0x9a, 0x88,0xcc,0x76,0x91,
+	0xa2,0xf3,0x55,0xa0, 0xac,0xfa,0x58,0xab, 0xbe,0xe1,0x4f,0xb6, 0xb0,0xe8,0x42,0xbd,
+	0xea,0x9f,0x09,0xd4, 0xe4,0x96,0x04,0xdf, 0xf6,0x8d,0x13,0xc2, 0xf8,0x84,0x1e,0xc9,
+	0xd2,0xbb,0x3d,0xf8, 0xdc,0xb2,0x30,0xf3, 0xce,0xa9,0x27,0xee, 0xc0,0xa0,0x2a,0xe5,
+	0x7a,0x47,0xb1,0x3c, 0x74,0x4e,0xbc,0x37, 0x66,0x55,0xab,0x2a, 0x68,0x5c,0xa6,0x21,
+	0x42,0x63,0x85,0x10, 0x4c,0x6a,0x88,0x1b, 0x5e,0x71,0x9f,0x06, 0x50,0x78,0x92,0x0d,
+	0x0a,0x0f,0xd9,0x64, 0x04,0x06,0xd4,0x6f, 0x16,0x1d,0xc3,0x72, 0x18,0x14,0xce,0x79,
+	0x32,0x2b,0xed,0x48, 0x3c,0x22,0xe0,0x43, 0x2e,0x39,0xf7,0x5e, 0x20,0x30,0xfa,0x55,
+	0xec,0x9a,0xb7,0x01, 0xe2,0x93,0xba,0x0a, 0xf0,0x88,0xad,0x17, 0xfe,0x81,0xa0,0x1c,
+	0xd4,0xbe,0x83,0x2d, 0xda,0xb7,0x8e,0x26, 0xc8,0xac,0x99,0x3b, 0xc6,0xa5,0x94,0x30,
+	0x9c,0xd2,0xdf,0x59, 0x92,0xdb,0xd2,0x52, 0x80,0xc0,0xc5,0x4f, 0x8e,0xc9,0xc8,0x44,
+	0xa4,0xf6,0xeb,0x75, 0xaa,0xff,0xe6,0x7e, 0xb8,0xe4,0xf1,0x63, 0xb6,0xed,0xfc,0x68,
+	0x0c,0x0a,0x67,0xb1, 0x02,0x03,0x6a,0xba, 0x10,0x18,0x7d,0xa7, 0x1e,0x11,0x70,0xac,
+	0x34,0x2e,0x53,0x9d, 0x3a,0x27,0x5e,0x96, 0x28,0x3c,0x49,0x8b, 0x26,0x35,0x44,0x80,
+	0x7c,0x42,0x0f,0xe9, 0x72,0x4b,0x02,0xe2, 0x60,0x50,0x15,0xff, 0x6e,0x59,0x18,0xf4,
+	0x44,0x66,0x3b,0xc5, 0x4a,0x6f,0x36,0xce, 0x58,0x74,0x21,0xd3, 0x56,0x7d,0x2c,0xd8,
+	0x37,0xa1,0x0c,0x7a, 0x39,0xa8,0x01,0x71, 0x2b,0xb3,0x16,0x6c, 0x25,0xba,0x1b,0x67,
+	0x0f,0x85,0x38,0x56, 0x01,0x8c,0x35,0x5d, 0x13,0x97,0x22,0x40, 0x1d,0x9e,0x2f,0x4b,
+	0x47,0xe9,0x64,0x22, 0x49,0xe0,0x69,0x29, 0x5b,0xfb,0x7e,0x34, 0x55,0xf2,0x73,0x3f,
+	0x7f,0xcd,0x50,0x0e, 0x71,0xc4,0x5d,0x05, 0x63,0xdf,0x4a,0x18, 0x6d,0xd6,0x47,0x13,
+	0xd7,0x31,0xdc,0xca, 0xd9,0x38,0xd1,0xc1, 0xcb,0x23,0xc6,0xdc, 0xc5,0x2a,0xcb,0xd7,
+	0xef,0x15,0xe8,0xe6, 0xe1,0x1c,0xe5,0xed, 0xf3,0x07,0xf2,0xf0, 0xfd,0x0e,0xff,0xfb,
+	0xa7,0x79,0xb4,0x92, 0xa9,0x70,0xb9,0x99, 0xbb,0x6b,0xae,0x84, 0xb5,0x62,0xa3,0x8f,
+	0x9f,0x5d,0x80,0xbe, 0x91,0x54,0x8d,0xb5, 0x83,0x4f,0x9a,0xa8, 0x8d,0x46,0x97,0xa3
+};
+
+static RD_UINT8 U2[256][4]=
+{
+	0x00,0x00,0x00,0x00, 0x0b,0x0e,0x09,0x0d, 0x16,0x1c,0x12,0x1a, 0x1d,0x12,0x1b,0x17,
+	0x2c,0x38,0x24,0x34, 0x27,0x36,0x2d,0x39, 0x3a,0x24,0x36,0x2e, 0x31,0x2a,0x3f,0x23,
+	0x58,0x70,0x48,0x68, 0x53,0x7e,0x41,0x65, 0x4e,0x6c,0x5a,0x72, 0x45,0x62,0x53,0x7f,
+	0x74,0x48,0x6c,0x5c, 0x7f,0x46,0x65,0x51, 0x62,0x54,0x7e,0x46, 0x69,0x5a,0x77,0x4b,
+	0xb0,0xe0,0x90,0xd0, 0xbb,0xee,0x99,0xdd, 0xa6,0xfc,0x82,0xca, 0xad,0xf2,0x8b,0xc7,
+	0x9c,0xd8,0xb4,0xe4, 0x97,0xd6,0xbd,0xe9, 0x8a,0xc4,0xa6,0xfe, 0x81,0xca,0xaf,0xf3,
+	0xe8,0x90,0xd8,0xb8, 0xe3,0x9e,0xd1,0xb5, 0xfe,0x8c,0xca,0xa2, 0xf5,0x82,0xc3,0xaf,
+	0xc4,0xa8,0xfc,0x8c, 0xcf,0xa6,0xf5,0x81, 0xd2,0xb4,0xee,0x96, 0xd9,0xba,0xe7,0x9b,
+	0x7b,0xdb,0x3b,0xbb, 0x70,0xd5,0x32,0xb6, 0x6d,0xc7,0x29,0xa1, 0x66,0xc9,0x20,0xac,
+	0x57,0xe3,0x1f,0x8f, 0x5c,0xed,0x16,0x82, 0x41,0xff,0x0d,0x95, 0x4a,0xf1,0x04,0x98,
+	0x23,0xab,0x73,0xd3, 0x28,0xa5,0x7a,0xde, 0x35,0xb7,0x61,0xc9, 0x3e,0xb9,0x68,0xc4,
+	0x0f,0x93,0x57,0xe7, 0x04,0x9d,0x5e,0xea, 0x19,0x8f,0x45,0xfd, 0x12,0x81,0x4c,0xf0,
+	0xcb,0x3b,0xab,0x6b, 0xc0,0x35,0xa2,0x66, 0xdd,0x27,0xb9,0x71, 0xd6,0x29,0xb0,0x7c,
+	0xe7,0x03,0x8f,0x5f, 0xec,0x0d,0x86,0x52, 0xf1,0x1f,0x9d,0x45, 0xfa,0x11,0x94,0x48,
+	0x93,0x4b,0xe3,0x03, 0x98,0x45,0xea,0x0e, 0x85,0x57,0xf1,0x19, 0x8e,0x59,0xf8,0x14,
+	0xbf,0x73,0xc7,0x37, 0xb4,0x7d,0xce,0x3a, 0xa9,0x6f,0xd5,0x2d, 0xa2,0x61,0xdc,0x20,
+	0xf6,0xad,0x76,0x6d, 0xfd,0xa3,0x7f,0x60, 0xe0,0xb1,0x64,0x77, 0xeb,0xbf,0x6d,0x7a,
+	0xda,0x95,0x52,0x59, 0xd1,0x9b,0x5b,0x54, 0xcc,0x89,0x40,0x43, 0xc7,0x87,0x49,0x4e,
+	0xae,0xdd,0x3e,0x05, 0xa5,0xd3,0x37,0x08, 0xb8,0xc1,0x2c,0x1f, 0xb3,0xcf,0x25,0x12,
+	0x82,0xe5,0x1a,0x31, 0x89,0xeb,0x13,0x3c, 0x94,0xf9,0x08,0x2b, 0x9f,0xf7,0x01,0x26,
+	0x46,0x4d,0xe6,0xbd, 0x4d,0x43,0xef,0xb0, 0x50,0x51,0xf4,0xa7, 0x5b,0x5f,0xfd,0xaa,
+	0x6a,0x75,0xc2,0x89, 0x61,0x7b,0xcb,0x84, 0x7c,0x69,0xd0,0x93, 0x77,0x67,0xd9,0x9e,
+	0x1e,0x3d,0xae,0xd5, 0x15,0x33,0xa7,0xd8, 0x08,0x21,0xbc,0xcf, 0x03,0x2f,0xb5,0xc2,
+	0x32,0x05,0x8a,0xe1, 0x39,0x0b,0x83,0xec, 0x24,0x19,0x98,0xfb, 0x2f,0x17,0x91,0xf6,
+	0x8d,0x76,0x4d,0xd6, 0x86,0x78,0x44,0xdb, 0x9b,0x6a,0x5f,0xcc, 0x90,0x64,0x56,0xc1,
+	0xa1,0x4e,0x69,0xe2, 0xaa,0x40,0x60,0xef, 0xb7,0x52,0x7b,0xf8, 0xbc,0x5c,0x72,0xf5,
+	0xd5,0x06,0x05,0xbe, 0xde,0x08,0x0c,0xb3, 0xc3,0x1a,0x17,0xa4, 0xc8,0x14,0x1e,0xa9,
+	0xf9,0x3e,0x21,0x8a, 0xf2,0x30,0x28,0x87, 0xef,0x22,0x33,0x90, 0xe4,0x2c,0x3a,0x9d,
+	0x3d,0x96,0xdd,0x06, 0x36,0x98,0xd4,0x0b, 0x2b,0x8a,0xcf,0x1c, 0x20,0x84,0xc6,0x11,
+	0x11,0xae,0xf9,0x32, 0x1a,0xa0,0xf0,0x3f, 0x07,0xb2,0xeb,0x28, 0x0c,0xbc,0xe2,0x25,
+	0x65,0xe6,0x95,0x6e, 0x6e,0xe8,0x9c,0x63, 0x73,0xfa,0x87,0x74, 0x78,0xf4,0x8e,0x79,
+	0x49,0xde,0xb1,0x5a, 0x42,0xd0,0xb8,0x57, 0x5f,0xc2,0xa3,0x40, 0x54,0xcc,0xaa,0x4d,
+	0xf7,0x41,0xec,0xda, 0xfc,0x4f,0xe5,0xd7, 0xe1,0x5d,0xfe,0xc0, 0xea,0x53,0xf7,0xcd,
+	0xdb,0x79,0xc8,0xee, 0xd0,0x77,0xc1,0xe3, 0xcd,0x65,0xda,0xf4, 0xc6,0x6b,0xd3,0xf9,
+	0xaf,0x31,0xa4,0xb2, 0xa4,0x3f,0xad,0xbf, 0xb9,0x2d,0xb6,0xa8, 0xb2,0x23,0xbf,0xa5,
+	0x83,0x09,0x80,0x86, 0x88,0x07,0x89,0x8b, 0x95,0x15,0x92,0x9c, 0x9e,0x1b,0x9b,0x91,
+	0x47,0xa1,0x7c,0x0a, 0x4c,0xaf,0x75,0x07, 0x51,0xbd,0x6e,0x10, 0x5a,0xb3,0x67,0x1d,
+	0x6b,0x99,0x58,0x3e, 0x60,0x97,0x51,0x33, 0x7d,0x85,0x4a,0x24, 0x76,0x8b,0x43,0x29,
+	0x1f,0xd1,0x34,0x62, 0x14,0xdf,0x3d,0x6f, 0x09,0xcd,0x26,0x78, 0x02,0xc3,0x2f,0x75,
+	0x33,0xe9,0x10,0x56, 0x38,0xe7,0x19,0x5b, 0x25,0xf5,0x02,0x4c, 0x2e,0xfb,0x0b,0x41,
+	0x8c,0x9a,0xd7,0x61, 0x87,0x94,0xde,0x6c, 0x9a,0x86,0xc5,0x7b, 0x91,0x88,0xcc,0x76,
+	0xa0,0xa2,0xf3,0x55, 0xab,0xac,0xfa,0x58, 0xb6,0xbe,0xe1,0x4f, 0xbd,0xb0,0xe8,0x42,
+	0xd4,0xea,0x9f,0x09, 0xdf,0xe4,0x96,0x04, 0xc2,0xf6,0x8d,0x13, 0xc9,0xf8,0x84,0x1e,
+	0xf8,0xd2,0xbb,0x3d, 0xf3,0xdc,0xb2,0x30, 0xee,0xce,0xa9,0x27, 0xe5,0xc0,0xa0,0x2a,
+	0x3c,0x7a,0x47,0xb1, 0x37,0x74,0x4e,0xbc, 0x2a,0x66,0x55,0xab, 0x21,0x68,0x5c,0xa6,
+	0x10,0x42,0x63,0x85, 0x1b,0x4c,0x6a,0x88, 0x06,0x5e,0x71,0x9f, 0x0d,0x50,0x78,0x92,
+	0x64,0x0a,0x0f,0xd9, 0x6f,0x04,0x06,0xd4, 0x72,0x16,0x1d,0xc3, 0x79,0x18,0x14,0xce,
+	0x48,0x32,0x2b,0xed, 0x43,0x3c,0x22,0xe0, 0x5e,0x2e,0x39,0xf7, 0x55,0x20,0x30,0xfa,
+	0x01,0xec,0x9a,0xb7, 0x0a,0xe2,0x93,0xba, 0x17,0xf0,0x88,0xad, 0x1c,0xfe,0x81,0xa0,
+	0x2d,0xd4,0xbe,0x83, 0x26,0xda,0xb7,0x8e, 0x3b,0xc8,0xac,0x99, 0x30,0xc6,0xa5,0x94,
+	0x59,0x9c,0xd2,0xdf, 0x52,0x92,0xdb,0xd2, 0x4f,0x80,0xc0,0xc5, 0x44,0x8e,0xc9,0xc8,
+	0x75,0xa4,0xf6,0xeb, 0x7e,0xaa,0xff,0xe6, 0x63,0xb8,0xe4,0xf1, 0x68,0xb6,0xed,0xfc,
+	0xb1,0x0c,0x0a,0x67, 0xba,0x02,0x03,0x6a, 0xa7,0x10,0x18,0x7d, 0xac,0x1e,0x11,0x70,
+	0x9d,0x34,0x2e,0x53, 0x96,0x3a,0x27,0x5e, 0x8b,0x28,0x3c,0x49, 0x80,0x26,0x35,0x44,
+	0xe9,0x7c,0x42,0x0f, 0xe2,0x72,0x4b,0x02, 0xff,0x60,0x50,0x15, 0xf4,0x6e,0x59,0x18,
+	0xc5,0x44,0x66,0x3b, 0xce,0x4a,0x6f,0x36, 0xd3,0x58,0x74,0x21, 0xd8,0x56,0x7d,0x2c,
+	0x7a,0x37,0xa1,0x0c, 0x71,0x39,0xa8,0x01, 0x6c,0x2b,0xb3,0x16, 0x67,0x25,0xba,0x1b,
+	0x56,0x0f,0x85,0x38, 0x5d,0x01,0x8c,0x35, 0x40,0x13,0x97,0x22, 0x4b,0x1d,0x9e,0x2f,
+	0x22,0x47,0xe9,0x64, 0x29,0x49,0xe0,0x69, 0x34,0x5b,0xfb,0x7e, 0x3f,0x55,0xf2,0x73,
+	0x0e,0x7f,0xcd,0x50, 0x05,0x71,0xc4,0x5d, 0x18,0x63,0xdf,0x4a, 0x13,0x6d,0xd6,0x47,
+	0xca,0xd7,0x31,0xdc, 0xc1,0xd9,0x38,0xd1, 0xdc,0xcb,0x23,0xc6, 0xd7,0xc5,0x2a,0xcb,
+	0xe6,0xef,0x15,0xe8, 0xed,0xe1,0x1c,0xe5, 0xf0,0xf3,0x07,0xf2, 0xfb,0xfd,0x0e,0xff,
+	0x92,0xa7,0x79,0xb4, 0x99,0xa9,0x70,0xb9, 0x84,0xbb,0x6b,0xae, 0x8f,0xb5,0x62,0xa3,
+	0xbe,0x9f,0x5d,0x80, 0xb5,0x91,0x54,0x8d, 0xa8,0x83,0x4f,0x9a, 0xa3,0x8d,0x46,0x97
+};
+
+static RD_UINT8 U3[256][4]=
+{
+	0x00,0x00,0x00,0x00, 0x0d,0x0b,0x0e,0x09, 0x1a,0x16,0x1c,0x12, 0x17,0x1d,0x12,0x1b,
+	0x34,0x2c,0x38,0x24, 0x39,0x27,0x36,0x2d, 0x2e,0x3a,0x24,0x36, 0x23,0x31,0x2a,0x3f,
+	0x68,0x58,0x70,0x48, 0x65,0x53,0x7e,0x41, 0x72,0x4e,0x6c,0x5a, 0x7f,0x45,0x62,0x53,
+	0x5c,0x74,0x48,0x6c, 0x51,0x7f,0x46,0x65, 0x46,0x62,0x54,0x7e, 0x4b,0x69,0x5a,0x77,
+	0xd0,0xb0,0xe0,0x90, 0xdd,0xbb,0xee,0x99, 0xca,0xa6,0xfc,0x82, 0xc7,0xad,0xf2,0x8b,
+	0xe4,0x9c,0xd8,0xb4, 0xe9,0x97,0xd6,0xbd, 0xfe,0x8a,0xc4,0xa6, 0xf3,0x81,0xca,0xaf,
+	0xb8,0xe8,0x90,0xd8, 0xb5,0xe3,0x9e,0xd1, 0xa2,0xfe,0x8c,0xca, 0xaf,0xf5,0x82,0xc3,
+	0x8c,0xc4,0xa8,0xfc, 0x81,0xcf,0xa6,0xf5, 0x96,0xd2,0xb4,0xee, 0x9b,0xd9,0xba,0xe7,
+	0xbb,0x7b,0xdb,0x3b, 0xb6,0x70,0xd5,0x32, 0xa1,0x6d,0xc7,0x29, 0xac,0x66,0xc9,0x20,
+	0x8f,0x57,0xe3,0x1f, 0x82,0x5c,0xed,0x16, 0x95,0x41,0xff,0x0d, 0x98,0x4a,0xf1,0x04,
+	0xd3,0x23,0xab,0x73, 0xde,0x28,0xa5,0x7a, 0xc9,0x35,0xb7,0x61, 0xc4,0x3e,0xb9,0x68,
+	0xe7,0x0f,0x93,0x57, 0xea,0x04,0x9d,0x5e, 0xfd,0x19,0x8f,0x45, 0xf0,0x12,0x81,0x4c,
+	0x6b,0xcb,0x3b,0xab, 0x66,0xc0,0x35,0xa2, 0x71,0xdd,0x27,0xb9, 0x7c,0xd6,0x29,0xb0,
+	0x5f,0xe7,0x03,0x8f, 0x52,0xec,0x0d,0x86, 0x45,0xf1,0x1f,0x9d, 0x48,0xfa,0x11,0x94,
+	0x03,0x93,0x4b,0xe3, 0x0e,0x98,0x45,0xea, 0x19,0x85,0x57,0xf1, 0x14,0x8e,0x59,0xf8,
+	0x37,0xbf,0x73,0xc7, 0x3a,0xb4,0x7d,0xce, 0x2d,0xa9,0x6f,0xd5, 0x20,0xa2,0x61,0xdc,
+	0x6d,0xf6,0xad,0x76, 0x60,0xfd,0xa3,0x7f, 0x77,0xe0,0xb1,0x64, 0x7a,0xeb,0xbf,0x6d,
+	0x59,0xda,0x95,0x52, 0x54,0xd1,0x9b,0x5b, 0x43,0xcc,0x89,0x40, 0x4e,0xc7,0x87,0x49,
+	0x05,0xae,0xdd,0x3e, 0x08,0xa5,0xd3,0x37, 0x1f,0xb8,0xc1,0x2c, 0x12,0xb3,0xcf,0x25,
+	0x31,0x82,0xe5,0x1a, 0x3c,0x89,0xeb,0x13, 0x2b,0x94,0xf9,0x08, 0x26,0x9f,0xf7,0x01,
+	0xbd,0x46,0x4d,0xe6, 0xb0,0x4d,0x43,0xef, 0xa7,0x50,0x51,0xf4, 0xaa,0x5b,0x5f,0xfd,
+	0x89,0x6a,0x75,0xc2, 0x84,0x61,0x7b,0xcb, 0x93,0x7c,0x69,0xd0, 0x9e,0x77,0x67,0xd9,
+	0xd5,0x1e,0x3d,0xae, 0xd8,0x15,0x33,0xa7, 0xcf,0x08,0x21,0xbc, 0xc2,0x03,0x2f,0xb5,
+	0xe1,0x32,0x05,0x8a, 0xec,0x39,0x0b,0x83, 0xfb,0x24,0x19,0x98, 0xf6,0x2f,0x17,0x91,
+	0xd6,0x8d,0x76,0x4d, 0xdb,0x86,0x78,0x44, 0xcc,0x9b,0x6a,0x5f, 0xc1,0x90,0x64,0x56,
+	0xe2,0xa1,0x4e,0x69, 0xef,0xaa,0x40,0x60, 0xf8,0xb7,0x52,0x7b, 0xf5,0xbc,0x5c,0x72,
+	0xbe,0xd5,0x06,0x05, 0xb3,0xde,0x08,0x0c, 0xa4,0xc3,0x1a,0x17, 0xa9,0xc8,0x14,0x1e,
+	0x8a,0xf9,0x3e,0x21, 0x87,0xf2,0x30,0x28, 0x90,0xef,0x22,0x33, 0x9d,0xe4,0x2c,0x3a,
+	0x06,0x3d,0x96,0xdd, 0x0b,0x36,0x98,0xd4, 0x1c,0x2b,0x8a,0xcf, 0x11,0x20,0x84,0xc6,
+	0x32,0x11,0xae,0xf9, 0x3f,0x1a,0xa0,0xf0, 0x28,0x07,0xb2,0xeb, 0x25,0x0c,0xbc,0xe2,
+	0x6e,0x65,0xe6,0x95, 0x63,0x6e,0xe8,0x9c, 0x74,0x73,0xfa,0x87, 0x79,0x78,0xf4,0x8e,
+	0x5a,0x49,0xde,0xb1, 0x57,0x42,0xd0,0xb8, 0x40,0x5f,0xc2,0xa3, 0x4d,0x54,0xcc,0xaa,
+	0xda,0xf7,0x41,0xec, 0xd7,0xfc,0x4f,0xe5, 0xc0,0xe1,0x5d,0xfe, 0xcd,0xea,0x53,0xf7,
+	0xee,0xdb,0x79,0xc8, 0xe3,0xd0,0x77,0xc1, 0xf4,0xcd,0x65,0xda, 0xf9,0xc6,0x6b,0xd3,
+	0xb2,0xaf,0x31,0xa4, 0xbf,0xa4,0x3f,0xad, 0xa8,0xb9,0x2d,0xb6, 0xa5,0xb2,0x23,0xbf,
+	0x86,0x83,0x09,0x80, 0x8b,0x88,0x07,0x89, 0x9c,0x95,0x15,0x92, 0x91,0x9e,0x1b,0x9b,
+	0x0a,0x47,0xa1,0x7c, 0x07,0x4c,0xaf,0x75, 0x10,0x51,0xbd,0x6e, 0x1d,0x5a,0xb3,0x67,
+	0x3e,0x6b,0x99,0x58, 0x33,0x60,0x97,0x51, 0x24,0x7d,0x85,0x4a, 0x29,0x76,0x8b,0x43,
+	0x62,0x1f,0xd1,0x34, 0x6f,0x14,0xdf,0x3d, 0x78,0x09,0xcd,0x26, 0x75,0x02,0xc3,0x2f,
+	0x56,0x33,0xe9,0x10, 0x5b,0x38,0xe7,0x19, 0x4c,0x25,0xf5,0x02, 0x41,0x2e,0xfb,0x0b,
+	0x61,0x8c,0x9a,0xd7, 0x6c,0x87,0x94,0xde, 0x7b,0x9a,0x86,0xc5, 0x76,0x91,0x88,0xcc,
+	0x55,0xa0,0xa2,0xf3, 0x58,0xab,0xac,0xfa, 0x4f,0xb6,0xbe,0xe1, 0x42,0xbd,0xb0,0xe8,
+	0x09,0xd4,0xea,0x9f, 0x04,0xdf,0xe4,0x96, 0x13,0xc2,0xf6,0x8d, 0x1e,0xc9,0xf8,0x84,
+	0x3d,0xf8,0xd2,0xbb, 0x30,0xf3,0xdc,0xb2, 0x27,0xee,0xce,0xa9, 0x2a,0xe5,0xc0,0xa0,
+	0xb1,0x3c,0x7a,0x47, 0xbc,0x37,0x74,0x4e, 0xab,0x2a,0x66,0x55, 0xa6,0x21,0x68,0x5c,
+	0x85,0x10,0x42,0x63, 0x88,0x1b,0x4c,0x6a, 0x9f,0x06,0x5e,0x71, 0x92,0x0d,0x50,0x78,
+	0xd9,0x64,0x0a,0x0f, 0xd4,0x6f,0x04,0x06, 0xc3,0x72,0x16,0x1d, 0xce,0x79,0x18,0x14,
+	0xed,0x48,0x32,0x2b, 0xe0,0x43,0x3c,0x22, 0xf7,0x5e,0x2e,0x39, 0xfa,0x55,0x20,0x30,
+	0xb7,0x01,0xec,0x9a, 0xba,0x0a,0xe2,0x93, 0xad,0x17,0xf0,0x88, 0xa0,0x1c,0xfe,0x81,
+	0x83,0x2d,0xd4,0xbe, 0x8e,0x26,0xda,0xb7, 0x99,0x3b,0xc8,0xac, 0x94,0x30,0xc6,0xa5,
+	0xdf,0x59,0x9c,0xd2, 0xd2,0x52,0x92,0xdb, 0xc5,0x4f,0x80,0xc0, 0xc8,0x44,0x8e,0xc9,
+	0xeb,0x75,0xa4,0xf6, 0xe6,0x7e,0xaa,0xff, 0xf1,0x63,0xb8,0xe4, 0xfc,0x68,0xb6,0xed,
+	0x67,0xb1,0x0c,0x0a, 0x6a,0xba,0x02,0x03, 0x7d,0xa7,0x10,0x18, 0x70,0xac,0x1e,0x11,
+	0x53,0x9d,0x34,0x2e, 0x5e,0x96,0x3a,0x27, 0x49,0x8b,0x28,0x3c, 0x44,0x80,0x26,0x35,
+	0x0f,0xe9,0x7c,0x42, 0x02,0xe2,0x72,0x4b, 0x15,0xff,0x60,0x50, 0x18,0xf4,0x6e,0x59,
+	0x3b,0xc5,0x44,0x66, 0x36,0xce,0x4a,0x6f, 0x21,0xd3,0x58,0x74, 0x2c,0xd8,0x56,0x7d,
+	0x0c,0x7a,0x37,0xa1, 0x01,0x71,0x39,0xa8, 0x16,0x6c,0x2b,0xb3, 0x1b,0x67,0x25,0xba,
+	0x38,0x56,0x0f,0x85, 0x35,0x5d,0x01,0x8c, 0x22,0x40,0x13,0x97, 0x2f,0x4b,0x1d,0x9e,
+	0x64,0x22,0x47,0xe9, 0x69,0x29,0x49,0xe0, 0x7e,0x34,0x5b,0xfb, 0x73,0x3f,0x55,0xf2,
+	0x50,0x0e,0x7f,0xcd, 0x5d,0x05,0x71,0xc4, 0x4a,0x18,0x63,0xdf, 0x47,0x13,0x6d,0xd6,
+	0xdc,0xca,0xd7,0x31, 0xd1,0xc1,0xd9,0x38, 0xc6,0xdc,0xcb,0x23, 0xcb,0xd7,0xc5,0x2a,
+	0xe8,0xe6,0xef,0x15, 0xe5,0xed,0xe1,0x1c, 0xf2,0xf0,0xf3,0x07, 0xff,0xfb,0xfd,0x0e,
+	0xb4,0x92,0xa7,0x79, 0xb9,0x99,0xa9,0x70, 0xae,0x84,0xbb,0x6b, 0xa3,0x8f,0xb5,0x62,
+	0x80,0xbe,0x9f,0x5d, 0x8d,0xb5,0x91,0x54, 0x9a,0xa8,0x83,0x4f, 0x97,0xa3,0x8d,0x46
+};
+
+static RD_UINT8 U4[256][4]=
+{
+	0x00,0x00,0x00,0x00, 0x09,0x0d,0x0b,0x0e, 0x12,0x1a,0x16,0x1c, 0x1b,0x17,0x1d,0x12,
+	0x24,0x34,0x2c,0x38, 0x2d,0x39,0x27,0x36, 0x36,0x2e,0x3a,0x24, 0x3f,0x23,0x31,0x2a,
+	0x48,0x68,0x58,0x70, 0x41,0x65,0x53,0x7e, 0x5a,0x72,0x4e,0x6c, 0x53,0x7f,0x45,0x62,
+	0x6c,0x5c,0x74,0x48, 0x65,0x51,0x7f,0x46, 0x7e,0x46,0x62,0x54, 0x77,0x4b,0x69,0x5a,
+	0x90,0xd0,0xb0,0xe0, 0x99,0xdd,0xbb,0xee, 0x82,0xca,0xa6,0xfc, 0x8b,0xc7,0xad,0xf2,
+	0xb4,0xe4,0x9c,0xd8, 0xbd,0xe9,0x97,0xd6, 0xa6,0xfe,0x8a,0xc4, 0xaf,0xf3,0x81,0xca,
+	0xd8,0xb8,0xe8,0x90, 0xd1,0xb5,0xe3,0x9e, 0xca,0xa2,0xfe,0x8c, 0xc3,0xaf,0xf5,0x82,
+	0xfc,0x8c,0xc4,0xa8, 0xf5,0x81,0xcf,0xa6, 0xee,0x96,0xd2,0xb4, 0xe7,0x9b,0xd9,0xba,
+	0x3b,0xbb,0x7b,0xdb, 0x32,0xb6,0x70,0xd5, 0x29,0xa1,0x6d,0xc7, 0x20,0xac,0x66,0xc9,
+	0x1f,0x8f,0x57,0xe3, 0x16,0x82,0x5c,0xed, 0x0d,0x95,0x41,0xff, 0x04,0x98,0x4a,0xf1,
+	0x73,0xd3,0x23,0xab, 0x7a,0xde,0x28,0xa5, 0x61,0xc9,0x35,0xb7, 0x68,0xc4,0x3e,0xb9,
+	0x57,0xe7,0x0f,0x93, 0x5e,0xea,0x04,0x9d, 0x45,0xfd,0x19,0x8f, 0x4c,0xf0,0x12,0x81,
+	0xab,0x6b,0xcb,0x3b, 0xa2,0x66,0xc0,0x35, 0xb9,0x71,0xdd,0x27, 0xb0,0x7c,0xd6,0x29,
+	0x8f,0x5f,0xe7,0x03, 0x86,0x52,0xec,0x0d, 0x9d,0x45,0xf1,0x1f, 0x94,0x48,0xfa,0x11,
+	0xe3,0x03,0x93,0x4b, 0xea,0x0e,0x98,0x45, 0xf1,0x19,0x85,0x57, 0xf8,0x14,0x8e,0x59,
+	0xc7,0x37,0xbf,0x73, 0xce,0x3a,0xb4,0x7d, 0xd5,0x2d,0xa9,0x6f, 0xdc,0x20,0xa2,0x61,
+	0x76,0x6d,0xf6,0xad, 0x7f,0x60,0xfd,0xa3, 0x64,0x77,0xe0,0xb1, 0x6d,0x7a,0xeb,0xbf,
+	0x52,0x59,0xda,0x95, 0x5b,0x54,0xd1,0x9b, 0x40,0x43,0xcc,0x89, 0x49,0x4e,0xc7,0x87,
+	0x3e,0x05,0xae,0xdd, 0x37,0x08,0xa5,0xd3, 0x2c,0x1f,0xb8,0xc1, 0x25,0x12,0xb3,0xcf,
+	0x1a,0x31,0x82,0xe5, 0x13,0x3c,0x89,0xeb, 0x08,0x2b,0x94,0xf9, 0x01,0x26,0x9f,0xf7,
+	0xe6,0xbd,0x46,0x4d, 0xef,0xb0,0x4d,0x43, 0xf4,0xa7,0x50,0x51, 0xfd,0xaa,0x5b,0x5f,
+	0xc2,0x89,0x6a,0x75, 0xcb,0x84,0x61,0x7b, 0xd0,0x93,0x7c,0x69, 0xd9,0x9e,0x77,0x67,
+	0xae,0xd5,0x1e,0x3d, 0xa7,0xd8,0x15,0x33, 0xbc,0xcf,0x08,0x21, 0xb5,0xc2,0x03,0x2f,
+	0x8a,0xe1,0x32,0x05, 0x83,0xec,0x39,0x0b, 0x98,0xfb,0x24,0x19, 0x91,0xf6,0x2f,0x17,
+	0x4d,0xd6,0x8d,0x76, 0x44,0xdb,0x86,0x78, 0x5f,0xcc,0x9b,0x6a, 0x56,0xc1,0x90,0x64,
+	0x69,0xe2,0xa1,0x4e, 0x60,0xef,0xaa,0x40, 0x7b,0xf8,0xb7,0x52, 0x72,0xf5,0xbc,0x5c,
+	0x05,0xbe,0xd5,0x06, 0x0c,0xb3,0xde,0x08, 0x17,0xa4,0xc3,0x1a, 0x1e,0xa9,0xc8,0x14,
+	0x21,0x8a,0xf9,0x3e, 0x28,0x87,0xf2,0x30, 0x33,0x90,0xef,0x22, 0x3a,0x9d,0xe4,0x2c,
+	0xdd,0x06,0x3d,0x96, 0xd4,0x0b,0x36,0x98, 0xcf,0x1c,0x2b,0x8a, 0xc6,0x11,0x20,0x84,
+	0xf9,0x32,0x11,0xae, 0xf0,0x3f,0x1a,0xa0, 0xeb,0x28,0x07,0xb2, 0xe2,0x25,0x0c,0xbc,
+	0x95,0x6e,0x65,0xe6, 0x9c,0x63,0x6e,0xe8, 0x87,0x74,0x73,0xfa, 0x8e,0x79,0x78,0xf4,
+	0xb1,0x5a,0x49,0xde, 0xb8,0x57,0x42,0xd0, 0xa3,0x40,0x5f,0xc2, 0xaa,0x4d,0x54,0xcc,
+	0xec,0xda,0xf7,0x41, 0xe5,0xd7,0xfc,0x4f, 0xfe,0xc0,0xe1,0x5d, 0xf7,0xcd,0xea,0x53,
+	0xc8,0xee,0xdb,0x79, 0xc1,0xe3,0xd0,0x77, 0xda,0xf4,0xcd,0x65, 0xd3,0xf9,0xc6,0x6b,
+	0xa4,0xb2,0xaf,0x31, 0xad,0xbf,0xa4,0x3f, 0xb6,0xa8,0xb9,0x2d, 0xbf,0xa5,0xb2,0x23,
+	0x80,0x86,0x83,0x09, 0x89,0x8b,0x88,0x07, 0x92,0x9c,0x95,0x15, 0x9b,0x91,0x9e,0x1b,
+	0x7c,0x0a,0x47,0xa1, 0x75,0x07,0x4c,0xaf, 0x6e,0x10,0x51,0xbd, 0x67,0x1d,0x5a,0xb3,
+	0x58,0x3e,0x6b,0x99, 0x51,0x33,0x60,0x97, 0x4a,0x24,0x7d,0x85, 0x43,0x29,0x76,0x8b,
+	0x34,0x62,0x1f,0xd1, 0x3d,0x6f,0x14,0xdf, 0x26,0x78,0x09,0xcd, 0x2f,0x75,0x02,0xc3,
+	0x10,0x56,0x33,0xe9, 0x19,0x5b,0x38,0xe7, 0x02,0x4c,0x25,0xf5, 0x0b,0x41,0x2e,0xfb,
+	0xd7,0x61,0x8c,0x9a, 0xde,0x6c,0x87,0x94, 0xc5,0x7b,0x9a,0x86, 0xcc,0x76,0x91,0x88,
+	0xf3,0x55,0xa0,0xa2, 0xfa,0x58,0xab,0xac, 0xe1,0x4f,0xb6,0xbe, 0xe8,0x42,0xbd,0xb0,
+	0x9f,0x09,0xd4,0xea, 0x96,0x04,0xdf,0xe4, 0x8d,0x13,0xc2,0xf6, 0x84,0x1e,0xc9,0xf8,
+	0xbb,0x3d,0xf8,0xd2, 0xb2,0x30,0xf3,0xdc, 0xa9,0x27,0xee,0xce, 0xa0,0x2a,0xe5,0xc0,
+	0x47,0xb1,0x3c,0x7a, 0x4e,0xbc,0x37,0x74, 0x55,0xab,0x2a,0x66, 0x5c,0xa6,0x21,0x68,
+	0x63,0x85,0x10,0x42, 0x6a,0x88,0x1b,0x4c, 0x71,0x9f,0x06,0x5e, 0x78,0x92,0x0d,0x50,
+	0x0f,0xd9,0x64,0x0a, 0x06,0xd4,0x6f,0x04, 0x1d,0xc3,0x72,0x16, 0x14,0xce,0x79,0x18,
+	0x2b,0xed,0x48,0x32, 0x22,0xe0,0x43,0x3c, 0x39,0xf7,0x5e,0x2e, 0x30,0xfa,0x55,0x20,
+	0x9a,0xb7,0x01,0xec, 0x93,0xba,0x0a,0xe2, 0x88,0xad,0x17,0xf0, 0x81,0xa0,0x1c,0xfe,
+	0xbe,0x83,0x2d,0xd4, 0xb7,0x8e,0x26,0xda, 0xac,0x99,0x3b,0xc8, 0xa5,0x94,0x30,0xc6,
+	0xd2,0xdf,0x59,0x9c, 0xdb,0xd2,0x52,0x92, 0xc0,0xc5,0x4f,0x80, 0xc9,0xc8,0x44,0x8e,
+	0xf6,0xeb,0x75,0xa4, 0xff,0xe6,0x7e,0xaa, 0xe4,0xf1,0x63,0xb8, 0xed,0xfc,0x68,0xb6,
+	0x0a,0x67,0xb1,0x0c, 0x03,0x6a,0xba,0x02, 0x18,0x7d,0xa7,0x10, 0x11,0x70,0xac,0x1e,
+	0x2e,0x53,0x9d,0x34, 0x27,0x5e,0x96,0x3a, 0x3c,0x49,0x8b,0x28, 0x35,0x44,0x80,0x26,
+	0x42,0x0f,0xe9,0x7c, 0x4b,0x02,0xe2,0x72, 0x50,0x15,0xff,0x60, 0x59,0x18,0xf4,0x6e,
+	0x66,0x3b,0xc5,0x44, 0x6f,0x36,0xce,0x4a, 0x74,0x21,0xd3,0x58, 0x7d,0x2c,0xd8,0x56,
+	0xa1,0x0c,0x7a,0x37, 0xa8,0x01,0x71,0x39, 0xb3,0x16,0x6c,0x2b, 0xba,0x1b,0x67,0x25,
+	0x85,0x38,0x56,0x0f, 0x8c,0x35,0x5d,0x01, 0x97,0x22,0x40,0x13, 0x9e,0x2f,0x4b,0x1d,
+	0xe9,0x64,0x22,0x47, 0xe0,0x69,0x29,0x49, 0xfb,0x7e,0x34,0x5b, 0xf2,0x73,0x3f,0x55,
+	0xcd,0x50,0x0e,0x7f, 0xc4,0x5d,0x05,0x71, 0xdf,0x4a,0x18,0x63, 0xd6,0x47,0x13,0x6d,
+	0x31,0xdc,0xca,0xd7, 0x38,0xd1,0xc1,0xd9, 0x23,0xc6,0xdc,0xcb, 0x2a,0xcb,0xd7,0xc5,
+	0x15,0xe8,0xe6,0xef, 0x1c,0xe5,0xed,0xe1, 0x07,0xf2,0xf0,0xf3, 0x0e,0xff,0xfb,0xfd,
+	0x79,0xb4,0x92,0xa7, 0x70,0xb9,0x99,0xa9, 0x6b,0xae,0x84,0xbb, 0x62,0xa3,0x8f,0xb5,
+	0x5d,0x80,0xbe,0x9f, 0x54,0x8d,0xb5,0x91, 0x4f,0x9a,0xa8,0x83, 0x46,0x97,0xa3,0x8d
+};
+
+static RD_UINT32 rcon[30]=
+{
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
+	0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+	0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
+	0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
+	0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// API
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Rijndael::Rijndael()
+{
+	 m_state = Invalid;
+}
+
+Rijndael::~Rijndael()
+{
+	// nothing here
+}
+
+int Rijndael::init(Mode mode,Direction dir,const RD_UINT8 * key,KeyLength keyLen,RD_UINT8 * initVector)
+{
+	// Not initialized yet
+	m_state = Invalid;
+
+	// Check the mode
+	if((mode != CBC) && (mode != ECB) && (mode != CFB1)) return RIJNDAEL_UNSUPPORTED_MODE;
+	m_mode = mode;
+
+	// And the direction
+	if((dir != Encrypt) && (dir != Decrypt)) return RIJNDAEL_UNSUPPORTED_DIRECTION;
+	m_direction = dir;
+
+	// Allow to set an init vector
+	if(initVector)
+	{
+		// specified init vector
+		for(int i = 0;i < MAX_IV_SIZE;i++)
+		{
+			m_initVector[i] = initVector[i];
+		}
+	} else {
+		// zero init vector
+		for(int i = 0;i < MAX_IV_SIZE;i++)
+		{
+			m_initVector[i] = 0;
+		}
+	}
+
+	RD_UINT32 uKeyLenInBytes;
+
+	// And check the key length
+	switch(keyLen)
+	{
+		case Key16Bytes:
+			uKeyLenInBytes = 16;
+			m_uRounds = 10;
+		break;
+		case Key24Bytes:
+			uKeyLenInBytes = 24;
+			m_uRounds = 12;
+		break;
+		case Key32Bytes:
+			uKeyLenInBytes = 32;
+			m_uRounds = 14;
+		break;
+		default:
+			return RIJNDAEL_UNSUPPORTED_KEY_LENGTH;
+		break;
+	}
+	// The number of rounds is calculated as
+	// m_uRounds = (m_uKeyLenInBits / 32) + 6;
+
+	if(!key) return RIJNDAEL_BAD_KEY;
+
+	RD_UINT8 keyMatrix[_MAX_KEY_COLUMNS][4];
+
+	for(RD_UINT32 i = 0;i < uKeyLenInBytes;i++)keyMatrix[i >> 2][i & 3] = key[i];
+
+	keySched(keyMatrix);
+
+	if(m_direction == Decrypt)keyEncToDec();
+
+	m_state = Valid;
+
+	return RIJNDAEL_SUCCESS;
+}
+
+int Rijndael::blockEncrypt(const RD_UINT8 *input,int inputLen,RD_UINT8 *outBuffer)
+{
+	int i, k, numBlocks;
+	RD_UINT8 block[16], iv[4][4];
+
+	if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED;
+	if(m_direction != Encrypt) return RIJNDAEL_BAD_DIRECTION;
+
+	if(input == 0 || inputLen <= 0) return 0;
+
+	numBlocks = inputLen/128;
+
+	switch(m_mode){
+		case ECB:
+			for(i = numBlocks;i > 0;i--)
+			{
+				encrypt(input,outBuffer);
+				input += 16;
+				outBuffer += 16;
+			}
+		break;
+		case CBC:
+			((RD_UINT32*)block)[0] = ((RD_UINT32*)m_initVector)[0] ^ ((RD_UINT32*)input)[0];
+			((RD_UINT32*)block)[1] = ((RD_UINT32*)m_initVector)[1] ^ ((RD_UINT32*)input)[1];
+			((RD_UINT32*)block)[2] = ((RD_UINT32*)m_initVector)[2] ^ ((RD_UINT32*)input)[2];
+			((RD_UINT32*)block)[3] = ((RD_UINT32*)m_initVector)[3] ^ ((RD_UINT32*)input)[3];
+			encrypt(block,outBuffer);
+			input += 16;
+			for(i = numBlocks - 1;i > 0;i--)
+			{
+				((RD_UINT32*)block)[0] = ((RD_UINT32*)outBuffer)[0] ^ ((RD_UINT32*)input)[0];
+				((RD_UINT32*)block)[1] = ((RD_UINT32*)outBuffer)[1] ^ ((RD_UINT32*)input)[1];
+				((RD_UINT32*)block)[2] = ((RD_UINT32*)outBuffer)[2] ^ ((RD_UINT32*)input)[2];
+				((RD_UINT32*)block)[3] = ((RD_UINT32*)outBuffer)[3] ^ ((RD_UINT32*)input)[3];
+				outBuffer += 16;
+				encrypt(block,outBuffer);
+				input += 16;
+			}
+		break;
+		case CFB1:
+#if STRICT_ALIGN
+			memcpy(iv,m_initVector,16);
+#else  /* !STRICT_ALIGN */
+			*((RD_UINT32*)iv[0]) = *((RD_UINT32*)(m_initVector   ));
+			*((RD_UINT32*)iv[1]) = *((RD_UINT32*)(m_initVector + 4));
+			*((RD_UINT32*)iv[2]) = *((RD_UINT32*)(m_initVector + 8));
+			*((RD_UINT32*)iv[3]) = *((RD_UINT32*)(m_initVector +12));
+#endif /* ?STRICT_ALIGN */
+			for(i = numBlocks; i > 0; i--)
+			{
+				for(k = 0; k < 128; k++)
+				{
+					*((RD_UINT32*) block    ) = *((RD_UINT32*)iv[0]);
+					*((RD_UINT32*)(block+ 4)) = *((RD_UINT32*)iv[1]);
+					*((RD_UINT32*)(block+ 8)) = *((RD_UINT32*)iv[2]);
+					*((RD_UINT32*)(block+12)) = *((RD_UINT32*)iv[3]);
+					encrypt(block,block);
+					outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+					iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+					iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+					iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+					iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+					iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+					iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+					iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+					iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+					iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+					iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+					iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+					iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+					iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+					iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+					iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+					iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1;
+				}
+			}
+		break;
+		default:
+			return -1;
+		break;
+	}
+
+	return 128 * numBlocks;
+}
+
+int Rijndael::padEncrypt(const RD_UINT8 *input, int inputOctets, RD_UINT8 *outBuffer)
+{
+	int i, numBlocks, padLen;
+	RD_UINT8 block[16], *iv;
+
+	if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED;
+	if(m_direction != Encrypt) return RIJNDAEL_NOT_INITIALIZED;
+
+	if((input == 0) || (inputOctets <= 0)) return 0;
+
+	numBlocks = inputOctets/16;
+
+	switch(m_mode)
+	{
+		case ECB:
+			for(i = numBlocks; i > 0; i--)
+			{
+				encrypt(input, outBuffer);
+				input += 16;
+				outBuffer += 16;
+			}
+			padLen = 16 - (inputOctets - 16*numBlocks);
+//			assert(padLen > 0 && padLen <= 16);
+			memcpy(block, input, 16 - padLen);
+			memset(block + 16 - padLen, padLen, padLen);
+			encrypt(block,outBuffer);
+		break;
+		case CBC:
+			iv = m_initVector;
+			for(i = numBlocks; i > 0; i--)
+			{
+				((RD_UINT32*)block)[0] = ((RD_UINT32*)input)[0] ^ ((RD_UINT32*)iv)[0];
+				((RD_UINT32*)block)[1] = ((RD_UINT32*)input)[1] ^ ((RD_UINT32*)iv)[1];
+				((RD_UINT32*)block)[2] = ((RD_UINT32*)input)[2] ^ ((RD_UINT32*)iv)[2];
+				((RD_UINT32*)block)[3] = ((RD_UINT32*)input)[3] ^ ((RD_UINT32*)iv)[3];
+				encrypt(block, outBuffer);
+				iv = outBuffer;
+				input += 16;
+				outBuffer += 16;
+			}
+			padLen = 16 - (inputOctets - 16*numBlocks);
+//			assert(padLen > 0 && padLen <= 16); // DO SOMETHING HERE ?
+			for (i = 0; i < 16 - padLen; i++) {
+				block[i] = input[i] ^ iv[i];
+			}
+			for (i = 16 - padLen; i < 16; i++) {
+				block[i] = (RD_UINT8)padLen ^ iv[i];
+			}
+			encrypt(block,outBuffer);
+		break;
+		default:
+			return -1;
+		break;
+	}
+
+	return 16*(numBlocks + 1);
+}
+
+int Rijndael::blockDecrypt(const RD_UINT8 *input, int inputLen, RD_UINT8 *outBuffer)
+{
+	int i, k, numBlocks;
+	RD_UINT8 block[16], iv[4][4];
+
+	if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED;
+	if((m_mode != CFB1) && (m_direction == Encrypt)) return RIJNDAEL_BAD_DIRECTION;
+
+	if((input == 0) || (inputLen <= 0)) return 0;
+
+	numBlocks = inputLen/128;
+
+	switch(m_mode)
+	{
+		case ECB:
+			for (i = numBlocks; i > 0; i--)
+			{
+				decrypt(input,outBuffer);
+				input += 16;
+				outBuffer += 16;
+			}
+		break;
+		case CBC:
+#if STRICT_ALIGN
+			memcpy(iv,m_initVector,16);
+#else
+			*((RD_UINT32*)iv[0]) = *((RD_UINT32*)(m_initVector  ));
+			*((RD_UINT32*)iv[1]) = *((RD_UINT32*)(m_initVector+ 4));
+			*((RD_UINT32*)iv[2]) = *((RD_UINT32*)(m_initVector+ 8));
+			*((RD_UINT32*)iv[3]) = *((RD_UINT32*)(m_initVector+12));
+#endif
+			for (i = numBlocks; i > 0; i--)
+			{
+				decrypt(input, block);
+				((RD_UINT32*)block)[0] ^= *((RD_UINT32*)iv[0]);
+				((RD_UINT32*)block)[1] ^= *((RD_UINT32*)iv[1]);
+				((RD_UINT32*)block)[2] ^= *((RD_UINT32*)iv[2]);
+				((RD_UINT32*)block)[3] ^= *((RD_UINT32*)iv[3]);
+#if STRICT_ALIGN
+				memcpy(iv, input, 16);
+				memcpy(outBuf, block, 16);
+#else
+				*((RD_UINT32*)iv[0]) = ((RD_UINT32*)input)[0]; ((RD_UINT32*)outBuffer)[0] = ((RD_UINT32*)block)[0];
+				*((RD_UINT32*)iv[1]) = ((RD_UINT32*)input)[1]; ((RD_UINT32*)outBuffer)[1] = ((RD_UINT32*)block)[1];
+				*((RD_UINT32*)iv[2]) = ((RD_UINT32*)input)[2]; ((RD_UINT32*)outBuffer)[2] = ((RD_UINT32*)block)[2];
+				*((RD_UINT32*)iv[3]) = ((RD_UINT32*)input)[3]; ((RD_UINT32*)outBuffer)[3] = ((RD_UINT32*)block)[3];
+#endif
+				input += 16;
+				outBuffer += 16;
+			}
+			break;
+		case CFB1:
+#if STRICT_ALIGN
+			memcpy(iv, m_initVector, 16);
+#else
+			*((RD_UINT32*)iv[0]) = *((RD_UINT32*)(m_initVector));
+			*((RD_UINT32*)iv[1]) = *((RD_UINT32*)(m_initVector+ 4));
+			*((RD_UINT32*)iv[2]) = *((RD_UINT32*)(m_initVector+ 8));
+			*((RD_UINT32*)iv[3]) = *((RD_UINT32*)(m_initVector+12));
+#endif
+			for(i = numBlocks; i > 0; i--)
+			{
+				for(k = 0; k < 128; k++)
+				{
+					*((RD_UINT32*) block    ) = *((RD_UINT32*)iv[0]);
+					*((RD_UINT32*)(block+ 4)) = *((RD_UINT32*)iv[1]);
+					*((RD_UINT32*)(block+ 8)) = *((RD_UINT32*)iv[2]);
+					*((RD_UINT32*)(block+12)) = *((RD_UINT32*)iv[3]);
+					encrypt(block, block);
+					iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+					iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+					iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+					iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+					iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+					iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+					iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+					iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+					iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+					iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+					iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+					iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+					iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+					iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+					iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+					iv[3][3] = (iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1;
+					outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+				}
+			}
+		break;
+		default:
+			return -1;
+		break;
+	}
+
+	return 128*numBlocks;
+}
+
+int Rijndael::padDecrypt(const RD_UINT8 *input, int inputOctets, RD_UINT8 *outBuffer)
+{
+	int i, numBlocks, padLen;
+	RD_UINT8 block[16];
+	RD_UINT32 iv[4];
+
+	if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED;
+	if(m_direction != Decrypt) return RIJNDAEL_BAD_DIRECTION;
+
+	if(input == 0 || inputOctets <= 0) return 0;
+
+	if((inputOctets % 16) != 0) return RIJNDAEL_CORRUPTED_DATA;
+
+	numBlocks = inputOctets/16;
+
+	switch(m_mode){
+		case ECB:
+			for (i = numBlocks - 1; i > 0; i--)
+			{
+				decrypt(input, outBuffer);
+				input += 16;
+				outBuffer += 16;
+			}
+
+			decrypt(input, block);
+			padLen = block[15];
+			if ((padLen <= 0) || (padLen > 16)) return RIJNDAEL_CORRUPTED_DATA;
+			for(i = 16 - padLen; i < 16; i++)
+			{
+				if(block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA;
+			}
+			memcpy(outBuffer, block, 16 - padLen);
+		break;
+		case CBC:
+			memcpy(iv, m_initVector, 16);
+			/* all blocks but last */
+			for (i = numBlocks - 1; i > 0; i--)
+			{
+				decrypt(input, block);
+				((RD_UINT32*)block)[0] ^= iv[0];
+				((RD_UINT32*)block)[1] ^= iv[1];
+				((RD_UINT32*)block)[2] ^= iv[2];
+				((RD_UINT32*)block)[3] ^= iv[3];
+				memcpy(iv, input, 16);
+				memcpy(outBuffer, block, 16);
+				input += 16;
+				outBuffer += 16;
+			}
+			/* last block */
+			decrypt(input, block);
+			((RD_UINT32*)block)[0] ^= iv[0];
+			((RD_UINT32*)block)[1] ^= iv[1];
+			((RD_UINT32*)block)[2] ^= iv[2];
+			((RD_UINT32*)block)[3] ^= iv[3];
+			padLen = block[15];
+			if((padLen <= 0) || (padLen > 16)) return RIJNDAEL_CORRUPTED_DATA;
+			for(i = 16 - padLen; i < 16; i++)
+			{
+				if(block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA;
+			}
+			memcpy(outBuffer, block, 16 - padLen);
+			break;
+
+		default:
+			return -1;
+		break;
+	}
+
+	return 16*numBlocks - padLen;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ALGORITHM
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void Rijndael::keySched(RD_UINT8 key[_MAX_KEY_COLUMNS][4])
+{
+	int j,rconpointer = 0;
+
+	// Calculate the necessary round keys
+	// The number of calculations depends on keyBits and blockBits
+	int uKeyColumns = m_uRounds - 6;
+
+	RD_UINT8 tempKey[_MAX_KEY_COLUMNS][4];
+
+	// Copy the input key to the temporary key matrix
+
+	for(j = 0;j < uKeyColumns;j++)
+	{
+		*((RD_UINT32*)(tempKey[j])) = *((RD_UINT32*)(key[j]));
+	}
+
+	int r = 0;
+	int t = 0;
+
+	// copy values into round key array
+	for(j = 0;(j < uKeyColumns) && (r <= (int)m_uRounds); )
+	{
+		for(;(j < uKeyColumns) && (t < 4); j++, t++)
+		{
+			*((RD_UINT32*)m_expandedKey[r][t]) = *((RD_UINT32*)tempKey[j]);
+		}
+
+
+		if(t == 4)
+		{
+			r++;
+			t = 0;
+		}
+	}
+
+	while(r <= (int)m_uRounds)
+	{
+		tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
+		tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
+		tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
+		tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
+		tempKey[0][0] ^= rcon[rconpointer++];
+
+		if (uKeyColumns != 8)
+		{
+			for(j = 1; j < uKeyColumns; j++)
+			{
+				*((RD_UINT32*)tempKey[j]) ^= *((RD_UINT32*)tempKey[j-1]);
+			}
+		} else {
+			for(j = 1; j < uKeyColumns/2; j++)
+			{
+				*((RD_UINT32*)tempKey[j]) ^= *((RD_UINT32*)tempKey[j-1]);
+			}
+			tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
+			tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
+			tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
+			tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
+			for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
+			{
+				*((RD_UINT32*)tempKey[j]) ^= *((RD_UINT32*)tempKey[j-1]);
+			}
+		}
+		for(j = 0; (j < uKeyColumns) && (r <= (int)m_uRounds); )
+		{
+			for(; (j < uKeyColumns) && (t < 4); j++, t++)
+			{
+				*((RD_UINT32*)m_expandedKey[r][t]) = *((RD_UINT32*)tempKey[j]);
+			}
+			if(t == 4)
+			{
+				r++;
+				t = 0;
+			}
+		}
+	}
+}
+
+void Rijndael::keyEncToDec()
+{
+	int r;
+	RD_UINT8 *w;
+
+	for(r = 1; r < (int)m_uRounds; r++)
+	{
+		w = m_expandedKey[r][0];
+		*((RD_UINT32*)w) = *((RD_UINT32*)U1[w[0]]) ^ *((RD_UINT32*)U2[w[1]]) ^ *((RD_UINT32*)U3[w[2]]) ^ *((RD_UINT32*)U4[w[3]]);
+		w = m_expandedKey[r][1];
+		*((RD_UINT32*)w) = *((RD_UINT32*)U1[w[0]]) ^ *((RD_UINT32*)U2[w[1]]) ^ *((RD_UINT32*)U3[w[2]]) ^ *((RD_UINT32*)U4[w[3]]);
+		w = m_expandedKey[r][2];
+		*((RD_UINT32*)w) = *((RD_UINT32*)U1[w[0]]) ^ *((RD_UINT32*)U2[w[1]]) ^ *((RD_UINT32*)U3[w[2]]) ^ *((RD_UINT32*)U4[w[3]]);
+		w = m_expandedKey[r][3];
+		*((RD_UINT32*)w) = *((RD_UINT32*)U1[w[0]]) ^ *((RD_UINT32*)U2[w[1]]) ^ *((RD_UINT32*)U3[w[2]]) ^ *((RD_UINT32*)U4[w[3]]);
+	}
+}
+
+void Rijndael::encrypt(const RD_UINT8 a[16], RD_UINT8 b[16])
+{
+	int r;
+	RD_UINT8 temp[4][4];
+
+    *((RD_UINT32*)temp[0]) = *((RD_UINT32*)(a   )) ^ *((RD_UINT32*)m_expandedKey[0][0]);
+    *((RD_UINT32*)temp[1]) = *((RD_UINT32*)(a+ 4)) ^ *((RD_UINT32*)m_expandedKey[0][1]);
+    *((RD_UINT32*)temp[2]) = *((RD_UINT32*)(a+ 8)) ^ *((RD_UINT32*)m_expandedKey[0][2]);
+    *((RD_UINT32*)temp[3]) = *((RD_UINT32*)(a+12)) ^ *((RD_UINT32*)m_expandedKey[0][3]);
+    *((RD_UINT32*)(b    )) = *((RD_UINT32*)T1[temp[0][0]])
+						^ *((RD_UINT32*)T2[temp[1][1]])
+						^ *((RD_UINT32*)T3[temp[2][2]])
+						^ *((RD_UINT32*)T4[temp[3][3]]);
+    *((RD_UINT32*)(b + 4)) = *((RD_UINT32*)T1[temp[1][0]])
+						^ *((RD_UINT32*)T2[temp[2][1]])
+						^ *((RD_UINT32*)T3[temp[3][2]])
+						^ *((RD_UINT32*)T4[temp[0][3]]);
+    *((RD_UINT32*)(b + 8)) = *((RD_UINT32*)T1[temp[2][0]])
+						^ *((RD_UINT32*)T2[temp[3][1]])
+						^ *((RD_UINT32*)T3[temp[0][2]])
+						^ *((RD_UINT32*)T4[temp[1][3]]);
+    *((RD_UINT32*)(b +12)) = *((RD_UINT32*)T1[temp[3][0]])
+						^ *((RD_UINT32*)T2[temp[0][1]])
+						^ *((RD_UINT32*)T3[temp[1][2]])
+						^ *((RD_UINT32*)T4[temp[2][3]]);
+	for(r = 1; r < (int)m_uRounds-1; r++)
+	{
+		*((RD_UINT32*)temp[0]) = *((RD_UINT32*)(b   )) ^ *((RD_UINT32*)m_expandedKey[r][0]);
+		*((RD_UINT32*)temp[1]) = *((RD_UINT32*)(b+ 4)) ^ *((RD_UINT32*)m_expandedKey[r][1]);
+		*((RD_UINT32*)temp[2]) = *((RD_UINT32*)(b+ 8)) ^ *((RD_UINT32*)m_expandedKey[r][2]);
+		*((RD_UINT32*)temp[3]) = *((RD_UINT32*)(b+12)) ^ *((RD_UINT32*)m_expandedKey[r][3]);
+
+		*((RD_UINT32*)(b    )) = *((RD_UINT32*)T1[temp[0][0]])
+							^ *((RD_UINT32*)T2[temp[1][1]])
+							^ *((RD_UINT32*)T3[temp[2][2]])
+							^ *((RD_UINT32*)T4[temp[3][3]]);
+		*((RD_UINT32*)(b + 4)) = *((RD_UINT32*)T1[temp[1][0]])
+							^ *((RD_UINT32*)T2[temp[2][1]])
+							^ *((RD_UINT32*)T3[temp[3][2]])
+							^ *((RD_UINT32*)T4[temp[0][3]]);
+		*((RD_UINT32*)(b + 8)) = *((RD_UINT32*)T1[temp[2][0]])
+							^ *((RD_UINT32*)T2[temp[3][1]])
+							^ *((RD_UINT32*)T3[temp[0][2]])
+							^ *((RD_UINT32*)T4[temp[1][3]]);
+		*((RD_UINT32*)(b +12)) = *((RD_UINT32*)T1[temp[3][0]])
+							^ *((RD_UINT32*)T2[temp[0][1]])
+							^ *((RD_UINT32*)T3[temp[1][2]])
+							^ *((RD_UINT32*)T4[temp[2][3]]);
+	}
+	*((RD_UINT32*)temp[0]) = *((RD_UINT32*)(b   )) ^ *((RD_UINT32*)m_expandedKey[m_uRounds-1][0]);
+	*((RD_UINT32*)temp[1]) = *((RD_UINT32*)(b+ 4)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds-1][1]);
+	*((RD_UINT32*)temp[2]) = *((RD_UINT32*)(b+ 8)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds-1][2]);
+	*((RD_UINT32*)temp[3]) = *((RD_UINT32*)(b+12)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds-1][3]);
+	b[ 0] = T1[temp[0][0]][1];
+	b[ 1] = T1[temp[1][1]][1];
+	b[ 2] = T1[temp[2][2]][1];
+	b[ 3] = T1[temp[3][3]][1];
+	b[ 4] = T1[temp[1][0]][1];
+	b[ 5] = T1[temp[2][1]][1];
+	b[ 6] = T1[temp[3][2]][1];
+	b[ 7] = T1[temp[0][3]][1];
+	b[ 8] = T1[temp[2][0]][1];
+	b[ 9] = T1[temp[3][1]][1];
+	b[10] = T1[temp[0][2]][1];
+	b[11] = T1[temp[1][3]][1];
+	b[12] = T1[temp[3][0]][1];
+	b[13] = T1[temp[0][1]][1];
+	b[14] = T1[temp[1][2]][1];
+	b[15] = T1[temp[2][3]][1];
+	*((RD_UINT32*)(b   )) ^= *((RD_UINT32*)m_expandedKey[m_uRounds][0]);
+	*((RD_UINT32*)(b+ 4)) ^= *((RD_UINT32*)m_expandedKey[m_uRounds][1]);
+	*((RD_UINT32*)(b+ 8)) ^= *((RD_UINT32*)m_expandedKey[m_uRounds][2]);
+	*((RD_UINT32*)(b+12)) ^= *((RD_UINT32*)m_expandedKey[m_uRounds][3]);
+}
+
+void Rijndael::decrypt(const RD_UINT8 a[16], RD_UINT8 b[16])
+{
+	int r;
+	RD_UINT8 temp[4][4];
+
+    *((RD_UINT32*)temp[0]) = *((RD_UINT32*)(a   )) ^ *((RD_UINT32*)m_expandedKey[m_uRounds][0]);
+    *((RD_UINT32*)temp[1]) = *((RD_UINT32*)(a+ 4)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds][1]);
+    *((RD_UINT32*)temp[2]) = *((RD_UINT32*)(a+ 8)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds][2]);
+    *((RD_UINT32*)temp[3]) = *((RD_UINT32*)(a+12)) ^ *((RD_UINT32*)m_expandedKey[m_uRounds][3]);
+
+    *((RD_UINT32*)(b   )) = *((RD_UINT32*)T5[temp[0][0]])
+           ^ *((RD_UINT32*)T6[temp[3][1]])
+           ^ *((RD_UINT32*)T7[temp[2][2]])
+           ^ *((RD_UINT32*)T8[temp[1][3]]);
+	*((RD_UINT32*)(b+ 4)) = *((RD_UINT32*)T5[temp[1][0]])
+           ^ *((RD_UINT32*)T6[temp[0][1]])
+           ^ *((RD_UINT32*)T7[temp[3][2]])
+           ^ *((RD_UINT32*)T8[temp[2][3]]);
+	*((RD_UINT32*)(b+ 8)) = *((RD_UINT32*)T5[temp[2][0]])
+           ^ *((RD_UINT32*)T6[temp[1][1]])
+           ^ *((RD_UINT32*)T7[temp[0][2]])
+           ^ *((RD_UINT32*)T8[temp[3][3]]);
+	*((RD_UINT32*)(b+12)) = *((RD_UINT32*)T5[temp[3][0]])
+           ^ *((RD_UINT32*)T6[temp[2][1]])
+           ^ *((RD_UINT32*)T7[temp[1][2]])
+           ^ *((RD_UINT32*)T8[temp[0][3]]);
+	for(r = m_uRounds-1; r > 1; r--)
+	{
+		*((RD_UINT32*)temp[0]) = *((RD_UINT32*)(b   )) ^ *((RD_UINT32*)m_expandedKey[r][0]);
+		*((RD_UINT32*)temp[1]) = *((RD_UINT32*)(b+ 4)) ^ *((RD_UINT32*)m_expandedKey[r][1]);
+		*((RD_UINT32*)temp[2]) = *((RD_UINT32*)(b+ 8)) ^ *((RD_UINT32*)m_expandedKey[r][2]);
+		*((RD_UINT32*)temp[3]) = *((RD_UINT32*)(b+12)) ^ *((RD_UINT32*)m_expandedKey[r][3]);
+		*((RD_UINT32*)(b   )) = *((RD_UINT32*)T5[temp[0][0]])
+           ^ *((RD_UINT32*)T6[temp[3][1]])
+           ^ *((RD_UINT32*)T7[temp[2][2]])
+           ^ *((RD_UINT32*)T8[temp[1][3]]);
+		*((RD_UINT32*)(b+ 4)) = *((RD_UINT32*)T5[temp[1][0]])
+           ^ *((RD_UINT32*)T6[temp[0][1]])
+           ^ *((RD_UINT32*)T7[temp[3][2]])
+           ^ *((RD_UINT32*)T8[temp[2][3]]);
+		*((RD_UINT32*)(b+ 8)) = *((RD_UINT32*)T5[temp[2][0]])
+           ^ *((RD_UINT32*)T6[temp[1][1]])
+           ^ *((RD_UINT32*)T7[temp[0][2]])
+           ^ *((RD_UINT32*)T8[temp[3][3]]);
+		*((RD_UINT32*)(b+12)) = *((RD_UINT32*)T5[temp[3][0]])
+           ^ *((RD_UINT32*)T6[temp[2][1]])
+           ^ *((RD_UINT32*)T7[temp[1][2]])
+           ^ *((RD_UINT32*)T8[temp[0][3]]);
+	}
+
+	*((RD_UINT32*)temp[0]) = *((RD_UINT32*)(b   )) ^ *((RD_UINT32*)m_expandedKey[1][0]);
+	*((RD_UINT32*)temp[1]) = *((RD_UINT32*)(b+ 4)) ^ *((RD_UINT32*)m_expandedKey[1][1]);
+	*((RD_UINT32*)temp[2]) = *((RD_UINT32*)(b+ 8)) ^ *((RD_UINT32*)m_expandedKey[1][2]);
+	*((RD_UINT32*)temp[3]) = *((RD_UINT32*)(b+12)) ^ *((RD_UINT32*)m_expandedKey[1][3]);
+	b[ 0] = S5[temp[0][0]];
+	b[ 1] = S5[temp[3][1]];
+	b[ 2] = S5[temp[2][2]];
+	b[ 3] = S5[temp[1][3]];
+	b[ 4] = S5[temp[1][0]];
+	b[ 5] = S5[temp[0][1]];
+	b[ 6] = S5[temp[3][2]];
+	b[ 7] = S5[temp[2][3]];
+	b[ 8] = S5[temp[2][0]];
+	b[ 9] = S5[temp[1][1]];
+	b[10] = S5[temp[0][2]];
+	b[11] = S5[temp[3][3]];
+	b[12] = S5[temp[3][0]];
+	b[13] = S5[temp[2][1]];
+	b[14] = S5[temp[1][2]];
+	b[15] = S5[temp[0][3]];
+	*((RD_UINT32*)(b   )) ^= *((RD_UINT32*)m_expandedKey[0][0]);
+	*((RD_UINT32*)(b+ 4)) ^= *((RD_UINT32*)m_expandedKey[0][1]);
+	*((RD_UINT32*)(b+ 8)) ^= *((RD_UINT32*)m_expandedKey[0][2]);
+	*((RD_UINT32*)(b+12)) ^= *((RD_UINT32*)m_expandedKey[0][3]);
+}

+ 161 - 0
EncryptDecrypt/rijndael.h

@@ -0,0 +1,161 @@
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+// This file is based on Szymon Stefanek's Rijndael implementation.
+// All I have done is changed the variable type definitions, not more.
+// The original header is below.
+
+//
+// File : rijndael.h
+// Creation date : Sun Nov 5 2000 03:21:05 CEST
+// Author : Szymon Stefanek ([email protected])
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// This code is public domain.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+//    rijndael-alg-fst.c   v2.4   April '2000
+//    rijndael-alg-fst.h
+//    rijndael-api-fst.c
+//    rijndael-api-fst.h
+//
+//    Optimised ANSI C code
+//
+//    authors: v1.0: Antoon Bosselaers
+//             v2.0: Vincent Rijmen, K.U.Leuven
+//             v2.3: Paulo Barreto
+//             v2.4: Vincent Rijmen, K.U.Leuven
+//
+//    This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+//
+// Example of usage:
+//
+//  // Input data
+//  unsigned char key[32];                       // The key
+//  initializeYour256BitKey();                   // Obviously initialized with sth
+//  const unsigned char * plainText = getYourPlainText(); // Your plain text
+//  int plainTextLen = strlen(plainText);        // Plain text length
+//
+//  // Encrypting
+//  Rijndael rin;
+//  unsigned char output[plainTextLen + 16];
+//
+//  rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
+//  // It is a good idea to check the error code
+//  int len = rin.padEncrypt(plainText,len,output);
+//  if(len >= 0)useYourEncryptedText();
+//  else encryptError(len);
+//
+//  // Decrypting: we can reuse the same object
+//  unsigned char output2[len];
+//  rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes));
+//  len = rin.padDecrypt(output,len,output2);
+//  if(len >= 0)useYourDecryptedText();
+//  else decryptError(len);
+//
+
+#define _MAX_KEY_COLUMNS (256/32)
+#define _MAX_ROUNDS      14
+#define MAX_IV_SIZE      16
+
+// DR: Changed definitions of the variables
+typedef unsigned __int8 RD_UINT8;
+typedef unsigned __int16 RD_UINT16;
+typedef unsigned __int32 RD_UINT32;
+
+// Error codes
+#define RIJNDAEL_SUCCESS 0
+#define RIJNDAEL_UNSUPPORTED_MODE -1
+#define RIJNDAEL_UNSUPPORTED_DIRECTION -2
+#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3
+#define RIJNDAEL_BAD_KEY -4
+#define RIJNDAEL_NOT_INITIALIZED -5
+#define RIJNDAEL_BAD_DIRECTION -6
+#define RIJNDAEL_CORRUPTED_DATA -7
+
+class Rijndael
+{	
+public:
+	enum Direction { Encrypt , Decrypt };
+	enum Mode { ECB , CBC , CFB1 };
+	enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes };
+	//
+	// Creates a Rijndael cipher object
+	// You have to call init() before you can encrypt or decrypt stuff
+	//
+	Rijndael();
+	~Rijndael();
+protected:
+	// Internal stuff
+	enum State { Valid , Invalid };
+
+	State     m_state;
+	Mode      m_mode;
+	Direction m_direction;
+	RD_UINT8     m_initVector[MAX_IV_SIZE];
+	RD_UINT32    m_uRounds;
+	RD_UINT8     m_expandedKey[_MAX_ROUNDS+1][4][4];
+public:
+	//////////////////////////////////////////////////////////////////////////////////////////
+	// API
+	//////////////////////////////////////////////////////////////////////////////////////////
+
+	// init(): Initializes the crypt session
+	// Returns RIJNDAEL_SUCCESS or an error code
+	// mode      : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1
+	//             You have to use the same mode for encrypting and decrypting
+	// dir       : Rijndael::Encrypt or Rijndael::Decrypt
+	//             A cipher instance works only in one direction
+	//             (Well , it could be easily modified to work in both
+	//             directions with a single init() call, but it looks
+	//             useless to me...anyway , it is a matter of generating
+	//             two expanded keys)
+	// key       : array of unsigned octets , it can be 16 , 24 or 32 bytes long
+	//             this CAN be binary data (it is not expected to be null terminated)
+	// keyLen    : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes
+	// initVector: initialization vector, you will usually use 0 here
+	int init(Mode mode,Direction dir,const RD_UINT8 *key,KeyLength keyLen,RD_UINT8 * initVector = 0);
+	// Encrypts the input array (can be binary data)
+	// The input array length must be a multiple of 16 bytes, the remaining part
+	// is DISCARDED.
+	// so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer
+	// Input len is in BITS!
+	// outBuffer must be at least inputLen / 8 bytes long.
+	// Returns the encrypted buffer length in BITS or an error code < 0 in case of error
+	int blockEncrypt(const RD_UINT8 *input, int inputLen, RD_UINT8 *outBuffer);
+	// Encrypts the input array (can be binary data)
+	// The input array can be any length , it is automatically padded on a 16 byte boundary.
+	// Input len is in BYTES!
+	// outBuffer must be at least (inputLen + 16) bytes long
+	// Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
+	int padEncrypt(const RD_UINT8 *input, int inputOctets, RD_UINT8 *outBuffer);
+	// Decrypts the input vector
+	// Input len is in BITS!
+	// outBuffer must be at least inputLen / 8 bytes long
+	// Returns the decrypted buffer length in BITS and an error code < 0 in case of error
+	int blockDecrypt(const RD_UINT8 *input, int inputLen, RD_UINT8 *outBuffer);
+	// Decrypts the input vector
+	// Input len is in BYTES!
+	// outBuffer must be at least inputLen bytes long
+	// Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
+	int padDecrypt(const RD_UINT8 *input, int inputOctets, RD_UINT8 *outBuffer);
+protected:
+	void keySched(RD_UINT8 key[_MAX_KEY_COLUMNS][4]);
+	void keyEncToDec();
+	void encrypt(const RD_UINT8 a[16], RD_UINT8 b[16]);
+	void decrypt(const RD_UINT8 a[16], RD_UINT8 b[16]);
+};
+	
+#endif // _RIJNDAEL_H_

+ 721 - 0
EncryptDecrypt/sha2.cpp

@@ -0,0 +1,721 @@
+// Modified version of Dr Brian Gladmans implementation of the SHA-2
+// algorithms.
+//
+// Changes:
+// - Added #include <stdafx.h> to compile with MFC projects
+// - Added _WIN32_WCE define condition
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <[email protected]>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary 
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright 
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products 
+      built using this software without specific written permission. 
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+ 
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness 
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 26/08/2003
+
+ This is a byte oriented version of SHA2 that operates on arrays of bytes
+ stored in memory. This code implements sha256, sha384 and sha512 but the
+ latter two functions rely on efficient 64-bit integer operations that 
+ may not be very efficient on 32-bit machines
+
+ The sha256 functions use a type 'sha256_ctx' to hold details of the 
+ current hash state and uses the following three calls:
+
+       void sha256_begin(sha256_ctx ctx[1])
+       void sha256_hash(const unsigned char data[], 
+                            unsigned long len, sha256_ctx ctx[1])
+       void sha256_end(unsigned char hval[], sha256_ctx ctx[1])
+
+ The first subroutine initialises a hash computation by setting up the 
+ context in the sha256_ctx context. The second subroutine hashes 8-bit 
+ bytes from array data[] into the hash state withinh sha256_ctx context, 
+ the number of bytes to be hashed being given by the the unsigned long 
+ integer len.  The third subroutine completes the hash calculation and 
+ places the resulting digest value in the array of 8-bit bytes hval[].
+
+ The sha384 and sha512 functions are similar and use the interfaces:
+
+       void sha384_begin(sha384_ctx ctx[1]);
+       void sha384_hash(const unsigned char data[], 
+                            unsigned long len, sha384_ctx ctx[1]);
+       void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
+
+       void sha512_begin(sha512_ctx ctx[1]);
+       void sha512_hash(const unsigned char data[], 
+                            unsigned long len, sha512_ctx ctx[1]);
+       void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
+
+ In addition there is a function sha2 that can be used to call all these
+ functions using a call with a hash length parameter as follows:
+
+       int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
+       void sha2_hash(const unsigned char data[], 
+                            unsigned long len, sha2_ctx ctx[1]);
+       void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
+
+ My thanks to Erik Andersen <[email protected]> for testing this code 
+ on big-endian systems and for his assistance with corrections
+*/
+
+// Dominik Reichl: Added to compile with MFC
+#include "StdAfx.h"
+
+/* define the hash functions that you need          */
+
+#define SHA_2           /* for dynamic hash length  */
+#define SHA_256
+#define SHA_384
+#define SHA_512
+
+#include <string.h>     /* for memcpy() etc.        */
+#include <stdlib.h>     /* for _lrotr with VC++     */
+
+#include "sha2.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*  PLATFORM SPECIFIC INCLUDES */
+
+#if defined( __FreeBSD__ ) || defined( __OpenBSD__ )
+#  include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 )
+#  include <machine/endian.h>
+#elif defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
+#  include <endian.h>
+#  include <byteswap.h>
+#elif defined( linux )
+#  include <endian.h>
+#endif
+
+/*  BYTE ORDER IN 32-BIT WORDS
+
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the byte order of the target machine. The following 
+    block of code is an attempt to capture the most obvious ways in which 
+    various environemnts define byte order. It may well fail, in which case 
+    the definitions will need to be set by editing at the points marked 
+    **** EDIT HERE IF NECESSARY **** below.  My thanks to Peter Gutmann for 
+    some of these defines (from cryptlib).
+*/
+
+#define BRG_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define BRG_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       ||   \
+    defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    ||   \
+    defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) ||   \
+    defined( vax )       || defined( vms )     || defined( VMS )        ||   \
+    defined( __VMS )     || defined( _WIN32_WCE )
+
+#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+
+#endif
+
+#if defined( AMIGA )    || defined( applec )  || defined( __AS400__ )  ||   \
+    defined( _CRAY )    || defined( __hppa )  || defined( __hp9000 )   ||   \
+    defined( ibm370 )   || defined( mc68000 ) || defined( m68k )       ||   \
+    defined( __MRC__ )  || defined( __MVS__ ) || defined( __MWERKS__ ) ||   \
+    defined( sparc )    || defined( __sparc)  || defined( SYMANTEC_C ) ||   \
+    defined( __TANDEM ) || defined( THINK_C ) || defined( __VMCMS__ )
+    
+#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+
+#endif
+
+/*  if the platform is still not known, try to find its byte order  */
+/*  from commonly used definitions in the headers included earlier  */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if    defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) &&  defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  endif
+
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if    defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) &&  defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  endif
+
+#elif defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)
+#  if    defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif !defined(__LITTLE_ENDIAN__) &&  defined(__BIG_ENDIAN__)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
+#    define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+#  elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
+#    define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+#  endif
+
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
+
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
+
+#else
+#error Please edit sha2.c (line 180 or 183) to set the platform byte order
+#endif
+
+#endif
+
+#ifdef _MSC_VER
+#pragma intrinsic(memcpy)
+#endif
+
+#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
+
+#if !defined(bswap_32)
+#define bswap_32(x) (rotr32((x), 24) & 0x00ff00ff | rotr32((x), 8) & 0xff00ff00)
+#endif
+
+#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
+#define SWAP_BYTES
+#else
+#undef  SWAP_BYTES
+#endif
+
+#if defined(SHA_2) || defined(SHA_256)
+
+#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
+
+#if defined(SWAP_BYTES)
+#define bsw_32(p,n) { int _i = (n); while(_i--) p[_i] = bswap_32(p[_i]); }
+#else
+#define bsw_32(p,n) 
+#endif
+
+/* SHA256 mixing function definitions   */
+
+#if 0
+
+#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
+#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#else   /* Thanks to Rich Schroeppel and Colin Plumb for the following      */
+
+#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
+#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))
+
+#endif
+
+#define s256_0(x) (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22)) 
+#define s256_1(x) (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25)) 
+#define g256_0(x) (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3)) 
+#define g256_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) 
+
+/* rotated SHA256 round definition. Rather than swapping variables as in    */
+/* FIPS-180, different variables are 'rotated' on each round, returning     */
+/* to their starting positions every eight rounds                           */
+
+#define h2(i) p[i & 15] += \
+    g256_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g256_0(p[(i + 1) & 15])
+
+#define h2_cycle(i,j)  \
+    v[(7 - i) & 7] += (j ? h2(i) : p[i & 15]) + k256[i + j] \
+        + s256_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7], v[(6 - i) & 7]); \
+    v[(3 - i) & 7] += v[(7 - i) & 7]; \
+    v[(7 - i) & 7] += s256_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7], v[(1 - i) & 7], v[(2 - i) & 7])
+
+/* SHA256 mixing data   */
+
+const sha2_32t k256[64] =
+{   n_u32(428a2f98), n_u32(71374491), n_u32(b5c0fbcf), n_u32(e9b5dba5), 
+    n_u32(3956c25b), n_u32(59f111f1), n_u32(923f82a4), n_u32(ab1c5ed5), 
+    n_u32(d807aa98), n_u32(12835b01), n_u32(243185be), n_u32(550c7dc3), 
+    n_u32(72be5d74), n_u32(80deb1fe), n_u32(9bdc06a7), n_u32(c19bf174), 
+    n_u32(e49b69c1), n_u32(efbe4786), n_u32(0fc19dc6), n_u32(240ca1cc), 
+    n_u32(2de92c6f), n_u32(4a7484aa), n_u32(5cb0a9dc), n_u32(76f988da), 
+    n_u32(983e5152), n_u32(a831c66d), n_u32(b00327c8), n_u32(bf597fc7), 
+    n_u32(c6e00bf3), n_u32(d5a79147), n_u32(06ca6351), n_u32(14292967), 
+    n_u32(27b70a85), n_u32(2e1b2138), n_u32(4d2c6dfc), n_u32(53380d13), 
+    n_u32(650a7354), n_u32(766a0abb), n_u32(81c2c92e), n_u32(92722c85),
+    n_u32(a2bfe8a1), n_u32(a81a664b), n_u32(c24b8b70), n_u32(c76c51a3), 
+    n_u32(d192e819), n_u32(d6990624), n_u32(f40e3585), n_u32(106aa070), 
+    n_u32(19a4c116), n_u32(1e376c08), n_u32(2748774c), n_u32(34b0bcb5), 
+    n_u32(391c0cb3), n_u32(4ed8aa4a), n_u32(5b9cca4f), n_u32(682e6ff3), 
+    n_u32(748f82ee), n_u32(78a5636f), n_u32(84c87814), n_u32(8cc70208), 
+    n_u32(90befffa), n_u32(a4506ceb), n_u32(bef9a3f7), n_u32(c67178f2),
+};
+
+/* SHA256 initialisation data */
+
+const sha2_32t i256[8] =
+{
+    n_u32(6a09e667), n_u32(bb67ae85), n_u32(3c6ef372), n_u32(a54ff53a),
+    n_u32(510e527f), n_u32(9b05688c), n_u32(1f83d9ab), n_u32(5be0cd19)
+};
+
+sha2_void sha256_begin(sha256_ctx ctx[1])
+{
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i256, 8 * sizeof(sha2_32t));
+}
+
+/* Compile 64 bytes of hash data into SHA256 digest value   */
+/* NOTE: this routine assumes that the byte order in the    */
+/* ctx->wbuf[] at this point is in such an order that low   */
+/* address bytes in the ORIGINAL byte stream placed in this */
+/* buffer will now go to the high end of words on BOTH big  */
+/* and little endian systems                                */
+
+sha2_void sha256_compile(sha256_ctx ctx[1])
+{   sha2_32t    v[8], j, *p = ctx->wbuf;
+
+    memcpy(v, ctx->hash, 8 * sizeof(sha2_32t));
+
+    for(j = 0; j < 64; j += 16)
+    {
+        h2_cycle( 0, j); h2_cycle( 1, j); h2_cycle( 2, j); h2_cycle( 3, j);
+        h2_cycle( 4, j); h2_cycle( 5, j); h2_cycle( 6, j); h2_cycle( 7, j);
+        h2_cycle( 8, j); h2_cycle( 9, j); h2_cycle(10, j); h2_cycle(11, j);
+        h2_cycle(12, j); h2_cycle(13, j); h2_cycle(14, j); h2_cycle(15, j);
+    }
+
+    ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
+    ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
+}
+
+/* SHA256 hash data in an array of bytes into hash buffer   */
+/* and call the hash_compile function as required.          */
+
+sha2_void sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
+{   sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA256_MASK), 
+             space = SHA256_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks while possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0; 
+        bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
+        sha256_compile(ctx);
+    }
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA256 Final padding and digest calculation  */
+
+static sha2_32t  m1[4] =
+{
+    n_u32(00000000), n_u32(ff000000), n_u32(ffff0000), n_u32(ffffff00)
+};
+
+static sha2_32t  b1[4] =
+{
+    n_u32(80000000), n_u32(00800000), n_u32(00008000), n_u32(00000080)
+};
+
+sha2_void sha256_end(unsigned char hval[], sha256_ctx ctx[1])
+{   sha2_32t    i = (sha2_32t)(ctx->count[0] & SHA256_MASK);
+
+    bsw_32(ctx->wbuf, (i + 3) >> 2)
+    /* bytes in the buffer are now in an order in which references  */
+    /* to 32-bit words will put bytes with lower addresses into the */
+    /* top of 32 bit words on BOTH big and little endian machines   */
+    
+    /* we now need to mask valid bytes and add the padding which is */
+    /* a single 1 bit and as many zero bits as necessary.           */
+    ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & m1[i & 3]) | b1[i & 3];
+
+    /* we need 9 or more empty positions, one for the padding byte  */
+    /* (above) and eight for the length count.  If there is not     */
+    /* enough space pad and empty the buffer                        */
+    if(i > SHA256_BLOCK_SIZE - 9)
+    {
+        if(i < 60) ctx->wbuf[15] = 0;
+        sha256_compile(ctx);
+        i = 0;
+    }
+    else    /* compute a word index for the empty buffer positions  */
+        i = (i >> 2) + 1;
+
+    while(i < 14) /* and zero pad all but last two positions      */ 
+        ctx->wbuf[i++] = 0;
+    
+    /* the following 32-bit length fields are assembled in the      */
+    /* wrong byte order on little endian machines but this is       */
+    /* corrected later since they are only ever used as 32-bit      */
+    /* word values.                                                 */
+
+    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
+    ctx->wbuf[15] = ctx->count[0] << 3;
+
+    sha256_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* mislaigned for 32-bit words                                  */
+    for(i = 0; i < SHA256_DIGEST_SIZE; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
+}
+
+sha2_void sha256(unsigned char hval[], const unsigned char data[], unsigned long len) 
+{   sha256_ctx  cx[1];
+    
+    sha256_begin(cx); sha256_hash(data, len, cx); sha256_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_384) || defined(SHA_512)
+
+#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
+
+#define rotr64(x,n)   (((x) >> n) | ((x) << (64 - n)))
+
+#if !defined(bswap_64)
+#define bswap_64(x) (((sha2_64t)(bswap_32((sha2_32t)(x)))) << 32 | bswap_32((sha2_32t)((x) >> 32)))
+#endif
+
+#if defined(SWAP_BYTES)
+#define bsw_64(p,n) { int _i = (n); while(_i--) p[_i] = bswap_64(p[_i]); }
+#else
+#define bsw_64(p,n) 
+#endif
+
+/* SHA512 mixing function definitions   */
+
+#define s512_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) 
+#define s512_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) 
+#define g512_0(x) (rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >>  7)) 
+#define g512_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >>  6)) 
+
+/* rotated SHA512 round definition. Rather than swapping variables as in    */
+/* FIPS-180, different variables are 'rotated' on each round, returning     */
+/* to their starting positions every eight rounds                           */
+
+#define h5(i) ctx->wbuf[i & 15] += \
+    g512_1(ctx->wbuf[(i + 14) & 15]) + ctx->wbuf[(i + 9) & 15] + g512_0(ctx->wbuf[(i + 1) & 15])
+
+#define h5_cycle(i,j)  \
+    v[(7 - i) & 7] += (j ? h5(i) : ctx->wbuf[i & 15]) + k512[i + j] \
+        + s512_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7], v[(6 - i) & 7]); \
+    v[(3 - i) & 7] += v[(7 - i) & 7]; \
+    v[(7 - i) & 7] += s512_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7], v[(1 - i) & 7], v[(2 - i) & 7])
+
+/* SHA384/SHA512 mixing data    */
+
+const sha2_64t  k512[80] = 
+{
+    n_u64(428a2f98d728ae22), n_u64(7137449123ef65cd), 
+    n_u64(b5c0fbcfec4d3b2f), n_u64(e9b5dba58189dbbc),
+    n_u64(3956c25bf348b538), n_u64(59f111f1b605d019),
+    n_u64(923f82a4af194f9b), n_u64(ab1c5ed5da6d8118),
+    n_u64(d807aa98a3030242), n_u64(12835b0145706fbe),
+    n_u64(243185be4ee4b28c), n_u64(550c7dc3d5ffb4e2),
+    n_u64(72be5d74f27b896f), n_u64(80deb1fe3b1696b1),
+    n_u64(9bdc06a725c71235), n_u64(c19bf174cf692694),
+    n_u64(e49b69c19ef14ad2), n_u64(efbe4786384f25e3),
+    n_u64(0fc19dc68b8cd5b5), n_u64(240ca1cc77ac9c65),
+    n_u64(2de92c6f592b0275), n_u64(4a7484aa6ea6e483),
+    n_u64(5cb0a9dcbd41fbd4), n_u64(76f988da831153b5),
+    n_u64(983e5152ee66dfab), n_u64(a831c66d2db43210),
+    n_u64(b00327c898fb213f), n_u64(bf597fc7beef0ee4),
+    n_u64(c6e00bf33da88fc2), n_u64(d5a79147930aa725),
+    n_u64(06ca6351e003826f), n_u64(142929670a0e6e70),
+    n_u64(27b70a8546d22ffc), n_u64(2e1b21385c26c926),
+    n_u64(4d2c6dfc5ac42aed), n_u64(53380d139d95b3df),
+    n_u64(650a73548baf63de), n_u64(766a0abb3c77b2a8),
+    n_u64(81c2c92e47edaee6), n_u64(92722c851482353b),
+    n_u64(a2bfe8a14cf10364), n_u64(a81a664bbc423001),
+    n_u64(c24b8b70d0f89791), n_u64(c76c51a30654be30),
+    n_u64(d192e819d6ef5218), n_u64(d69906245565a910),
+    n_u64(f40e35855771202a), n_u64(106aa07032bbd1b8),
+    n_u64(19a4c116b8d2d0c8), n_u64(1e376c085141ab53),
+    n_u64(2748774cdf8eeb99), n_u64(34b0bcb5e19b48a8),
+    n_u64(391c0cb3c5c95a63), n_u64(4ed8aa4ae3418acb),
+    n_u64(5b9cca4f7763e373), n_u64(682e6ff3d6b2b8a3),
+    n_u64(748f82ee5defb2fc), n_u64(78a5636f43172f60),
+    n_u64(84c87814a1f0ab72), n_u64(8cc702081a6439ec),
+    n_u64(90befffa23631e28), n_u64(a4506cebde82bde9),
+    n_u64(bef9a3f7b2c67915), n_u64(c67178f2e372532b),
+    n_u64(ca273eceea26619c), n_u64(d186b8c721c0c207),
+    n_u64(eada7dd6cde0eb1e), n_u64(f57d4f7fee6ed178),
+    n_u64(06f067aa72176fba), n_u64(0a637dc5a2c898a6),
+    n_u64(113f9804bef90dae), n_u64(1b710b35131c471b),
+    n_u64(28db77f523047d84), n_u64(32caab7b40c72493),
+    n_u64(3c9ebe0a15c9bebc), n_u64(431d67c49c100d4c),
+    n_u64(4cc5d4becb3e42b6), n_u64(597f299cfc657e2a),
+    n_u64(5fcb6fab3ad6faec), n_u64(6c44198c4a475817)
+};
+
+/* Compile 64 bytes of hash data into SHA384/SHA512 digest value  */
+
+sha2_void sha512_compile(sha512_ctx ctx[1])
+{   sha2_64t    v[8];
+    sha2_32t    j;
+
+    memcpy(v, ctx->hash, 8 * sizeof(sha2_64t));
+
+    for(j = 0; j < 80; j += 16)
+    {
+        h5_cycle( 0, j); h5_cycle( 1, j); h5_cycle( 2, j); h5_cycle( 3, j);
+        h5_cycle( 4, j); h5_cycle( 5, j); h5_cycle( 6, j); h5_cycle( 7, j);
+        h5_cycle( 8, j); h5_cycle( 9, j); h5_cycle(10, j); h5_cycle(11, j);
+        h5_cycle(12, j); h5_cycle(13, j); h5_cycle(14, j); h5_cycle(15, j);
+    }
+
+    ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
+    ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
+}
+
+/* Compile 128 bytes of hash data into SHA256 digest value  */
+/* NOTE: this routine assumes that the byte order in the    */
+/* ctx->wbuf[] at this point is in such an order that low   */
+/* address bytes in the ORIGINAL byte stream placed in this */
+/* buffer will now go to the high end of words on BOTH big  */
+/* and little endian systems                                */
+
+sha2_void sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
+{   sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA512_MASK), 
+             space = SHA512_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks while possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0; 
+        bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);        
+        sha512_compile(ctx);
+    }
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA384/512 Final padding and digest calculation  */
+
+static sha2_64t  m2[8] =
+{
+    n_u64(0000000000000000), n_u64(ff00000000000000), 
+    n_u64(ffff000000000000), n_u64(ffffff0000000000),
+    n_u64(ffffffff00000000), n_u64(ffffffffff000000),
+    n_u64(ffffffffffff0000), n_u64(ffffffffffffff00)
+};
+
+static sha2_64t  b2[8] =
+{
+    n_u64(8000000000000000), n_u64(0080000000000000), 
+    n_u64(0000800000000000), n_u64(0000008000000000),
+    n_u64(0000000080000000), n_u64(0000000000800000), 
+    n_u64(0000000000008000), n_u64(0000000000000080)
+};
+
+static void sha_end(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
+{   sha2_32t    i = (sha2_32t)(ctx->count[0] & SHA512_MASK);
+
+    bsw_64(ctx->wbuf, (i + 7) >> 3);
+
+    /* bytes in the buffer are now in an order in which references  */
+    /* to 64-bit words will put bytes with lower addresses into the */
+    /* top of 64 bit words on BOTH big and little endian machines   */
+    
+    /* we now need to mask valid bytes and add the padding which is */
+    /* a single 1 bit and as many zero bits as necessary.           */
+    ctx->wbuf[i >> 3] = (ctx->wbuf[i >> 3] & m2[i & 7]) | b2[i & 7];
+
+    /* we need 17 or more empty byte positions, one for the padding */
+    /* byte (above) and sixteen for the length count.  If there is  */
+    /* not enough space pad and empty the buffer                    */
+    if(i > SHA512_BLOCK_SIZE - 17)
+    {
+        if(i < 120) ctx->wbuf[15] = 0;
+        sha512_compile(ctx);
+        i = 0;
+    }
+    else
+        i = (i >> 3) + 1;
+
+    while(i < 14)
+        ctx->wbuf[i++] = 0;
+    
+    /* the following 64-bit length fields are assembled in the      */
+    /* wrong byte order on little endian machines but this is       */
+    /* corrected later since they are only ever used as 64-bit      */
+    /* word values.                                                 */
+
+    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
+    ctx->wbuf[15] = ctx->count[0] << 3;
+
+    sha512_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* misaligned for 32-bit words                                  */
+    for(i = 0; i < hlen; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_384)
+
+/* SHA384 initialisation data   */
+
+const sha2_64t  i384[80] = 
+{
+    n_u64(cbbb9d5dc1059ed8), n_u64(629a292a367cd507),
+    n_u64(9159015a3070dd17), n_u64(152fecd8f70e5939),
+    n_u64(67332667ffc00b31), n_u64(8eb44a8768581511),
+    n_u64(db0c2e0d64f98fa7), n_u64(47b5481dbefa4fa4)
+};
+
+sha2_void sha384_begin(sha384_ctx ctx[1])
+{
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i384, 8 * sizeof(sha2_64t));
+}
+
+sha2_void sha384_end(unsigned char hval[], sha384_ctx ctx[1])
+{
+    sha_end(hval, ctx, SHA384_DIGEST_SIZE);
+}
+
+sha2_void sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
+{   sha384_ctx  cx[1];
+    
+    sha384_begin(cx); sha384_hash(data, len, cx); sha384_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_512)
+
+/* SHA512 initialisation data   */
+
+const sha2_64t  i512[80] = 
+{
+    n_u64(6a09e667f3bcc908), n_u64(bb67ae8584caa73b),
+    n_u64(3c6ef372fe94f82b), n_u64(a54ff53a5f1d36f1),
+    n_u64(510e527fade682d1), n_u64(9b05688c2b3e6c1f),
+    n_u64(1f83d9abfb41bd6b), n_u64(5be0cd19137e2179)
+};
+
+sha2_void sha512_begin(sha512_ctx ctx[1])
+{
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i512, 8 * sizeof(sha2_64t));
+}
+
+sha2_void sha512_end(unsigned char hval[], sha512_ctx ctx[1])
+{
+    sha_end(hval, ctx, SHA512_DIGEST_SIZE);
+}
+
+sha2_void sha512(unsigned char hval[], const unsigned char data[], unsigned long len) 
+{   sha512_ctx  cx[1];
+    
+    sha512_begin(cx); sha512_hash(data, len, cx); sha512_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2)
+
+#define CTX_256(x)  ((x)->uu->ctx256)
+#define CTX_384(x)  ((x)->uu->ctx512)
+#define CTX_512(x)  ((x)->uu->ctx512)
+
+/* SHA2 initialisation */
+
+sha2_int sha2_begin(unsigned long len, sha2_ctx ctx[1])
+{   unsigned long   l = len;
+    switch(len)
+    {
+        case 256:   l = len >> 3;
+        case  32:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
+                    memcpy(CTX_256(ctx)->hash, i256, 32); break;
+        case 384:   l = len >> 3;
+        case  48:   CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
+                    memcpy(CTX_384(ctx)->hash, i384, 64); break;
+        case 512:   l = len >> 3;
+        case  64:   CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
+                    memcpy(CTX_512(ctx)->hash, i512, 64); break;
+        default:    return SHA2_BAD;
+    }
+    
+    ctx->sha2_len = l; return SHA2_GOOD;
+}
+
+sha2_void sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
+{
+    switch(ctx->sha2_len)
+    {
+        case 32: sha256_hash(data, len, CTX_256(ctx)); return;
+        case 48: sha384_hash(data, len, CTX_384(ctx)); return;
+        case 64: sha512_hash(data, len, CTX_512(ctx)); return;
+    }
+}
+
+sha2_void sha2_end(unsigned char hval[], sha2_ctx ctx[1])
+{
+    switch(ctx->sha2_len)
+    {
+        case 32: sha256_end(hval, CTX_256(ctx)); return;
+        case 48: sha_end(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
+        case 64: sha_end(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
+    }
+}
+
+sha2_int sha2(unsigned char hval[], unsigned long size,
+                                const unsigned char data[], unsigned long len)
+{   sha2_ctx    cx[1];
+
+    if(sha2_begin(size, cx) == SHA2_GOOD)
+    {
+        sha2_hash(data, len, cx); sha2_end(hval, cx); return SHA2_GOOD;
+    }
+    else
+        return SHA2_BAD;
+}
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif

+ 154 - 0
EncryptDecrypt/sha2.h

@@ -0,0 +1,154 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <[email protected]>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary 
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright 
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products 
+      built using this software without specific written permission. 
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+ 
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness 
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 26/08/2003
+*/
+
+#ifndef _SHA2_H
+#define _SHA2_H
+
+#include <limits.h>
+
+/*  Defines for suffixes to 32 and 64 bit unsigned numeric values   */
+
+#define sfx_lo(x,y) x##y
+#define sfx_hi(x,y) sfx_lo(x,y)
+#define n_u32(p)    sfx_hi(0x##p,s_u32)
+#define n_u64(p)    sfx_hi(0x##p,s_u64)
+
+/* define an unsigned 32-bit type */
+
+#if UINT_MAX == 0xffffffff
+  typedef   unsigned int     sha2_32t;
+  #define s_u32    u
+#elif ULONG_MAX == 0xffffffff
+  typedef   unsigned long    sha2_32t;
+  #define s_u32   ul
+#else
+#error Please define sha2_32t as an unsigned 32 bit type in sha2.h
+#endif
+
+/* define an unsigned 64-bit type */
+
+#if _MSC_VER < 1300
+  typedef unsigned __int64   sha2_64t;
+  #define s_u64 ui64
+#elif ULONG_MAX == 0xffffffffffffffff
+  typedef unsigned long      sha2_64t;
+  #define s_u64   ul
+#elif ULONG_MAX == 0xffffffff
+  typedef unsigned long long sha2_64t;   /* a somewhat dangerous guess */
+  #define s_u64  ull
+#else
+#error Please define sha2_64t as an unsigned 64 bit type in sha2.h
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define SHA256_DIGEST_SIZE  32
+#define SHA384_DIGEST_SIZE  48
+#define SHA512_DIGEST_SIZE  64
+
+#define SHA256_BLOCK_SIZE   64
+#define SHA384_BLOCK_SIZE  128
+#define SHA512_BLOCK_SIZE  128
+
+#define SHA2_MAX_DIGEST_SIZE    SHA512_DIGEST_SIZE
+
+#define SHA2_GOOD   0
+#define SHA2_BAD    1
+
+/* type to hold the SHA256 context              */
+
+typedef struct
+{   sha2_32t count[2];
+    sha2_32t hash[8];
+    sha2_32t wbuf[16];
+} sha256_ctx;
+
+/* type to hold the SHA384/512 context          */
+
+typedef struct
+{   sha2_64t count[2];
+    sha2_64t hash[8];
+    sha2_64t wbuf[16];
+} sha512_ctx;
+
+typedef sha512_ctx  sha384_ctx;
+
+/* type to hold a SHA2 context (256/384/512)  */
+
+typedef struct
+{   union
+    {   sha256_ctx  ctx256[1];
+        sha512_ctx  ctx512[1];
+    } uu[1];
+    sha2_32t    sha2_len;
+} sha2_ctx;
+
+#ifndef SHA2_DLL                  /* implement normal or DLL functions   */
+#define sha2_void   void
+#define sha2_int    int
+#else
+#define sha2_void   void __declspec(dllexport) _stdcall
+#define sha2_int    int  __declspec(dllexport) _stdcall
+#endif
+
+sha2_void sha256_compile(sha256_ctx ctx[1]);
+sha2_void sha512_compile(sha512_ctx ctx[1]);
+
+sha2_void sha256_begin(sha256_ctx ctx[1]);
+sha2_void sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]);
+sha2_void sha256_end(unsigned char hval[], sha256_ctx ctx[1]);
+sha2_void sha256(unsigned char hval[], const unsigned char data[], unsigned long len); 
+
+sha2_void sha384_begin(sha384_ctx ctx[1]);
+#define sha384_hash sha512_hash
+sha2_void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
+sha2_void sha384(unsigned char hval[], const unsigned char data[], unsigned long len); 
+
+sha2_void sha512_begin(sha512_ctx ctx[1]);
+sha2_void sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]);
+sha2_void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
+sha2_void sha512(unsigned char hval[], const unsigned char data[], unsigned long len); 
+
+sha2_int  sha2_begin(unsigned long size, sha2_ctx ctx[1]);
+sha2_void sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
+sha2_void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
+sha2_int  sha2(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len); 
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif

BIN
EncryptDecryptD.lib


+ 33 - 1
Help/DittoFAQ.htm

@@ -199,6 +199,8 @@ cell in Microsoft Excel and it only pastes back the text not the formulas.</a></
 <p class=MsoToc3><span class=MsoHyperlink><a href="#bm_Search">5) I searched
 for something I know I copied but it’s not showing in the search results.</a></span></p>
 
+<p class=MsoToc3><span class="MsoHyperlink"><a href="#bm_Searching">6) How does searching work?</a></span></p>
+
 <p class=dittoheading3><span
 style='mso-bookmark:_Toc84104799'><a name="bm_WhatIsDitto"></a>1) What is Ditto?</span></p>
 
@@ -217,7 +219,7 @@ store its data?</p>
 
 <p class=MsoNormal>Settings are stored in “HKCU\programs\Ditto”</p>
 
-<p class=MsoNormal>The database is stored in “[Current User]\Application
+<p class=MsoNormal>The database is stored in “Documents and Settings\[Current User]\Application
 Data\Ditto\DittoDB.mdb”</p>
 
 <p class=MsoNormal>Application files are stored in “Program Files\Ditto\”</p>
@@ -291,6 +293,36 @@ General -&gt; &quot;Amount of text to save for description&quot;].</p>
 
 <p class=MsoNormal>&nbsp;</p>
 
+<p class=dittoheading3><a name="bm_Searching"></a>6) How does searching work?</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>On all searches, search are treated as Clip Text contains the 
+search words.</p>
+
+<p class=MsoNormal>When searching spaces are treated as &quot;and&quot; unless they are 
+contained in quotes (&quot;&quot;)</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>ex.&nbsp;&nbsp;&nbsp; search for - right click -</p>
+
+<p class=MsoNormal>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+this would find anything with &quot;right&quot; and &quot;click&quot; in the text, not necessarily 
+next to each other</p>
+
+<p class=MsoNormal>&nbsp;&nbsp;&nbsp; </p>
+
+<p class=MsoNormal>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; search for - 
+&quot;right click&quot;</p>
+
+<p class=MsoNormal>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+this would find all text containing the exact text &quot;right click&quot; </p>
+
+<p class=MsoNormal>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
+
+<p class=MsoNormal>&nbsp;</p>
+
 <div style='border:none;border-bottom:solid windowtext 1.0pt;padding:0in 0in 1.0pt 0in'>
 
 <p class=MsoNormal>&nbsp;</p>

+ 1 - 1
MainFrm.cpp

@@ -400,7 +400,7 @@ BOOL CMainFrame::ResetKillDBTimer()
 {
 	KillTimer(KILL_DB_TIMER);
 
-	SetTimer(KILL_DB_TIMER, ONE_MINUTE*60, NULL);
+	SetTimer(KILL_DB_TIMER, 20000, NULL);
 
 	return TRUE;
 }

+ 1 - 1
MainFrm.h

@@ -13,7 +13,7 @@
 #include "QuickPaste.h"
 
 
-#define KILL_DB_TIMER					1
+#define KILL_DB_TIMER					1	
 #define HIDE_ICON_TIMER					2
 #define REMOVE_OLD_ENTRIES_TIMER		3
 #define CHECK_FOR_UPDATE				4

+ 130 - 2
Misc.cpp

@@ -480,6 +480,9 @@ long CGetSetOptions::m_lPort;
 BOOL CGetSetOptions::m_bDrawThumbnail;
 CString CGetSetOptions::m_csPassword;
 BOOL CGetSetOptions::m_bDrawRTF;
+BOOL CGetSetOptions::m_bMultiPasteReverse;
+CString CGetSetOptions::m_csPlaySoundOnCopy;
+CStringArray CGetSetOptions::m_csNetworkPasswordArray;
 
 CGetSetOptions g_Opt;
 
@@ -506,6 +509,29 @@ CGetSetOptions::CGetSetOptions()
 	m_bDrawThumbnail = GetDrawThumbnail();
 	m_csPassword = GetNetworkPassword();
 	m_bDrawRTF = GetDrawRTF();
+	m_bMultiPasteReverse = GetMultiPasteReverse();
+	m_csPlaySoundOnCopy = GetPlaySoundOnCopy();
+
+	CString cs = GetProfileString("NetorkPassword1", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword2", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword3", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword4", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword5", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword6", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword7", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword8", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword9", "");
+	m_csNetworkPasswordArray.Add(cs);
+	cs = GetProfileString("NetorkPassword10", "");
+	m_csNetworkPasswordArray.Add(cs);
 
 	#ifdef _DEBUG
 	m_bUseHookDllForFocus = FALSE;
@@ -1170,12 +1196,47 @@ void CGetSetOptions::SetNetworkPassword(CString csPassword)
 {
 	m_csPassword = csPassword;
 
-	SetProfileString("NetworkPassword", csPassword);
+	UCHAR *pData = NULL;
+	int nLength = 0;
+
+	if(EncryptString(csPassword, pData, nLength))
+	{
+		SetProfileData("NetworkPassword", pData, nLength);
+	}
+	else
+	{
+		SetProfileData("NetworkPassword", NULL, 0);
+	}
+
+	if(pData)
+	{
+		delete pData;
+		pData = NULL;
+	}
 }
 
 CString CGetSetOptions::GetNetworkPassword()
 {
-	CString cs = GetProfileString("NetworkPassword", "!.*abc");
+	CString cs = "";
+	DWORD dwLength = 0;
+	LPVOID lpVoid = GetProfileData("NetworkPassword", dwLength);
+	if(lpVoid)
+	{
+		UCHAR *pData = NULL;
+		int nLength = 0;
+
+		if(DecryptString((UCHAR *)lpVoid, dwLength, pData, nLength))
+			cs = pData;
+
+		if(pData)
+		{
+			delete pData;
+			pData = NULL;
+		}
+	}
+
+	if(cs == "")
+		cs = "LetMeIn";
 
 	return cs;
 }
@@ -1191,6 +1252,29 @@ BOOL CGetSetOptions::GetDrawRTF()
 	return GetProfileLong("DrawRTF", FALSE);
 }
 
+void CGetSetOptions::SetMultiPasteReverse(bool bVal)
+{
+	SetProfileLong("MultiPasteReverse", bVal); 
+	m_bMultiPasteReverse = bVal;
+}
+
+BOOL CGetSetOptions::GetMultiPasteReverse()
+{
+	return GetProfileLong("MultiPasteReverse", TRUE); 
+}
+
+void CGetSetOptions::SetPlaySoundOnCopy(CString cs)
+{
+	m_csPlaySoundOnCopy = cs;
+
+	SetProfileString("PlaySoundOnCopy", cs);
+}
+
+CString CGetSetOptions::GetPlaySoundOnCopy()
+{
+	return GetProfileString("PlaySoundOnCopy", "");
+}
+
 /*------------------------------------------------------------------*\
 CHotKey - a single system-wide hotkey
 \*------------------------------------------------------------------*/
@@ -2028,3 +2112,47 @@ void CPopup::Hide()
 	m_bIsShowing = false;
 }
 
+#include "Encryption.h"
+#define STRING_PASSWORD "*4ei)"
+BOOL EncryptString(CString &csIn, UCHAR *&pOutput, int &nLenOutput)
+{
+	BOOL bRet = FALSE;
+	CEncryption *pEncryptor;
+
+	pEncryptor = new CEncryption;
+
+	if(pEncryptor)
+	{
+		UCHAR *pData = (UCHAR*)csIn.GetBuffer(csIn.GetLength());
+
+		nLenOutput = 0;
+		if(pEncryptor->Encrypt(pData, csIn.GetLength(), STRING_PASSWORD, pOutput, nLenOutput))
+		{
+			bRet = TRUE;
+		}
+
+		delete pEncryptor;
+	}
+
+	return bRet;
+}
+
+BOOL DecryptString(UCHAR *pData, int nLenIn, UCHAR *&pOutput, int &nLenOutput)
+{
+	BOOL bRet = FALSE;
+	CEncryption *pEncryptor;
+
+	pEncryptor = new CEncryption;
+
+	if(pEncryptor)
+	{
+		if(pEncryptor->Decrypt(pData, nLenIn, STRING_PASSWORD, pOutput, nLenOutput))
+		{
+			bRet = TRUE;
+		}
+
+		delete pEncryptor;
+	}
+
+	return bRet;
+}

+ 12 - 0
Misc.h

@@ -62,6 +62,8 @@ HGLOBAL NewGlobal(UINT nLen);
 int CompareGlobalHP( HGLOBAL hLeft, LPVOID pBuf, ULONG ulBufLen );
 int CompareGlobalHH( HGLOBAL hLeft, HGLOBAL hRight, ULONG ulBufLen );
 
+BOOL EncryptString(CString &csString, UCHAR*& pOutput, int &nLenOutput);
+BOOL DecryptString(UCHAR *pData, int nLenIn, UCHAR*& pOutput, int &nLenOutput);
 
 int GetScreenWidth();
 int GetScreenHeight();
@@ -318,6 +320,16 @@ public:
 	static void		SetDrawRTF(long bDraw);
 	static BOOL		GetDrawRTF();
 
+	static BOOL		m_bMultiPasteReverse;
+	static void		SetMultiPasteReverse(bool bVal);
+	static BOOL		GetMultiPasteReverse();
+
+	static CString	m_csPlaySoundOnCopy;
+	static void		SetPlaySoundOnCopy(CString cs);
+	static CString	GetPlaySoundOnCopy();
+
+	static CStringArray m_csNetworkPasswordArray;
+
 	/*
 	BOOL IsAutoRun();
 	void SetAutoRun(BOOL bRun);

+ 7 - 0
OptionFriends.cpp

@@ -23,6 +23,7 @@ COptionFriends::COptionFriends() : CPropertyPage(COptionFriends::IDD)
 {
 	//{{AFX_DATA_INIT(COptionFriends)
 	m_PlaceOnClipboard = _T("");
+	m_csPassword = _T("");
 	//}}AFX_DATA_INIT
 }
 
@@ -38,6 +39,7 @@ void COptionFriends::DoDataExchange(CDataExchange* pDX)
 	DDX_Control(pDX, IDC_CHECK_LOG_SEND_RECIEVE, m_SendRecieve);
 	DDX_Control(pDX, IDC_LIST, m_List);
 	DDX_Text(pDX, IDC_EDIT_PLACE_ON_CLIPBOARD, m_PlaceOnClipboard);
+	DDX_Text(pDX, IDC_EDIT_PASSWORD, m_csPassword);
 	//}}AFX_DATA_MAP
 }
 
@@ -71,6 +73,8 @@ BOOL COptionFriends::OnInitDialog()
 
 	m_PlaceOnClipboard = g_Opt.m_csIPListToPutOnClipboard;
 
+	m_csPassword = "[Not Shown]";
+
 	UpdateData(FALSE);
 		
 	return FALSE;
@@ -107,6 +111,9 @@ BOOL COptionFriends::OnApply()
 
 	g_Opt.SetListToPutOnClipboard(m_PlaceOnClipboard);
 
+	if(m_csPassword != "[Not Shown]")
+		g_Opt.SetNetworkPassword(m_csPassword);
+
 	g_Opt.GetClientSendCount();
 	
 	return CPropertyPage::OnApply();

+ 1 - 0
OptionFriends.h

@@ -27,6 +27,7 @@ public:
 	CButton	m_SendRecieve;
 	CListCtrl	m_List;
 	CString	m_PlaceOnClipboard;
+	CString	m_csPassword;
 	//}}AFX_DATA
 
 

+ 50 - 0
OptionsGeneral.cpp

@@ -6,6 +6,7 @@
 #include "OptionsGeneral.h"
 #include "InternetUpdate.h"
 #include <io.h>
+#include <Mmsystem.h> //play sound
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -21,6 +22,7 @@ IMPLEMENT_DYNCREATE(COptionsGeneral, CPropertyPage)
 COptionsGeneral::COptionsGeneral() : CPropertyPage(COptionsGeneral::IDD)
 {
 	//{{AFX_DATA_INIT(COptionsGeneral)
+	m_csPlaySound = _T("");
 	//}}AFX_DATA_INIT
 }
 
@@ -45,6 +47,7 @@ void COptionsGeneral::DoDataExchange(CDataExchange* pDX)
 	DDX_Control(pDX, IDC_EXPIRE, m_btExpire);
 	DDX_Control(pDX, IDC_DISPLAY_IN_SYSTEMTRAY, m_btShowIconInSysTray);
 	DDX_Control(pDX, IDC_START_ON_STARTUP, m_btRunOnStartup);
+	DDX_Text(pDX, IDC_EDIT_PLAY_SOUND, m_csPlaySound);
 	//}}AFX_DATA_MAP
 	DDX_Control(pDX, IDC_ALLOW_DUPLICATES, m_btAllowDuplicates);
 	DDX_Control(pDX, IDC_UPDATE_TIME_ON_PASTE, m_btUpdateTimeOnPaste);
@@ -58,6 +61,8 @@ BEGIN_MESSAGE_MAP(COptionsGeneral, CPropertyPage)
 	ON_BN_CLICKED(IDC_CHECK_FOR_UPDATES, OnCheckForUpdates)
 	ON_BN_CLICKED(IDC_SET_DB_PATH, OnSetDbPath)
 	ON_BN_CLICKED(IDC_GET_PATH, OnGetPath)
+	ON_BN_CLICKED(IDC_SELECT_SOUND, OnSelectSound)
+	ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -100,6 +105,10 @@ BOOL COptionsGeneral::OnInitDialog()
 		m_ePath.SetWindowText(csPath);
 	}
 
+	m_csPlaySound = g_Opt.m_csPlaySoundOnCopy;
+
+	UpdateData(FALSE);
+
 	return TRUE;
 }
 
@@ -121,6 +130,8 @@ BOOL COptionsGeneral::OnApply()
 	CGetSetOptions::SetExpiredEntries(m_eExpireAfter.GetNumber());
 	CGetSetOptions::SetDescTextSize(m_DescTextSize.GetNumber());
 
+	CGetSetOptions::SetPlaySoundOnCopy(m_csPlaySound);
+
 	g_Opt.SetAllowDuplicates( m_btAllowDuplicates.GetCheck() );
 	g_Opt.SetUpdateTimeOnPaste( m_btUpdateTimeOnPaste.GetCheck() );
 	g_Opt.SetSaveMultiPaste( m_btSaveMultiPaste.GetCheck() );
@@ -247,3 +258,42 @@ void COptionsGeneral::OnGetPath()
 	else
 		m_ePath.SetWindowText(csPath);	
 }
+
+void COptionsGeneral::OnSelectSound() 
+{
+	OPENFILENAME	FileName;
+
+	char			szFileName[400];
+	char			szDir[400];
+
+	memset(&FileName, 0, sizeof(FileName));
+	memset(szFileName, 0, sizeof(szFileName));
+	memset(&szDir, 0, sizeof(szDir));
+
+	FileName.lStructSize = sizeof(FileName);
+
+	FileName.lpstrTitle = "Select .wav file";
+	FileName.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST;
+	FileName.nMaxFile = 400;
+	FileName.lpstrFile = szFileName;
+	FileName.lpstrInitialDir = szDir;
+	FileName.lpstrFilter = "Sounds(*.wav)\0*.wav";
+	FileName.lpstrDefExt = "wav";
+
+	if(GetOpenFileName(&FileName) == 0)
+		return;
+
+	CString	csPath(FileName.lpstrFile);
+
+	if(csPath.GetLength())
+		m_csPlaySound = csPath;
+
+	UpdateData(FALSE);
+}
+
+void COptionsGeneral::OnButtonPlay() 
+{
+	UpdateData();
+
+	PlaySound(m_csPlaySound, NULL, SND_FILENAME|SND_ASYNC);
+}

+ 3 - 0
OptionsGeneral.h

@@ -43,6 +43,7 @@ public:
 	CButton m_btAllowDuplicates;
 	CButton m_btUpdateTimeOnPaste;
 	CButton m_btSaveMultiPaste;
+	CString	m_csPlaySound;
 	//}}AFX_DATA
 
 
@@ -68,6 +69,8 @@ protected:
 	afx_msg void OnCheckForUpdates();
 	afx_msg void OnSetDbPath();
 	afx_msg void OnGetPath();
+	afx_msg void OnSelectSound();
+	afx_msg void OnButtonPlay();
 	//}}AFX_MSG
 	DECLARE_MESSAGE_MAP()
 

+ 5 - 0
ProcessCopy.cpp

@@ -8,6 +8,8 @@
 #include "DatabaseUtilities.h"
 #include ".\processcopy.h"
 
+#include <Mmsystem.h>
+
 #ifdef _DEBUG
 #undef THIS_FILE
 static char THIS_FILE[]=__FILE__;
@@ -418,6 +420,9 @@ bool CClip::AddToDB( bool bCheckForDuplicates )
 		
 		// AddToDataTable must go first in order to assign m_DataID
 		bResult = AddToDataTable() && AddToMainTable();
+
+	if(g_Opt.m_csPlaySoundOnCopy.GetLength() > 0)
+		PlaySound(g_Opt.m_csPlaySoundOnCopy, NULL, SND_FILENAME|SND_ASYNC);
 	
 	// should be emptied by AddToDataTable
 	ASSERT( m_Formats.GetSize() == 0 );

+ 42 - 13
ProcessPaste.cpp

@@ -341,11 +341,12 @@ CClipIDs
 HGLOBAL CClipIDs::Render( UINT cfType )
 {
 	int count = GetSize();
-	if( count <= 0 )
+	if(count <= 0)
 		return 0;
-	if( count == 1 )
-		return CClip::LoadFormat( ElementAt(0), cfType );
-	CString text = AggregateText( CF_TEXT, "\r\n" );
+	if(count == 1)
+		return CClip::LoadFormat(ElementAt(0), cfType);
+	CString text = AggregateText(CF_TEXT, "\r\n", g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop);
+
 	return NewGlobalP( (void*)(LPCSTR) text, text.GetLength()+1 );
 }
 
@@ -362,7 +363,7 @@ void CClipIDs::GetTypes( CClipTypes& types )
 // Aggregates the cfType Format Data of the Clip IDs in this array, assuming
 //  each Format is NULL terminated and placing pSeparator between them.
 // This assumes that the given cfType is a null terminated text type.
-CString CClipIDs::AggregateText( UINT cfType, char* pSeparator )
+CString CClipIDs::AggregateText(UINT cfType, char* pSeparator, BOOL bReverse)
 {
 	CString csSQL;
 	CDataTable recset;
@@ -370,6 +371,8 @@ CString CClipIDs::AggregateText( UINT cfType, char* pSeparator )
 	char* pData = NULL;
 	DWORD len;
 	DWORD maxLen;
+
+	CLIPFORMAT cfRTF = GetFormatID(CF_RTF);
 	
 	// maybe we should sum up the "recset.m_ooData.m_dwDataLength" of all IDs first
 	//  in order to determine the max space required??  Or would that be wastefull?
@@ -390,9 +393,16 @@ CString CClipIDs::AggregateText( UINT cfType, char* pSeparator )
 	
 	try
 	{
+		int nIndex;
 		for( int i=0; i < numIDs; i++ )
 		{
-			recset.Open( csSQL, pIDs[i] );
+			nIndex = i;
+			if(bReverse)
+			{
+				nIndex = numIDs - i - 1;
+			}
+
+			recset.Open( csSQL, pIDs[nIndex] );
 			if( !recset.IsBOF() && !recset.IsEOF() )
 			{
 				maxLen = recset.m_ooData.m_dwDataLength;
@@ -410,19 +420,29 @@ CString CClipIDs::AggregateText( UINT cfType, char* pSeparator )
 					if( len >= maxLen )
 						continue;
 				}
-				
+
+//				if(i == 0 && cfType == cfRTF)
+//				{
+//					pData[maxLen-2] = '\0';
+//				}
+
 				text += pData;
 				GlobalUnlock(recset.m_ooData.m_hData);
 				
 				if( pSeparator )
 					text += pSeparator;
+
+//				if((i == numIDs-1) && cfType == cfRTF)
+//				{
+//					text += "}";
+//				}
 			}
 			recset.Close();
 		}
 	}
 	CATCHDAO
 		
-		return text;
+	return text;
 }
 
 //----------------------------------------------
@@ -729,9 +749,9 @@ BOOL COleClipSource::DoImmediateRender()
 	m_bLoadedFormats = true;
 	
 	int count = m_ClipIDs.GetSize();
-	if( count <= 0 )
+	if(count <= 0)
 		return 0;
-	if( count == 1 )
+	if(count == 1)
 	{
 		CClipFormats formats;
 		
@@ -741,9 +761,18 @@ BOOL COleClipSource::DoImmediateRender()
 	}
 	
 	HGLOBAL hGlobal;
-	CString text = m_ClipIDs.AggregateText( CF_TEXT, "\r\n" );
-	hGlobal = NewGlobalP( (void*)(LPCSTR) text, text.GetLength()+1 );
-	CacheGlobalData( CF_TEXT, hGlobal );
+	
+	CString text = m_ClipIDs.AggregateText(CF_TEXT, "\r\n", g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop);
+	hGlobal = NewGlobalP((void*)(LPCSTR) text, text.GetLength()+1);
+	CacheGlobalData(CF_TEXT, hGlobal);
+	
+//	text = "{\rtf1";
+//	text += m_ClipIDs.AggregateText(GetFormatID(CF_RTF), "\r\n", true);
+//	text += "}";
+//	
+//	hGlobal = NewGlobalP((void*)(LPCSTR) text, text.GetLength()+1);
+//	CacheGlobalData(GetFormatID(CF_RTF), hGlobal);
+
 	return hGlobal != 0;
 }
 

+ 3 - 3
ProcessPaste.h

@@ -48,12 +48,12 @@ public:
 // PASTING FUNCTIONS
 
 	// allocate an HGLOBAL of the given Format Type representing the Clip IDs in this array.
-	HGLOBAL	Render( UINT cfType );
+	HGLOBAL	Render(UINT cfType);
 	// Fills "types" with the Format Types corresponding to the Clip IDs in this array.
-	void GetTypes( CClipTypes& types );
+	void GetTypes(CClipTypes& types);
 	// Aggregates the cfType Format Data of the Clip IDs in this array, assuming
 	//  each Format is NULL terminated and placing pSeparator between them.
-	CString AggregateText( UINT cfType, char* pSeparator );
+	CString AggregateText(UINT cfType, char* pSeparator, BOOL bReverse = FALSE);
 
 // MANAGEMENT FUNCTIONS
 

+ 5 - 3
QListCtrl.cpp

@@ -446,9 +446,9 @@ void CQListCtrl::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
 			pDC->DrawText(strSymbols, &rectSym, DT_VCENTER | DT_EXPANDTABS | DT_CALCRECT);
 			VERIFY( rectSpace.Width() > 0 );
 			
-			int numSpaces = rectSym.Width() / rectSpace.Width();
-			numSpaces++;
-			csText = CString(' ',numSpaces) + csText;
+//			int numSpaces = rectSym.Width() / rectSpace.Width();
+//			numSpaces++;
+//			csText = CString(' ',numSpaces) + csText;
 			
 			// draw the symbols
 			pDC->FillSolidRect( rectSym, GetSysColor(COLOR_ACTIVECAPTION) );
@@ -458,6 +458,8 @@ void CQListCtrl::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
 			COLORREF crOld = pDC->SetTextColor(RGB(255, 255, 255));
 			pDC->DrawText(strSymbols, rectSym, DT_VCENTER | DT_EXPANDTABS);
 			pDC->SetTextColor(crOld);
+
+			rcText.left += rectSym.Width() + 2;
 		}
 		
 		if(DrawText(nItem, rcText, pDC) == FALSE)

BIN
Release/focus.dll


BIN
Release/focus.lib


+ 5 - 1
Resource.h

@@ -35,6 +35,7 @@
 #define IDD_MOVE_TO_GROUP               156
 #define IDC_PATH                        1000
 #define IDC_GET_PATH                    1001
+#define IDC_SELECT_SOUND                1002
 #define IDC_SELECT                      1003
 #define IDC_TRIP_COPIES                 1004
 #define IDC_TRIP_PASTES                 1005
@@ -133,7 +134,10 @@
 #define IDC_HOTKEY8                     2031
 #define IDC_BUTTON_DEFAULT_FAULT        2031
 #define IDC_HOTKEY9                     2032
+#define IDC_EDIT_PASSWORD               2032
 #define IDC_HOTKEY10                    2033
+#define IDC_EDIT_PLAY_SOUND             2033
+#define IDC_BUTTON_PLAY                 2034
 #define ID_FIRST_OPTION                 32771
 #define ID_FIRST_EXIT                   32772
 #define ID_FIRST_SHOWQUICKPASTE         32773
@@ -214,7 +218,7 @@
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        157
 #define _APS_NEXT_COMMAND_VALUE         32847
-#define _APS_NEXT_CONTROL_VALUE         2032
+#define _APS_NEXT_CONTROL_VALUE         2035
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

+ 154 - 30
Server.cpp

@@ -79,7 +79,95 @@ UINT  MTServerThread(LPVOID pParam)
 	return 0;
 }
 
-BOOL RecieveExactSize(SOCKET sock, char *pData, long lSize)
+CRecieveSocket::CRecieveSocket(SOCKET sk)
+{
+	m_pDataReturnedFromDecrypt = NULL;
+	m_Socket = sk;
+	m_pEncryptor = new CEncryption; //CreateEncryptionInterface("encryptdecrypt.dll");
+}
+
+CRecieveSocket::~CRecieveSocket()
+{
+	if(m_pEncryptor)
+	{
+		m_pEncryptor->FreeBuffer(m_pDataReturnedFromDecrypt);
+
+		delete m_pEncryptor;
+		m_pEncryptor = NULL;
+		//ReleaseEncryptionInterface(m_pEncryptor);
+	}
+	closesocket(m_Socket);
+}
+
+void CRecieveSocket::FreeDecryptedData()
+{ 
+	if(g_Opt.m_csPassword == "")
+	{
+		delete [] m_pDataReturnedFromDecrypt;
+	}
+	else
+	{
+		m_pEncryptor->FreeBuffer(m_pDataReturnedFromDecrypt);
+	}
+	m_pDataReturnedFromDecrypt = NULL;
+}
+
+LPVOID CRecieveSocket::ReceiveEncryptedData(long lInSize, long &lOutSize)
+{
+	if(m_pEncryptor == NULL)
+	{
+		LogSendRecieveInfo("ReceiveEncryptedData::Encryption not initialized");
+		return NULL;
+	}
+
+	if(m_pDataReturnedFromDecrypt)
+		FreeDecryptedData();
+
+	char *pInput = new char[lInSize];
+
+	UCHAR* pOutput = NULL;
+	
+	if(pInput)
+	{
+		RecieveExactSize(pInput, lInSize);
+
+		int nOut = 0;
+		CString csPassword;
+		int nCount = g_Opt.m_csNetworkPasswordArray.GetSize() + 1;
+		for(int i = -1; i < nCount; i++)
+		{
+			if(i == -1)
+				csPassword = g_Opt.m_csPassword;
+			else
+				csPassword = g_Opt.m_csNetworkPasswordArray[i];
+
+			if(m_pEncryptor->Decrypt((UCHAR*)pInput, lInSize, csPassword, pOutput, nOut) == FALSE)
+			{
+				LogSendRecieveInfo(StrF("ReceiveEncryptedData:: Failed to Decrypt data password = %s", g_Opt.m_csPassword));
+			}
+			else
+			{
+				break;
+			}
+		}
+
+		lOutSize = nOut;
+
+		delete [] pInput;
+		pInput = NULL;
+	}	
+	else
+	{
+		ASSERT(FALSE);
+		LogSendRecieveInfo(StrF("ReceiveEncryptedData:: Failed to create new data size = %d", lInSize));
+	}
+
+	m_pDataReturnedFromDecrypt = pOutput;
+
+	return pOutput;
+}
+
+BOOL CRecieveSocket::RecieveExactSize(char *pData, long lSize)
 {
 	long lReceiveCount = 0;
 
@@ -88,35 +176,46 @@ BOOL RecieveExactSize(SOCKET sock, char *pData, long lSize)
 
 	while(lWanted > 0)
 	{
-		lReceiveCount = recv(sock, pData + lOffset, lWanted, 0);
+		lReceiveCount = recv(m_Socket, pData + lOffset, lWanted, 0);
 		if(lReceiveCount == SOCKET_ERROR)
 		{
-			LogSendRecieveInfo("********ERROR if(lReceiveCount == SOCKET_ERROR)*******");
+			LogSendRecieveInfo("RecieveExactSize:: ********ERROR if(lReceiveCount == SOCKET_ERROR)*******");
 			return FALSE;
 		}
 		else if(lReceiveCount == 0)
 		{
-			LogSendRecieveInfo("********ERROR lRecieveCount == 0");
+			LogSendRecieveInfo("RecieveExactSize:: ********ERROR lRecieveCount == 0");
 			return FALSE;
 		}
 
-		LogSendRecieveInfo(StrF("------Bytes Read %d Total Recieved %d", lReceiveCount, lOffset));
+		LogSendRecieveInfo(StrF("RecieveExactSize:: ------Bytes Read %d Total Recieved %d", lReceiveCount, lOffset));
 
 		lWanted -= lReceiveCount;
 		lOffset += lReceiveCount;
 	}
 
-	LogSendRecieveInfo(StrF("------END RecieveExactSize Recieved %d", lOffset));
+	LogSendRecieveInfo(StrF("RecieveExactSize:: ------END RecieveExactSize Recieved %d", lOffset));
 
 	return TRUE;
 }
 
-BOOL RecieveCSendInfo(SOCKET sock, CSendInfo *pInfo)
+#define ENCRYPTED_SIZE_CSENDINFO 508
+
+BOOL CRecieveSocket::RecieveCSendInfo(CSendInfo *pInfo)
 {
-	BOOL bRet = RecieveExactSize(sock, (char*)pInfo, sizeof(CSendInfo));
-	if(bRet)
+	BOOL bRet = FALSE;
+	long lOutSize = 0;
+
+	long lRecieveSize = ENCRYPTED_SIZE_CSENDINFO;
+
+	LPVOID lpData = ReceiveEncryptedData(lRecieveSize, lOutSize);
+	if(lpData)
 	{
-		bRet = pInfo->m_nSize == sizeof(CSendInfo);
+		memcpy(pInfo, lpData, sizeof(CSendInfo));
+
+		bRet = (pInfo->m_nSize == sizeof(CSendInfo));
+
+		FreeDecryptedData();
 	}
 
 	return bRet;
@@ -126,7 +225,7 @@ UINT  ClientThread(LPVOID pParam)
 {	
 	LogSendRecieveInfo("*********************Start of ClientThread*********************");
 	
-	SOCKET socket = (SOCKET)pParam;
+	CRecieveSocket Sock((SOCKET)pParam);
 
 	CClipList *pClipList = NULL;
 	CClip *pClip = NULL;
@@ -137,7 +236,7 @@ UINT  ClientThread(LPVOID pParam)
 	
 	while(true)
 	{
-		if(RecieveCSendInfo(socket, &info) == FALSE)
+		if(Sock.RecieveCSendInfo(&info) == FALSE)
 			break;
 		
 		switch(info.m_Type)
@@ -175,23 +274,43 @@ UINT  ClientThread(LPVOID pParam)
 		case MyEnums::DATA_START:
 			{
 				LogSendRecieveInfo("::DATA_START -- START");
-				cf.m_hgData = NewGlobal(info.m_lParameter1);
-				cf.m_cfType = GetFormatID(info.m_cDesc);
-
-				LogSendRecieveInfo(StrF("::--------DATA_START Total Size = %d type = %s", info.m_lParameter1, info.m_cDesc));
 
-				if(pClip)
-					pClip->m_lTotalCopySize += info.m_lParameter1;
-
-				LogSendRecieveInfo("::--------Before RecieveExactSize");
-				LPVOID pvData = GlobalLock(cf.m_hgData);
+				cf.m_cfType = GetFormatID(info.m_cDesc);
+				cf.m_hgData = 0;
 				
-				//Recieve the clip data
-				if(RecieveExactSize(socket, (char*)pvData, info.m_lParameter1) == FALSE)
-					bBreak = true;
-
-				GlobalUnlock(cf.m_hgData);
-				LogSendRecieveInfo("::--------After RecieveExactSize");
+				long lInSize = info.m_lParameter1;
+				long lOutSize = 0;
+
+				LPVOID lpData = Sock.ReceiveEncryptedData(lInSize, lOutSize);
+
+				if(lpData && lOutSize > 0)
+				{					
+					cf.m_hgData = NewGlobal(lOutSize);
+
+					if(cf.m_hgData)
+					{
+						if(pClip)
+							pClip->m_lTotalCopySize += lOutSize;
+
+						LPVOID pvData = GlobalLock(cf.m_hgData);
+						if(pvData)
+						{
+							memcpy(pvData, lpData, lOutSize);
+
+							GlobalUnlock(cf.m_hgData);
+						}
+						else
+						{
+							LogSendRecieveInfo("::DATA_START -- failed to lock hGlobal");
+						}
+					}
+					else
+					{
+						LogSendRecieveInfo("::DATA_START -- failed to create new hGlobal");
+					}
+
+					Sock.FreeDecryptedData();
+				}
 
 				LogSendRecieveInfo("::DATA_START -- END");
 			}
@@ -200,11 +319,15 @@ UINT  ClientThread(LPVOID pParam)
 			{
 				LogSendRecieveInfo("::DATA_END");
 				
-				if(pClip)
+				if(pClip && cf.m_hgData)
 				{
 					pClip->m_Formats.Add(cf);
 					cf.m_hgData = 0; // now owned by pClip
 				}
+				else
+				{
+					LogSendRecieveInfo("MyEnums::DATA_END Error if(pClip && cf.m_hgData)");
+				}
 			}
 			break;
 		case MyEnums::END:
@@ -241,6 +364,9 @@ UINT  ClientThread(LPVOID pParam)
 				bBreak = true;
 			}
 			break;
+		default:
+			LogSendRecieveInfo("::ERROR unknown action type exiting");
+			bBreak = true;
 		}
 
 		if(bBreak || theApp.m_bAppExiting)
@@ -263,8 +389,6 @@ UINT  ClientThread(LPVOID pParam)
 		LogSendRecieveInfo("::ERROR pClip was not NULL something is wrong");
 	}
 
-	closesocket(socket);
-
 	LogSendRecieveInfo("*********************End of ClientThread*********************");
 	
 	return 0;

+ 21 - 0
Server.h

@@ -10,6 +10,7 @@
 #endif // _MSC_VER > 1000
 
 #include "Winsock2.h"
+#include "Encryption.h"
 
 class MyEnums
 {
@@ -38,6 +39,26 @@ public:
 	char				m_cExtra[50];
 };
 
+class CRecieveSocket
+{
+public:
+	CRecieveSocket(SOCKET sk);
+
+	~CRecieveSocket();
+	
+	LPVOID ReceiveEncryptedData(long lInSize, long &lOutSize);
+	BOOL RecieveExactSize(char *pData, long lSize);
+	BOOL RecieveCSendInfo(CSendInfo *pInfo);
+
+	void FreeDecryptedData();
+
+protected:
+	CEncryption *m_pEncryptor;
+	SOCKET m_Socket;
+	UCHAR *m_pDataReturnedFromDecrypt;
+	
+};
+
 UINT  MTServerThread(LPVOID pParam);
 UINT  ClientThread(LPVOID pParam);
 

+ 4 - 2
focusdll/focus.dsp

@@ -40,6 +40,7 @@ RSC=rc.exe
 # PROP Use_Debug_Libraries 0
 # PROP Output_Dir "Release"
 # PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOCUS_EXPORTS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOCUS_EXPORTS" /YX /FD /c
@@ -52,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib Winmm.lib /nologo /dll /machine:I386
 # Begin Special Build Tool
 OutDir=.\Release
 SOURCE="$(InputPath)"
@@ -70,6 +71,7 @@ PostBuild_Cmds=copy $(OutDir)\*.lib ..\Release	copy $(OutDir)\*.dll ..\Release
 # PROP Use_Debug_Libraries 1
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOCUS_EXPORTS" /YX /FD /GZ /c
 # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOCUS_EXPORTS" /YX /FD /GZ /c
@@ -82,7 +84,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib Winmm.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
 # Begin Special Build Tool
 OutDir=.\Debug
 SOURCE="$(InputPath)"