Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Crypto')
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.cpp305
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.dsp245
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.dsw29
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.h122
-rwxr-xr-xCPP/7zip/Crypto/7zAES/DllExports.cpp111
-rwxr-xr-xCPP/7zip/Crypto/7zAES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/7zAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/7zAES/makefile52
-rwxr-xr-xCPP/7zip/Crypto/7zAES/resource.rc3
-rwxr-xr-xCPP/7zip/Crypto/AES/AES.dsp203
-rwxr-xr-xCPP/7zip/Crypto/AES/AES.dsw29
-rwxr-xr-xCPP/7zip/Crypto/AES/AES_CBC.h39
-rwxr-xr-xCPP/7zip/Crypto/AES/DllExports.cpp100
-rwxr-xr-xCPP/7zip/Crypto/AES/MyAES.cpp94
-rwxr-xr-xCPP/7zip/Crypto/AES/MyAES.h106
-rwxr-xr-xCPP/7zip/Crypto/AES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/AES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/AES/aes.h103
-rwxr-xr-xCPP/7zip/Crypto/AES/aescpp.h55
-rwxr-xr-xCPP/7zip/Crypto/AES/aescrypt.c421
-rwxr-xr-xCPP/7zip/Crypto/AES/aeskey.c363
-rwxr-xr-xCPP/7zip/Crypto/AES/aesopt.h839
-rwxr-xr-xCPP/7zip/Crypto/AES/aestab.c494
-rwxr-xr-xCPP/7zip/Crypto/AES/makefile31
-rwxr-xr-xCPP/7zip/Crypto/AES/resource.rc3
-rwxr-xr-xCPP/7zip/Crypto/Codec.def4
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.cpp109
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.h39
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp83
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.cpp78
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RotateDefs.h19
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.h68
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.h30
-rwxr-xr-xCPP/7zip/Crypto/Hash/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Cipher.cpp76
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Cipher.h35
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Crypto.cpp124
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Crypto.h33
-rwxr-xr-xCPP/7zip/Crypto/Rar20/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/RarAES/RarAES.cpp187
-rwxr-xr-xCPP/7zip/Crypto/RarAES/RarAES.h61
-rwxr-xr-xCPP/7zip/Crypto/RarAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/WzAES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/WzAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/WzAES/WzAES.cpp246
-rwxr-xr-xCPP/7zip/Crypto/WzAES/WzAES.h126
-rwxr-xr-xCPP/7zip/Crypto/Zip/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCipher.cpp85
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCipher.h59
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCrypto.cpp65
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCrypto.h26
-rwxr-xr-xCPP/7zip/Crypto/makefile8
56 files changed, 5835 insertions, 0 deletions
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.cpp b/CPP/7zip/Crypto/7zAES/7zAES.cpp
new file mode 100755
index 00000000..843d9027
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.cpp
@@ -0,0 +1,305 @@
+// 7z_AES.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "Windows/Synchronization.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+
+#include "7zAES.h"
+// #include "../../Hash/Common/CryptoHashInterface.h"
+
+#ifdef CRYPTO_AES
+#include "../AES/MyAES.h"
+#endif
+
+#include "../Hash/Sha256.h"
+
+using namespace NWindows;
+
+#ifndef CRYPTO_AES
+extern HINSTANCE g_hInstance;
+#endif
+
+namespace NCrypto {
+namespace NSevenZ {
+
+bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const
+{
+ if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)
+ return false;
+ for (UInt32 i = 0; i < SaltSize; i++)
+ if (Salt[i] != a.Salt[i])
+ return false;
+ return (Password == a.Password);
+}
+
+void CKeyInfo::CalculateDigest()
+{
+ if (NumCyclesPower == 0x3F)
+ {
+ UInt32 pos;
+ for (pos = 0; pos < SaltSize; pos++)
+ Key[pos] = Salt[pos];
+ for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++)
+ Key[pos++] = Password[i];
+ for (; pos < kKeySize; pos++)
+ Key[pos] = 0;
+ }
+ else
+ {
+ NCrypto::NSha256::CContext sha;
+ const UInt64 numRounds = UInt64(1) << (NumCyclesPower);
+ Byte temp[8] = { 0,0,0,0,0,0,0,0 };
+ for (UInt64 round = 0; round < numRounds; round++)
+ {
+ sha.Update(Salt, SaltSize);
+ sha.Update(Password, Password.GetCapacity());
+ sha.Update(temp, 8);
+ for (int i = 0; i < 8; i++)
+ if (++(temp[i]) != 0)
+ break;
+ }
+ sha.Final(Key);
+ }
+}
+
+bool CKeyInfoCache::Find(CKeyInfo &key)
+{
+ for (int i = 0; i < Keys.Size(); i++)
+ {
+ const CKeyInfo &cached = Keys[i];
+ if (key.IsEqualTo(cached))
+ {
+ for (int j = 0; j < kKeySize; j++)
+ key.Key[j] = cached.Key[j];
+ if (i != 0)
+ {
+ Keys.Insert(0, cached);
+ Keys.Delete(i+1);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+void CKeyInfoCache::Add(CKeyInfo &key)
+{
+ if (Find(key))
+ return;
+ if (Keys.Size() >= Size)
+ Keys.DeleteBack();
+ Keys.Insert(0, key);
+}
+
+static CKeyInfoCache g_GlobalKeyCache(32);
+static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection;
+
+CBase::CBase():
+ _cachedKeys(16)
+{
+ for (int i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+}
+
+void CBase::CalculateDigest()
+{
+ NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection);
+ if (_cachedKeys.Find(_key))
+ g_GlobalKeyCache.Add(_key);
+ else
+ {
+ if (!g_GlobalKeyCache.Find(_key))
+ {
+ _key.CalculateDigest();
+ g_GlobalKeyCache.Add(_key);
+ }
+ _cachedKeys.Add(_key);
+ }
+}
+
+
+/*
+static void GetRandomData(Byte *data)
+{
+ // probably we don't need truly random.
+ // it's enough to prevent dictionary attack;
+ // but it gives some info about time when compressing
+ // was made.
+ UInt64 tempValue;
+ SYSTEMTIME systemTime;
+ FILETIME fileTime;
+ ::GetSystemTime(&systemTime);
+ ::SystemTimeToFileTime(&systemTime, &fileTime);
+ tempValue = *(const UInt64 *)&fileTime;
+ LARGE_INTEGER counter;
+ ::QueryPerformanceCounter(&counter);
+ tempValue += *(const UInt64 *)&counter;
+ tempValue += (UInt64)(GetTickCount()) << 32;
+ *(UInt64 *)data = tempValue;
+}
+*/
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ _key.Init();
+ for (UInt32 i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+
+ _key.SaltSize = 0;
+
+ // _key.SaltSize = 8;
+ // GetRandomData(_key.Salt);
+
+ int ivSize = 0;
+
+ // _key.NumCyclesPower = 0x3F;
+ _key.NumCyclesPower = 18;
+
+ Byte firstByte = (Byte)(_key.NumCyclesPower |
+ (((_key.SaltSize == 0) ? 0 : 1) << 7) |
+ (((ivSize == 0) ? 0 : 1) << 6));
+ RINOK(outStream->Write(&firstByte, 1, NULL));
+ if (_key.SaltSize == 0 && ivSize == 0)
+ return S_OK;
+ Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1));
+ Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1));
+ Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec);
+ RINOK(outStream->Write(&secondByte, 1, NULL));
+ if (_key.SaltSize > 0)
+ {
+ RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL));
+ }
+ if (ivSize > 0)
+ {
+ RINOK(WriteStream(outStream, _iv, ivSize, NULL));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ _key.Init();
+ UInt32 i;
+ for (i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+ if (size == 0)
+ return S_OK;
+ UInt32 pos = 0;
+ Byte firstByte = data[pos++];
+
+ _key.NumCyclesPower = firstByte & 0x3F;
+ if ((firstByte & 0xC0) == 0)
+ return S_OK;
+ _key.SaltSize = (firstByte >> 7) & 1;
+ UInt32 ivSize = (firstByte >> 6) & 1;
+
+ if (pos >= size)
+ return E_INVALIDARG;
+ Byte secondByte = data[pos++];
+
+ _key.SaltSize += (secondByte >> 4);
+ ivSize += (secondByte & 0x0F);
+
+ if (pos + _key.SaltSize + ivSize > size)
+ return E_INVALIDARG;
+ for (i = 0; i < _key.SaltSize; i++)
+ _key.Salt[i] = data[pos++];
+ for (i = 0; i < ivSize; i++)
+ _iv[i] = data[pos++];
+ return S_OK;
+}
+
+STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _key.Password.SetCapacity(size);
+ memcpy(_key.Password, data, size);
+ return S_OK;
+}
+
+/*
+static Byte *WideToRaw(const wchar_t *src, Byte *dest, int destSize=0x10000000)
+{
+ for (int i = 0; i < destSize; i++, src++)
+ {
+ dest[i * 2] = (Byte)*src;
+ dest[i * 2 + 1]= (Byte)(*src >> 8);
+ if (*src == 0)
+ break;
+ }
+ return(dest);
+}
+*/
+
+#ifndef CRYPTO_AES
+bool GetAESLibPath(TCHAR *path)
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0)
+ return false;
+ LPTSTR fileNamePointer;
+ DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1,
+ path, &fileNamePointer);
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ lstrcpy(fileNamePointer, TEXT("AES.dll"));
+ return true;
+}
+#endif
+
+STDMETHODIMP CBaseCoder::Init()
+{
+ CalculateDigest();
+ if (_aesFilter == 0)
+ {
+ RINOK(CreateFilter());
+ }
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ RINOK(cp->SetKey(_key.Key, sizeof(_key.Key)));
+ RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size)
+{
+ return _aesFilter->Filter(data, size);
+}
+
+#ifndef CRYPTO_AES
+HRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID)
+{
+ if (!_aesLibrary)
+ {
+ TCHAR filePath[MAX_PATH + 2];
+ if (!GetAESLibPath(filePath))
+ return ::GetLastError();
+ return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter);
+ }
+ return S_OK;
+}
+#endif
+
+HRESULT CEncoder::CreateFilter()
+{
+ #ifdef CRYPTO_AES
+ _aesFilter = new CAES_CBC_Encoder;
+ return S_OK;
+ #else
+ return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Encoder);
+ #endif
+}
+
+HRESULT CDecoder::CreateFilter()
+{
+ #ifdef CRYPTO_AES
+ _aesFilter = new CAES_CBC_Decoder;
+ return S_OK;
+ #else
+ return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Decoder);
+ #endif
+}
+
+}}
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsp b/CPP/7zip/Crypto/7zAES/7zAES.dsp
new file mode 100755
index 00000000..37cd7792
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.dsp
@@ -0,0 +1,245 @@
+# Microsoft Developer Studio Project File - Name="7zAES" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=7zAES - 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 "7zAES.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 "7zAES.mak" CFG="7zAES - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7zAES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "7zAES - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7zAES - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "7zAES_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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 /out:"C:\Program Files\7-Zip\Codecs\7zAES.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "7zAES - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "7zAES_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /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 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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 /out:"C:\Program Files\7-Zip\Codecs\7zAES.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7zAES - Win32 Release"
+# Name "7zAES - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Codec.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "7-Zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderLoader.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Hash\RotateDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Hash\Sha256.cpp
+
+!IF "$(CFG)" == "7zAES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7zAES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\Hash\Sha256.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAES.cpp
+
+!IF "$(CFG)" == "7zAES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7zAES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAES.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsw b/CPP/7zip/Crypto/7zAES/7zAES.dsw
new file mode 100755
index 00000000..08efbad8
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7zAES"=.\7zAES.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.h b/CPP/7zip/Crypto/7zAES/7zAES.h
new file mode 100755
index 00000000..f312f7e6
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.h
@@ -0,0 +1,122 @@
+// 7z_AES.h
+
+#ifndef __CRYPTO_7Z_AES_H
+#define __CRYPTO_7Z_AES_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+#include "Common/Vector.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#ifndef CRYPTO_AES
+#include "../../Archive/Common/CoderLoader.h"
+#endif
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+namespace NCrypto {
+namespace NSevenZ {
+
+const int kKeySize = 32;
+
+class CKeyInfo
+{
+public:
+ int NumCyclesPower;
+ UInt32 SaltSize;
+ Byte Salt[16];
+ CByteBuffer Password;
+ Byte Key[kKeySize];
+
+ bool IsEqualTo(const CKeyInfo &a) const;
+ void CalculateDigest();
+
+ CKeyInfo() { Init(); }
+ void Init()
+ {
+ NumCyclesPower = 0;
+ SaltSize = 0;
+ for (int i = 0; i < sizeof(Salt); i++)
+ Salt[i] = 0;
+ }
+};
+
+class CKeyInfoCache
+{
+ int Size;
+ CObjectVector<CKeyInfo> Keys;
+public:
+ CKeyInfoCache(int size): Size(size) {}
+ bool Find(CKeyInfo &key);
+ // HRESULT Calculate(CKeyInfo &key);
+ void Add(CKeyInfo &key);
+};
+
+class CBase
+{
+ CKeyInfoCache _cachedKeys;
+protected:
+ CKeyInfo _key;
+ Byte _iv[16];
+ // int _ivSize;
+ void CalculateDigest();
+ CBase();
+};
+
+class CBaseCoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp,
+ public CBase
+{
+protected:
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesLibrary;
+ #endif
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ virtual HRESULT CreateFilter() = 0;
+ #ifndef CRYPTO_AES
+ HRESULT CreateFilterFromDLL(REFCLSID clsID);
+ #endif
+public:
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+};
+
+class CEncoder:
+ public CBaseCoder,
+ public ICompressWriteCoderProperties
+{
+ virtual HRESULT CreateFilter();
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressWriteCoderProperties)
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+};
+
+class CDecoder:
+ public CBaseCoder,
+ public ICompressSetDecoderProperties2
+{
+ virtual HRESULT CreateFilter();
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/7zAES/DllExports.cpp b/CPP/7zip/Crypto/7zAES/DllExports.cpp
new file mode 100755
index 00000000..8766ded4
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/DllExports.cpp
@@ -0,0 +1,111 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "7zAES.h"
+
+/*
+// {23170F69-40C1-278B-0703-000000000000}
+DEFINE_GUID(CLSID_CCrypto_Hash_SHA256,
+0x23170F69, 0x40C1, 0x278B, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+*/
+
+// {23170F69-40C1-278B-06F1-070100000100}
+DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-06F1-070100000000}
+DEFINE_GUID(CLSID_CCrypto7zAESDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*iid == IID_ICompressFilter);
+ CMyComPtr<ICompressFilter> filter;
+ if (*clsid == CLSID_CCrypto7zAESDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ filter = (ICompressFilter *)new NCrypto::NSevenZ::CDecoder();
+ }
+ else if (*clsid == CLSID_CCrypto7zAESEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ filter = (ICompressFilter *)new NCrypto::NSevenZ::CEncoder();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = filter.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods = 1;
+ return S_OK;
+}
+
+STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ ::VariantClear((tagVARIANT *)value);
+ switch(propID)
+ {
+ case NMethodPropID::kID:
+ {
+ const char id[] = { 0x06, (char)(unsigned char)0xF1, 0x07, 0x01 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"7zAES")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCrypto7zAESDecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCrypto7zAESEncoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.cpp b/CPP/7zip/Crypto/7zAES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.h b/CPP/7zip/Crypto/7zAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/7zAES/makefile b/CPP/7zip/Crypto/7zAES/makefile
new file mode 100755
index 00000000..c3d9a51d
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/makefile
@@ -0,0 +1,52 @@
+PROG = 7zAES.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+7ZAES_OBJS = \
+ $O\DllExports.obj \
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(7ZAES_OBJS) \
+ $(7ZAES_OPT_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(7ZAES_OBJS): $(*B).cpp
+ $(COMPL)
+$(7ZAES_OPT_OBJS): $(*B).cpp
+ $(COMPL)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Crypto/7zAES/resource.rc b/CPP/7zip/Crypto/7zAES/resource.rc
new file mode 100755
index 00000000..24d428de
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7zAES Codec", "7zAES")
diff --git a/CPP/7zip/Crypto/AES/AES.dsp b/CPP/7zip/Crypto/AES/AES.dsp
new file mode 100755
index 00000000..d039be77
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES.dsp
@@ -0,0 +1,203 @@
+# Microsoft Developer Studio Project File - Name="AES" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=AES - 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 "AES.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 "AES.mak" CFG="AES - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "AES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AES - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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 /out:"C:\Program Files\7-Zip\Codecs\AES.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /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 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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 /out:"C:\Program Files\7-Zip\Codecs\AES.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "AES - Win32 Release"
+# Name "AES - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Codec.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aescrypt.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\aeskey.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aestab.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyAES.cpp
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyAES.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Crypto/AES/AES.dsw b/CPP/7zip/Crypto/AES/AES.dsw
new file mode 100755
index 00000000..7fa9d07b
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AES"=.\AES.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Crypto/AES/AES_CBC.h b/CPP/7zip/Crypto/AES/AES_CBC.h
new file mode 100755
index 00000000..fa3485a9
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES_CBC.h
@@ -0,0 +1,39 @@
+// AES_CBC.h
+
+#ifndef __AES_CBC_H
+#define __AES_CBC_H
+
+#include "aescpp.h"
+
+class CAES_CBC: public AESclass
+{
+protected:
+ Byte _prevBlock[16];
+public:
+ void Init(const Byte *iv)
+ {
+ for (int i = 0; i < 16; i++)
+ _prevBlock[i] = iv[i];
+ }
+ void Encode(const Byte *inBlock, Byte *outBlock)
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] ^= inBlock[i];
+ enc_blk(_prevBlock, outBlock);
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] = outBlock[i];
+ }
+
+ void Decode(const Byte *inBlock, Byte *outBlock)
+ {
+ dec_blk(inBlock, outBlock);
+ int i;
+ for (i = 0; i < 16; i++)
+ outBlock[i] ^= _prevBlock[i];
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] = inBlock[i];
+ }
+};
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/DllExports.cpp b/CPP/7zip/Crypto/AES/DllExports.cpp
new file mode 100755
index 00000000..7c21ac5c
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/DllExports.cpp
@@ -0,0 +1,100 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "MyAES.h"
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
+{
+ return TRUE;
+}
+
+#define MY_CreateClass(n) \
+if (*clsid == CLSID_CCrypto_ ## n ## _Encoder) { \
+ if (!correctInterface) return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Encoder(); \
+ } else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \
+ if (!correctInterface) return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Decoder(); \
+ }
+
+STDAPI CreateObject(
+ const GUID *clsid,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*interfaceID == IID_ICompressFilter);
+ CMyComPtr<ICompressFilter> filter;
+
+ MY_CreateClass(AES_CBC)
+ else
+ MY_CreateClass(AES_ECB)
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = filter.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+struct CAESMethodItem
+{
+ char ID[3];
+ const wchar_t *UserName;
+ const GUID *Decoder;
+ const GUID *Encoder;
+};
+
+#define METHOD_ITEM(Name, id, UserName) \
+ { { 0x06, 0x01, id }, UserName, \
+ &CLSID_CCrypto_ ## Name ## _Decoder, \
+ &CLSID_CCrypto_ ## Name ## _Encoder }
+
+
+static CAESMethodItem g_Methods[] =
+{
+ METHOD_ITEM(AES_ECB, (char)(unsigned char)0xC0, L"AES-ECB"),
+ METHOD_ITEM(AES_CBC, (char)(unsigned char)0xC1, L"AES")
+};
+
+STDAPI GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]);
+ return S_OK;
+}
+
+STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index > sizeof(g_Methods) / sizeof(g_Methods[1]))
+ return E_INVALIDARG;
+ VariantClear((tagVARIANT *)value);
+ const CAESMethodItem &method = g_Methods[index];
+ switch(propID)
+ {
+ case NMethodPropID::kID:
+ if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
+ sizeof(method.ID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Decoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Crypto/AES/MyAES.cpp b/CPP/7zip/Crypto/AES/MyAES.cpp
new file mode 100755
index 00000000..359caa25
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/MyAES.cpp
@@ -0,0 +1,94 @@
+// Crypto/AES/MyAES.cpp
+
+#include "StdAfx.h"
+
+#include "windows.h"
+
+#include "MyAES.h"
+#include "Windows/Defs.h"
+
+#include "AES_CBC.h"
+
+static const int kAESBlockSize = 16;
+
+extern "C"
+{
+#include "aesopt.h"
+}
+
+class CTabInit
+{
+public:
+ CTabInit() { gen_tabs();}
+} g_TabInit;
+
+STDMETHODIMP CAESFilter::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CAESFilter::Filter(Byte *data, UInt32 size)
+{
+ if (size > 0 && size < kAESBlockSize)
+ return kAESBlockSize;
+ UInt32 i;
+ for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize)
+ {
+ Byte outBlock[kAESBlockSize];
+ SubFilter(data + i, outBlock);
+ for (int j = 0; j < kAESBlockSize; j++)
+ data[i + j] = outBlock[j];
+ }
+ return i;
+}
+
+STDMETHODIMP CAESFilter::SetInitVector(const Byte *data, UInt32 size)
+{
+ if (size != 16)
+ return E_INVALIDARG;
+ AES.Init(data);
+ return S_OK;
+}
+
+STDMETHODIMP CAESEncoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAESEncoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.Encode(inBlock, outBlock); }
+
+STDMETHODIMP CAESDecoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAESDecoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.Decode(inBlock, outBlock); }
+
+////////////////////////////
+// ECB mode
+
+STDMETHODIMP CAesEcbFilter::Init() { return S_OK; }
+STDMETHODIMP CAesEcbFilter::SetInitVector(const Byte * /* data */, UInt32 size)
+ { return (size == 0) ? S_OK: E_INVALIDARG; }
+
+STDMETHODIMP_(UInt32) CAesEcbFilter::Filter(Byte *data, UInt32 size)
+{
+ if (size > 0 && size < kAESBlockSize)
+ return kAESBlockSize;
+ UInt32 i;
+ for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize)
+ {
+ Byte outBlock[kAESBlockSize];
+ SubFilter(data + i, outBlock);
+ for (int j = 0; j < kAESBlockSize; j++)
+ data[i + j] = outBlock[j];
+ }
+ return i;
+}
+
+STDMETHODIMP CAesEcbEncoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAesEcbEncoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.enc_blk(inBlock, outBlock); }
+
+STDMETHODIMP CAesEcbDecoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAesEcbDecoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.dec_blk(inBlock, outBlock); }
diff --git a/CPP/7zip/Crypto/AES/MyAES.h b/CPP/7zip/Crypto/AES/MyAES.h
new file mode 100755
index 00000000..f58913ae
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/MyAES.h
@@ -0,0 +1,106 @@
+// Crypto/AES/MyAES.h
+
+#ifndef __CIPHER_MYAES_H
+#define __CIPHER_MYAES_H
+
+#include "Common/Types.h"
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "AES_CBC.h"
+
+class CAESFilter:
+ public ICompressFilter,
+ public ICryptoProperties,
+ public CMyUnknownImp
+{
+protected:
+ CAES_CBC AES;
+ // Byte Key[32];
+ // Byte IV[kAESBlockSize];
+public:
+ MY_UNKNOWN_IMP1(ICryptoProperties)
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0;
+};
+
+class CAESEncoder: public CAESFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+class CAESDecoder: public CAESFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+#define MyClassCrypto3E(Name) class C ## Name: public CAESEncoder { };
+#define MyClassCrypto3D(Name) class C ## Name: public CAESDecoder { };
+
+// {23170F69-40C1-278B-0601-000000000000}
+#define MyClassCrypto2(Name, id, encodingId) \
+DEFINE_GUID(CLSID_CCrypto_ ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassCrypto(Name, id) \
+MyClassCrypto2(Name ## _Encoder, id, 0x01) \
+MyClassCrypto3E(Name ## _Encoder) \
+MyClassCrypto2(Name ## _Decoder, id, 0x00) \
+MyClassCrypto3D(Name ## _Decoder) \
+
+MyClassCrypto(AES_CBC, 0xC1)
+
+class CAesEcbFilter:
+ public ICompressFilter,
+ public ICryptoProperties,
+ public CMyUnknownImp
+{
+protected:
+ AESclass AES;
+public:
+ MY_UNKNOWN_IMP1(ICryptoProperties)
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0;
+};
+
+class CAesEcbEncoder: public CAesEcbFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+class CAesEcbDecoder: public CAesEcbFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+#define MyClassCrypto3E_Ecb(Name) class C ## Name: public CAesEcbEncoder { };
+#define MyClassCrypto3D_Ecb(Name) class C ## Name: public CAesEcbDecoder { };
+
+// {23170F69-40C1-278B-0601-000000000000}
+#define MyClassCrypto2_Ecb(Name, id, encodingId) \
+DEFINE_GUID(CLSID_CCrypto_ ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassCrypto_Ecb(Name, id) \
+MyClassCrypto2_Ecb(Name ## _Encoder, id, 0x01) \
+MyClassCrypto3E_Ecb(Name ## _Encoder) \
+MyClassCrypto2_Ecb(Name ## _Decoder, id, 0x00) \
+MyClassCrypto3D_Ecb(Name ## _Decoder) \
+
+MyClassCrypto_Ecb(AES_ECB, 0xC0)
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/StdAfx.cpp b/CPP/7zip/Crypto/AES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/AES/StdAfx.h b/CPP/7zip/Crypto/AES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aes.h b/CPP/7zip/Crypto/AES/aes.h
new file mode 100755
index 00000000..9aaba978
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aes.h
@@ -0,0 +1,103 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, 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.
+
+ 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 fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the definitions required to use AES (Rijndael) in C.
+*/
+
+#ifndef _AES_H
+#define _AES_H
+
+/* This include is used only to find 8 and 32 bit unsigned integer types */
+
+#include "limits.h"
+
+#if UCHAR_MAX == 0xff /* an unsigned 8 bit type for internal AES use */
+ typedef unsigned char aes_08t;
+#else
+#error Please define an unsigned 8 bit type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type for internal AES use */
+ typedef unsigned int aes_32t;
+#elif ULONG_MAX == 0xffffffff
+ typedef unsigned long aes_32t;
+#else
+#error Please define an unsigned 32 bit type in aes.h
+#endif
+
+/* BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
+ 24, 28, 32 or undefined for aespp.c. When left undefined a slower
+ version that provides variable block length is compiled.
+*/
+
+#define BLOCK_SIZE 16
+
+/* key schedule length (in 32-bit words) */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH 128
+#else
+#define KS_LENGTH 4 * BLOCK_SIZE
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef unsigned int aes_fret; /* type for function return value */
+#define aes_bad 0 /* bad function return value */
+#define aes_good 1 /* good function return value */
+#ifndef AES_DLL /* implement normal or DLL functions */
+#define aes_rval aes_fret
+#else
+#define aes_rval aes_fret __declspec(dllexport) _stdcall
+#endif
+
+
+typedef struct /* the AES context for encryption */
+{ aes_32t k_sch[KS_LENGTH]; /* the encryption key schedule */
+ aes_32t n_rnd; /* the number of cipher rounds */
+ aes_32t n_blk; /* the number of bytes in the state */
+} aes_ctx;
+
+#if !defined(BLOCK_SIZE)
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+#endif
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aescpp.h b/CPP/7zip/Crypto/AES/aescpp.h
new file mode 100755
index 00000000..93e3c8b0
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aescpp.h
@@ -0,0 +1,55 @@
+
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ All rights reserved.
+
+ TERMS
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted subject to the following conditions:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ 3. The copyright holder's name must not be used to endorse or promote
+ any products derived from this software without his specific prior
+ written permission.
+
+ This software is provided 'as is' with no express or implied warranties
+ of correctness or fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 21/01/2002
+
+ This file contains the definitions required to use AES (Rijndael) in C++.
+*/
+
+#ifndef _AESCPP_H
+#define _AESCPP_H
+
+#include "aes.h"
+
+class AESclass
+{ aes_ctx cx[1];
+public:
+#if defined(BLOCK_SIZE)
+ AESclass() { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 0; }
+#else
+ AESclass(unsigned int blen = 16) { cx->n_blk = blen; cx->n_rnd = 0; }
+ aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); }
+#endif
+ aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_enc_key(in_key, klen, cx); }
+ aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_dec_key(in_key, klen, cx); }
+ aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_enc_blk(in_blk, out_blk, cx); }
+ aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_dec_blk(in_blk, out_blk, cx); }
+};
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aescrypt.c b/CPP/7zip/Crypto/AES/aescrypt.c
new file mode 100755
index 00000000..095a61c4
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aescrypt.c
@@ -0,0 +1,421 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, 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.
+
+ 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 fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the code for implementing encryption and decryption
+ for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
+ can optionally be replaced by code written in assembler using NASM.
+*/
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+#define unused 77 /* Sunset Strip */
+
+#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+ /*
+ the following defines prevent the compiler requiring the declaration
+ of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
+ case 6: si(y,x,k,5); si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); so(y,x,6); \
+ case 6: so(y,x,5); so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ (and that for decryption) which, given the column (c) of the
+ output state variable, gives the input state variables which
+ are needed in its computation for each row (r) of the state.
+
+ For the fixed block size options, compilers should be able to
+ reduce this complex expression (and the equivalent one for
+ decryption) to a static variable reference at compile time.
+ But for variable block size code, there will be some limbs on
+ which conditional clauses will be returned.
+*/
+
+/* y = output word, x = input word, r = row, c = column for r = 0,
+ 1, 2 and 3 = column accessed for row r.
+*/
+
+#define fwd_var(x,r,c)\
+ ( r == 0 ? \
+ ( c == 0 ? s(x,0) \
+ : c == 1 ? s(x,1) \
+ : c == 2 ? s(x,2) \
+ : c == 3 ? s(x,3) \
+ : c == 4 ? s(x,4) \
+ : c == 5 ? s(x,5) \
+ : c == 6 ? s(x,6) \
+ : s(x,7))\
+ : r == 1 ? \
+ ( c == 0 ? s(x,1) \
+ : c == 1 ? s(x,2) \
+ : c == 2 ? s(x,3) \
+ : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
+ : c == 4 ? s(x,5) \
+ : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
+ : c == 6 ? s(x,7) \
+ : s(x,0))\
+ : r == 2 ? \
+ ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
+ : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
+ : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 6 ? s(x,1) \
+ : s(x,2))\
+ : \
+ ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
+ : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
+ : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(FT4_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#elif defined(FT1_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ aes_32t locals(b0, b1);
+ const aes_32t *kp = cx->k_sch;
+ dec_fmvars /* declare variables for fwd_mcol() if needed */
+
+ if(!(cx->n_blk & 1)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == FULL)
+
+ kp += (cx->n_rnd - 9) * nc;
+
+ switch(cx->n_rnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
+ round(fwd_rnd, b0, b1, kp - 3 * nc);
+ case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
+ round(fwd_rnd, b0, b1, kp - nc);
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+#else
+
+#if (ENC_UNROLL == PARTIAL)
+ { aes_32t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ kp += nc;
+ round(fwd_rnd, b0, b1, kp);
+ }
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+#else
+ { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp += nc;
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x,r,c) \
+ ( r == 0 ? \
+ ( c == 0 ? s(x,0) \
+ : c == 1 ? s(x,1) \
+ : c == 2 ? s(x,2) \
+ : c == 3 ? s(x,3) \
+ : c == 4 ? s(x,4) \
+ : c == 5 ? s(x,5) \
+ : c == 6 ? s(x,6) \
+ : s(x,7))\
+ : r == 1 ? \
+ ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
+ : c == 1 ? s(x,0) \
+ : c == 2 ? s(x,1) \
+ : c == 3 ? s(x,2) \
+ : c == 4 ? s(x,3) \
+ : c == 5 ? s(x,4) \
+ : c == 6 ? s(x,5) \
+ : s(x,6))\
+ : r == 2 ? \
+ ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
+ : c == 6 ? s(x,3) \
+ : s(x,4))\
+ : \
+ ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
+ : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(IT4_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(IT1_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ aes_32t locals(b0, b1);
+ const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
+ dec_imvars /* declare variables for inv_mcol() if needed */
+
+ if(!(cx->n_blk & 2)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == FULL)
+
+ kp = cx->k_sch + 9 * nc;
+ switch(cx->n_rnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
+ round(inv_rnd, b0, b1, kp + 3 * nc);
+ case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
+ round(inv_rnd, b0, b1, kp + nc );
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp - nc);
+ round(inv_rnd, b1, b0, kp - 2 * nc);
+ round(inv_rnd, b0, b1, kp - 3 * nc);
+ round(inv_rnd, b1, b0, kp - 4 * nc);
+ round(inv_rnd, b0, b1, kp - 5 * nc);
+ round(inv_rnd, b1, b0, kp - 6 * nc);
+ round(inv_rnd, b0, b1, kp - 7 * nc);
+ round(inv_rnd, b1, b0, kp - 8 * nc);
+ round(inv_lrnd, b0, b1, kp - 9 * nc);
+ }
+#else
+
+#if (DEC_UNROLL == PARTIAL)
+ { aes_32t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ kp -= nc;
+ round(inv_rnd, b0, b1, kp);
+ }
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+#else
+ { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp -= nc;
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aeskey.c b/CPP/7zip/Crypto/AES/aeskey.c
new file mode 100755
index 00000000..d281e1a8
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aeskey.c
@@ -0,0 +1,363 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, 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.
+
+ 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 fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the code for implementing the key schedule for AES
+ (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
+*/
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ values being 16, 24 and 32.
+*/
+
+#if !defined(BLOCK_SIZE)
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+ if((blen & 7) || blen < 16 || blen > 32)
+ {
+ cx->n_blk = 0; return aes_bad;
+ }
+
+ cx->n_blk = blen;
+ return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ length is now specified in bytes - 16, 24 or 32 as appropriate.
+ This corresponds to bit lengths of 128, 192 and 256 bits, and
+ to Nk values of 4, 6 and 8 respectively.
+
+ The following macros implement a single cycle in the key
+ schedule generation process. The number of cycles needed
+ for each cx->n_col and nk value is:
+
+ nk = 4 5 6 7 8
+ ------------------------------
+ cx->n_col = 4 10 9 8 7 7
+ cx->n_col = 5 14 11 10 9 9
+ cx->n_col = 6 19 15 12 11 11
+ cx->n_col = 7 21 19 16 13 14
+ cx->n_col = 8 29 23 19 17 14
+*/
+
+#define ke4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+#define kel4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+
+#define ke6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+ k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
+}
+#define kel6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+}
+
+#define ke8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+ k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
+ k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
+}
+#define kel8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+}
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ aes_32t ss[8];
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 1;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
+ ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
+ ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
+ ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
+ ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
+ ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
+ ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
+ ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
+ ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
+ ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
+ kel8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { aes_32t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16: for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+#if (DEC_ROUND != NO_TABLES)
+#define d_vars dec_imvars
+#define ff(x) inv_mcol(x)
+#else
+#define ff(x) (x)
+#define d_vars
+#endif
+
+#if 1
+#define kdf4(k,i) \
+{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
+ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
+ ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
+ k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
+ k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
+}
+#define kdl4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
+ k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
+}
+#else
+#define kdf4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
+ ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
+}
+#define kdl4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
+}
+#endif
+
+#define kdf6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
+}
+#define kd6(k,i) \
+{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
+ ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
+}
+#define kdl6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
+}
+
+#define kdf8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
+ ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
+ ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
+}
+#define kd8(k,i) \
+{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
+ ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
+ ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
+ g = ls_box(ss[3],0); \
+ ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
+ ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
+ ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
+}
+#define kdl8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
+}
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ aes_32t ss[8];
+ d_vars
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 2;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
+ kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
+ kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
+ kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
+ kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+ cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+ kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
+ kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
+ kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
+ kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+ cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+ cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24));
+ cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28));
+ kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
+ kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
+ kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
+ kdl8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { aes_32t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16:
+ for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#if (DEC_ROUND != NO_TABLES)
+ for(i = nc; i < nc * cx->n_rnd; ++i)
+ cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+#endif
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aesopt.h b/CPP/7zip/Crypto/AES/aesopt.h
new file mode 100755
index 00000000..bcad345f
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aesopt.h
@@ -0,0 +1,839 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, 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.
+
+ 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 fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
+
+ OPERATION
+
+ These source code files implement the AES algorithm Rijndael designed by
+ Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+ block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+ that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+ and 256 bits (16, 20, 24, 28 and 32 bytes). This file is a common header
+ file for these two implementations and for aesref.c, which is a reference
+ implementation.
+
+ This version is designed for flexibility and speed using operations on
+ 32-bit words rather than operations on bytes. It provides aes_both fixed
+ and dynamic block and key lengths and can also run with either big or
+ little endian internal byte order (see aes.h). It inputs block and key
+ lengths in bytes with the legal values being 16, 24 and 32 for aes.c and
+ 16, 20, 24, 28 and 32 for aespp.c
+
+ THE CIPHER INTERFACE
+
+ aes_08t (an unsigned 8-bit type)
+ aes_32t (an unsigned 32-bit type)
+ aes_fret (a signed 16 bit type for function return values)
+ aes_good (value != 0, a good return)
+ aes_bad (value == 0, an error return)
+ struct aes_ctx (structure for the cipher encryption context)
+ struct aes_ctx (structure for the cipher decryption context)
+ aes_rval the function return type (aes_fret if not DLL)
+
+ C subroutine calls:
+
+ aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ IMPORTANT NOTE: If you are using this C interface and your compiler does
+ not set the memory used for objects to zero before use, you will need to
+ ensure that cx.s_flg is set to zero before using these subroutine calls.
+
+ C++ aes class subroutines:
+
+ class AESclass for encryption
+ class AESclass for decryption
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ The block length inputs to set_block and set_key are in numbers of
+ BYTES, not bits. The calls to subroutines must be made in the above
+ order but multiple calls can be made without repeating earlier calls
+ if their parameters have not changed. If the cipher block length is
+ variable but set_blk has not been called before cipher operations a
+ value of 16 is assumed (that is, the AES block size). In contrast to
+ earlier versions the block and key length parameters are now checked
+ for correctness and the encryption and decryption routines check to
+ ensure that an appropriate key has been set before they are called.
+
+ COMPILATION
+
+ The files used to provide AES (Rijndael) are
+
+ a. aes.h for the definitions needed for use in C.
+ b. aescpp.h for the definitions needed for use in C++.
+ c. aesopt.h for setting compilation options (also includes common
+ code).
+ d. aescrypt.c for encryption and decrytpion, or
+ e. aescrypt.asm for encryption and decryption using assembler code.
+ f. aeskey.c for key scheduling.
+ g. aestab.c for table loading or generation.
+
+ The assembler code uses the NASM assembler. The above files provice
+ block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+ If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+ aeskey.c respectively, the block and key lengths can then be 16, 20,
+ 24, 28 or 32 bytes. However this code has not been optimised to the
+ same extent and is hence slower (esepcially for the AES block size
+ of 16 bytes).
+
+ To compile AES (Rijndael) for use in C code use aes.h and exclude
+ the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+ exclude the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+ aes.h, include the AES_DLL define and compile the DLL. If using
+ the test files to test the DLL, exclude aes.c from the test build
+ project and compile it with the same defines as used for the DLL
+ (ensure that the DLL path is correct)
+
+ CONFIGURATION OPTIONS (here and in aes.h)
+
+ a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+ or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+ extended code) or leave this undefined for dynamically variable
+ block size (this will result in much slower code).
+ b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+ c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+ d. If you want the code to run in a specific internal byte order, then
+ INTERNAL_BYTE_ORDER must be set accordingly.
+ e. set other configuration options decribed below.
+*/
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+/* START OF CONFIGURATION OPTIONS
+
+ USE OF DEFINES
+
+ Later in this section there are a number of defines that control the
+ operation of the code. In each section, the purpose of each define is
+ explained so that the relevant form can be included or excluded by
+ setting either 1's or 0's respectively on the branches of the related
+ #if clauses.
+*/
+
+/* 1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
+#include "crypt/aes.h"
+#else
+ #include "aes.h"
+#endif
+
+// 2003-09-16: Changed by Igor Pavlov. Check it.
+// #if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(_WIN32)
+
+# include <endian.h>
+# include <byteswap.h>
+#elif defined(__CRYPTLIB__)
+# if defined( INC_ALL )
+# include "crypt.h"
+# elif defined( INC_CHILD )
+# include "../crypt.h"
+# else
+# include "crypt.h"
+# endif
+# if defined(DATA_LITTLEENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# else
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_MSC_VER)
+# include <stdlib.h>
+#elif !defined(_WIN32)
+# include <stdlib.h>
+# if !defined (_ENDIAN_H)
+# include <sys/param.h>
+# else
+# include _ENDIAN_H
+# endif
+#endif
+
+/* 2. BYTE ORDER IN 32-BIT WORDS
+
+ To obtain the highest speed on processors with 32-bit words, this code
+ needs to determine the order in which bytes are packed into such words.
+ 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.
+*/
+#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# if defined(BYTE_ORDER)
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (BYTE_ORDER == BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# if defined(_BYTE_ORDER)
+# if (_BYTE_ORDER == _LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (_BYTE_ORDER == _BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+# error Please set undetermined byte order (lines 233 or 235 of aesopt.h).
+#endif
+
+/* 3. ASSEMBLER SUPPORT
+
+ If the assembler code is used for encryption and decryption this file only
+ provides key scheduling so the following defines are used
+*/
+#ifdef AES_ASM
+#define ENCRYPTION_KEY_SCHEDULE
+#define DECRYPTION_KEY_SCHEDULE
+#else
+
+/* 4. FUNCTIONS REQUIRED
+
+ This implementation provides five main subroutines which provide for
+ setting block length, setting encryption and decryption keys and for
+ encryption and decryption. When the assembler code is not being used
+ the following definition blocks allow the selection of the routines
+ that are to be included in the compilation.
+*/
+#if 1
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define ENCRYPTION
+#endif
+
+#if 1
+#define DECRYPTION
+#endif
+
+#endif
+
+/* 5. BYTE ORDER WITHIN 32 BIT WORDS
+
+ The fundamental data processing units in Rijndael are 8-bit bytes. The
+ input, output and key input are all enumerated arrays of bytes in which
+ bytes are numbered starting at zero and increasing to one less than the
+ number of bytes in the array in question. This enumeration is only used
+ for naming bytes and does not imply any adjacency or order relationship
+ from one byte to another. When these inputs and outputs are considered
+ as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+ byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+ In this implementation bits are numbered from 0 to 7 starting at the
+ numerically least significant end of each byte (bit n represents 2^n).
+
+ However, Rijndael can be implemented more efficiently using 32-bit
+ words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+ into word[n]. While in principle these bytes can be assembled into words
+ in any positions, this implementation only supports the two formats in
+ which bytes in adjacent positions within words also have adjacent byte
+ numbers. This order is called big-endian if the lowest numbered bytes
+ in words have the highest numeric significance and little-endian if the
+ opposite applies.
+
+ This code can work in either order irrespective of the order used by the
+ machine on which it runs. Normally the internal byte order will be set
+ to the order of the processor on which the code is to be run but this
+ define can be used to reverse this in special situations
+*/
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif defined(AES_LITTLE_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif defined(AES_BIG_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+
+/* 6. FAST INPUT/OUTPUT OPERATIONS.
+
+ On some machines it is possible to improve speed by transferring the
+ bytes in the input and output arrays to and from the internal 32-bit
+ variables by addressing these arrays as if they are arrays of 32-bit
+ words. On some machines this will always be possible but there may
+ be a large performance penalty if the byte arrays are not aligned on
+ the normal word boundaries. On other machines this technique will
+ lead to memory access errors when such 32-bit word accesses are not
+ properly aligned. The option SAFE_IO avoids such problems but will
+ often be slower on those machines that support misaligned access
+ (especially so if care is taken to align the input and output byte
+ arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+ assumed that access to byte arrays as if they are arrays of 32-bit
+ words will not cause problems when such accesses are misaligned.
+*/
+#if 1
+#define SAFE_IO
+#endif
+
+/* 7. LOOP UNROLLING
+
+ The code for encryption and decrytpion cycles through a number of rounds
+ that can be implemented either in a loop or by expanding the code into a
+ long sequence of instructions, the latter producing a larger program but
+ one that will often be much faster. The latter is called loop unrolling.
+ There are also potential speed advantages in expanding two iterations in
+ a loop with half the number of iterations, which is called partial loop
+ unrolling. The following options allow partial or full loop unrolling
+ to be set independently for encryption and decryption
+*/
+#if 1
+#define ENC_UNROLL FULL
+#elif 0
+#define ENC_UNROLL PARTIAL
+#else
+#define ENC_UNROLL NONE
+#endif
+
+// 7-Zip: Small size for SFX
+#ifdef _SFX
+#define DEC_UNROLL NONE
+#else
+
+#if 1
+#define DEC_UNROLL FULL
+#elif 0
+#define DEC_UNROLL PARTIAL
+#else
+#define DEC_UNROLL NONE
+#endif
+
+#endif
+
+/* 8. FIXED OR DYNAMIC TABLES
+
+ When this section is included the tables used by the code are comipled
+ statically into the binary file. Otherwise they are computed once when
+ the code is first used.
+*/
+#if 0
+#define FIXED_TABLES
+#endif
+
+/* 9. FAST FINITE FIELD OPERATIONS
+
+ If this section is included, tables are used to provide faster finite
+ field arithmetic (this has no effect if FIXED_TABLES is defined).
+*/
+#if 1
+#define FF_TABLES
+#endif
+
+/* 10. INTERNAL STATE VARIABLE FORMAT
+
+ The internal state of Rijndael is stored in a number of local 32-bit
+ word varaibles which can be defined either as an array or as individual
+ names variables. Include this section if you want to store these local
+ varaibles in arrays. Otherwise individual local variables will be used.
+*/
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+ 32-bit words. The state array can be held in various ways: in an array
+ of words, in a number of individual word variables or in a number of
+ processor registers. The following define maps a variable name x and
+ a column number c to the way the state array variable is to be held.
+ The first define below maps the state into an array x[c] whereas the
+ second form maps the state into a number of individual variables x0,
+ x1, etc. Another form could map individual state colums to machine
+ register names.
+*/
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+/* 11. VARIABLE BLOCK SIZE SPEED
+
+ This section is only relevant if you wish to use the variable block
+ length feature of the code. Include this section if you place more
+ emphasis on speed rather than code size.
+*/
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/* 12. INTERNAL TABLE CONFIGURATION
+
+ This cipher proceeds by repeating in a number of cycles known as 'rounds'
+ which are implemented by a round function which can optionally be speeded
+ up using tables. The basic tables are each 256 32-bit words, with either
+ one or four tables being required for each round function depending on
+ how much speed is required. The encryption and decryption round functions
+ are different and the last encryption and decrytpion round functions are
+ different again making four different round functions in all.
+
+ This means that:
+ 1. Normal encryption and decryption rounds can each use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+ 2. The last encryption and decryption rounds can also use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+
+ Include or exclude the appropriate definitions below to set the number
+ of tables used by this implementation.
+*/
+
+#if 1 /* set tables for the normal encryption round */
+#define ENC_ROUND FOUR_TABLES
+#elif 0
+#define ENC_ROUND ONE_TABLE
+#else
+#define ENC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the last encryption round */
+#define LAST_ENC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND ONE_TABLE
+#else
+#define LAST_ENC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the normal decryption round */
+#define DEC_ROUND FOUR_TABLES
+#elif 0
+#define DEC_ROUND ONE_TABLE
+#else
+#define DEC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the last decryption round */
+#define LAST_DEC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND ONE_TABLE
+#else
+#define LAST_DEC_ROUND NO_TABLES
+#endif
+
+/* The decryption key schedule can be speeded up with tables in the same
+ way that the round functions can. Include or exclude the following
+ defines to set this requirement.
+*/
+#if 1
+#define KEY_SCHED FOUR_TABLES
+#elif 0
+#define KEY_SCHED ONE_TABLE
+#else
+#define KEY_SCHED NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#define NO_TABLES 0 /* DO NOT CHANGE */
+#define ONE_TABLE 1 /* DO NOT CHANGE */
+#define FOUR_TABLES 4 /* DO NOT CHANGE */
+#define NONE 0 /* DO NOT CHANGE */
+#define PARTIAL 1 /* DO NOT CHANGE */
+#define FULL 2 /* DO NOT CHANGE */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH 29
+#else
+#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef ENC_UNROLL
+#define ENC_UNROLL NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef DEC_UNROLL
+#define DEC_UNROLL NONE
+#endif
+
+/* upr(x,n): rotates bytes within words by n positions, moving bytes to
+ higher index positions with wrap around into low positions
+ ups(x,n): moves bytes by n positions to higher index positions in
+ words but without wrap around
+ bval(x,n): extracts a byte from a word
+
+ NOTE: The definitions given here are intended only for use with
+ unsigned variables and with shift counts that are compile
+ time constants
+*/
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#if defined(_MSC_VER)
+#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n))
+#else
+#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> 32 - 8 * (n))
+#endif
+#define ups(x,n) ((aes_32t)(x) << 8 * (n))
+#define bval(x,n) ((aes_08t)((x) >> 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n))
+#define ups(x,n) ((aes_32t)(x) >> 8 * (n)))
+#define bval(x,n) ((aes_08t)((x) >> 24 - 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \
+ (x)[2] = bval(v,2); (x)[3] = bval(v,3); }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x) *(aes_32t*)(x)
+#define word_out(x,v) *(aes_32t*)(x) = (v)
+
+#else
+
+#if !defined(bswap_32)
+#if !defined(_MSC_VER)
+#define _lrotl(x,n) ((aes_32t)(x) << n | (aes_32t)(x) >> 32 - n)
+#endif
+#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
+#endif
+
+#define word_in(x) bswap_32(*(aes_32t*)(x))
+#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v)
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY 0x011b
+#define BPOLY 0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1 0x80808080
+#define m2 0x7f7f7f7f
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+ give improved performance if a fast 32-bit multiply is not available. Note
+ that a temporary variable u needs to be defined where FFmulX is used.
+
+#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+#define m4 (0x01010101 * BPOLY)
+#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+*/
+
+/* Work out which tables are needed for the different options */
+
+#ifdef AES_ASM
+#ifdef ENC_ROUND
+#undef ENC_ROUND
+#endif
+#define ENC_ROUND FOUR_TABLES
+#ifdef LAST_ENC_ROUND
+#undef LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND FOUR_TABLES
+#ifdef DEC_ROUND
+#undef DEC_ROUND
+#endif
+#define DEC_ROUND FOUR_TABLES
+#ifdef LAST_DEC_ROUND
+#undef LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND FOUR_TABLES
+#ifdef KEY_SCHED
+#undef KEY_SCHED
+#define KEY_SCHED FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#ifdef FIXED_TABLES
+#define prefx extern const
+#else
+#define prefx extern
+extern aes_08t tab_init;
+void gen_tabs(void);
+#endif
+
+prefx aes_32t rcon_tab[29];
+
+#ifdef SBX_SET
+prefx aes_08t s_box[256];
+#endif
+
+#ifdef ISB_SET
+prefx aes_08t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+prefx aes_32t ft_tab[256];
+#endif
+
+#ifdef FT4_SET
+prefx aes_32t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+prefx aes_32t fl_tab[256];
+#endif
+
+#ifdef FL4_SET
+prefx aes_32t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+prefx aes_32t it_tab[256];
+#endif
+
+#ifdef IT4_SET
+prefx aes_32t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+prefx aes_32t il_tab[256];
+#endif
+
+#ifdef IL4_SET
+prefx aes_32t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+#ifdef FL1_SET
+#undef LS1_SET
+#else
+prefx aes_32t ls_tab[256];
+#endif
+#endif
+
+#ifdef LS4_SET
+#ifdef FL4_SET
+#undef LS4_SET
+#else
+prefx aes_32t ls_tab[4][256];
+#endif
+#endif
+
+#ifdef IM1_SET
+prefx aes_32t im_tab[256];
+#endif
+
+#ifdef IM4_SET
+prefx aes_32t im_tab[4][256];
+#endif
+
+/* Set the number of columns in nc. Note that it is important
+ that nc is a constant which is known at compile time if the
+ highest speed version of the code is needed.
+*/
+
+#if defined(BLOCK_SIZE)
+#define nc (BLOCK_SIZE >> 2)
+#else
+#define nc (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use tables */
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+ box[bval(vf(x,0,c),rf(0,c))], \
+ box[bval(vf(x,1,c),rf(1,c))], \
+ box[bval(vf(x,2,c),rf(2,c))], \
+ box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c) (x)
+#define rf1(r,c) (r)
+#define rf2(r,c) ((r-c)&3)
+
+/* perform forward and inverse column mix operation on four bytes in long word x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
+
+#define dec_fmvars
+#if defined(FM4_SET) /* not currently used */
+#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0)
+#elif defined(FM1_SET) /* not currently used */
+#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0)
+#else
+#undef dec_fmvars
+#define dec_fmvars aes_32t f1, f2;
+#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+#elif defined(IM1_SET)
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
+#else
+#undef dec_imvars
+#define dec_imvars aes_32t f2, f4, f8, f9;
+#define inv_mcol(x) \
+ (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+#elif defined(LS4_SET)
+#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c)
+#elif defined(FL1_SET)
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
+#elif defined(LS1_SET)
+#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c)
+#else
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aestab.c b/CPP/7zip/Crypto/AES/aestab.c
new file mode 100755
index 00000000..de1d7eea
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aestab.c
@@ -0,0 +1,494 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, 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.
+
+ 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 fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+*/
+
+#include "aesopt.h"
+
+#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+
+/* finite field arithmetic operations */
+
+#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
+#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
+#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
+ ^ (((x>>5) & 4) * WPOLY))
+#define f3(x) (f2(x) ^ x)
+#define f9(x) (f8(x) ^ x)
+#define fb(x) (f8(x) ^ f2(x) ^ x)
+#define fd(x) (f8(x) ^ f4(x) ^ x)
+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
+
+#endif
+
+#if defined(FIXED_TABLES)
+
+#define sb_data(w) \
+ w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
+ w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
+ w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
+ w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
+ w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
+ w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
+ w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
+ w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
+ w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
+ w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
+ w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
+ w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
+ w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
+ w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
+ w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
+ w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
+ w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
+ w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
+ w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
+ w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
+ w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
+ w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
+ w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
+ w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
+ w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
+ w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
+ w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
+ w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
+ w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
+ w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
+ w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
+ w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+
+#define isb_data(w) \
+ w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
+ w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
+ w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
+ w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
+ w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
+ w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
+ w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
+ w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
+ w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
+ w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
+ w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
+ w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
+ w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
+ w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
+ w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
+ w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
+ w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
+ w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
+ w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
+ w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
+ w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
+ w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
+ w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
+ w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
+ w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
+ w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
+ w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
+ w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
+ w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
+ w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
+ w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
+ w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+
+#define mm_data(w) \
+ w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
+ w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
+ w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
+ w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
+ w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
+ w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
+ w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
+ w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
+ w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
+ w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
+ w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
+ w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
+ w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
+ w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
+ w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
+ w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
+ w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
+ w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
+ w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
+ w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
+ w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
+ w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
+ w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
+ w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
+ w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
+ w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
+ w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
+ w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
+ w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
+ w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
+ w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
+ w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+
+#define h0(x) (x)
+
+/* These defines are used to ensure tables are generated in the
+ right format depending on the internal byte order required
+*/
+
+#define w0(p) bytes2word(p, 0, 0, 0)
+#define w1(p) bytes2word(0, p, 0, 0)
+#define w2(p) bytes2word(0, 0, p, 0)
+#define w3(p) bytes2word(0, 0, 0, p)
+
+/* Number of elements required in this table for different
+ block and key lengths is:
+
+ Rcon Table key length (bytes)
+ Length 16 20 24 28 32
+ ---------------------
+ block 16 | 10 9 8 7 7
+ length 20 | 14 11 10 9 9
+ (bytes) 24 | 19 15 12 11 11
+ 28 | 24 19 16 13 13
+ 32 | 29 23 19 17 14
+
+ this table can be a table of bytes if the key schedule
+ code is adjusted accordingly
+*/
+
+#define u0(p) bytes2word(f2(p), p, p, f3(p))
+#define u1(p) bytes2word(f3(p), f2(p), p, p)
+#define u2(p) bytes2word(p, f3(p), f2(p), p)
+#define u3(p) bytes2word(p, p, f3(p), f2(p))
+
+#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
+#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
+#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
+#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
+
+const aes_32t rcon_tab[29] =
+{
+ w0(0x01), w0(0x02), w0(0x04), w0(0x08),
+ w0(0x10), w0(0x20), w0(0x40), w0(0x80),
+ w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
+ w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
+ w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
+ w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
+ w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
+ w0(0xc5)
+};
+
+#ifdef SBX_SET
+const aes_08t s_box[256] = { sb_data(h0) };
+#endif
+#ifdef ISB_SET
+const aes_08t inv_s_box[256] = { isb_data(h0) };
+#endif
+
+#ifdef FT1_SET
+const aes_32t ft_tab[256] = { sb_data(u0) };
+#endif
+#ifdef FT4_SET
+const aes_32t ft_tab[4][256] =
+ { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } };
+#endif
+
+#ifdef FL1_SET
+const aes_32t fl_tab[256] = { sb_data(w0) };
+#endif
+#ifdef FL4_SET
+const aes_32t fl_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IT1_SET
+const aes_32t it_tab[256] = { isb_data(v0) };
+#endif
+#ifdef IT4_SET
+const aes_32t it_tab[4][256] =
+ { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
+#endif
+
+#ifdef IL1_SET
+const aes_32t il_tab[256] = { isb_data(w0) };
+#endif
+#ifdef IL4_SET
+const aes_32t il_tab[4][256] =
+ { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
+#endif
+
+#ifdef LS1_SET
+const aes_32t ls_tab[256] = { sb_data(w0) };
+#endif
+#ifdef LS4_SET
+const aes_32t ls_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IM1_SET
+const aes_32t im_tab[256] = { mm_data(v0) };
+#endif
+#ifdef IM4_SET
+const aes_32t im_tab[4][256] =
+ { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } };
+#endif
+
+#else /* dynamic table generation */
+
+aes_08t tab_init = 0;
+
+#define const
+
+aes_32t rcon_tab[29];
+
+#ifdef SBX_SET
+aes_08t s_box[256];
+#endif
+#ifdef ISB_SET
+aes_08t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+aes_32t ft_tab[256];
+#endif
+#ifdef FT4_SET
+aes_32t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+aes_32t fl_tab[256];
+#endif
+#ifdef FL4_SET
+aes_32t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+aes_32t it_tab[256];
+#endif
+#ifdef IT4_SET
+aes_32t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+aes_32t il_tab[256];
+#endif
+#ifdef IL4_SET
+aes_32t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+aes_32t ls_tab[256];
+#endif
+#ifdef LS4_SET
+aes_32t ls_tab[4][256];
+#endif
+
+#ifdef IM1_SET
+aes_32t im_tab[256];
+#endif
+#ifdef IM4_SET
+aes_32t im_tab[4][256];
+#endif
+
+#if !defined(FF_TABLES)
+
+/* Generate the tables for the dynamic table option
+
+ It will generally be sensible to use tables to compute finite
+ field multiplies and inverses but where memory is scarse this
+ code might sometimes be better. But it only has effect during
+ initialisation so its pretty unimportant in overall terms.
+*/
+
+/* return 2 ^ (n - 1) where n is the bit number of the highest bit
+ set in x with x in the range 1 < x < 0x00000200. This form is
+ used so that locals within fi can be bytes rather than words
+*/
+
+static aes_08t hibit(const aes_32t x)
+{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static aes_08t fi(const aes_08t x)
+{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+ if(x < 2) return x;
+
+ for(;;)
+ {
+ if(!n1) return v1;
+
+ while(n2 >= n1)
+ {
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+ }
+
+ if(!n2) return v2;
+
+ while(n1 >= n2)
+ {
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+ }
+ }
+}
+
+#else
+
+/* define the finite field multiplies required for Rijndael */
+
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+#define fi(x) ((x) ? pow[255 - log[x]]: 0)
+
+#endif
+
+/* The forward and inverse affine transformations used in the S-box */
+
+#define fwd_affine(x) \
+ (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
+
+#define inv_affine(x) \
+ (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
+
+void gen_tabs(void)
+{ aes_32t i, w;
+
+#if defined(FF_TABLES)
+
+ aes_08t pow[512], log[256];
+
+ /* log and power tables for GF(2^8) finite field with
+ WPOLY as modular polynomial - the simplest primitive
+ root is 0x03, used here to generate the tables
+ */
+
+ i = 0; w = 1;
+ do
+ {
+ pow[i] = (aes_08t)w;
+ pow[i + 255] = (aes_08t)w;
+ log[w] = (aes_08t)i++;
+ w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+ }
+ while (w != 1);
+
+#endif
+
+ for(i = 0, w = 1; i < RC_LENGTH; ++i)
+ {
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
+ w = f2(w);
+ }
+
+ for(i = 0; i < 256; ++i)
+ { aes_08t b;
+
+ b = fwd_affine(fi((aes_08t)i));
+ w = bytes2word(f2(b), b, b, f3(b));
+
+#ifdef SBX_SET
+ s_box[i] = b;
+#endif
+
+#ifdef FT1_SET /* tables for a normal encryption round */
+ ft_tab[i] = w;
+#endif
+#ifdef FT4_SET
+ ft_tab[0][i] = w;
+ ft_tab[1][i] = upr(w,1);
+ ft_tab[2][i] = upr(w,2);
+ ft_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+
+#ifdef FL1_SET /* tables for last encryption round (may also */
+ fl_tab[i] = w; /* be used in the key schedule) */
+#endif
+#ifdef FL4_SET
+ fl_tab[0][i] = w;
+ fl_tab[1][i] = upr(w,1);
+ fl_tab[2][i] = upr(w,2);
+ fl_tab[3][i] = upr(w,3);
+#endif
+
+#ifdef LS1_SET /* table for key schedule if fl_tab above is */
+ ls_tab[i] = w; /* not of the required form */
+#endif
+#ifdef LS4_SET
+ ls_tab[0][i] = w;
+ ls_tab[1][i] = upr(w,1);
+ ls_tab[2][i] = upr(w,2);
+ ls_tab[3][i] = upr(w,3);
+#endif
+
+ b = fi(inv_affine((aes_08t)i));
+ w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+
+#ifdef IM1_SET /* tables for the inverse mix column operation */
+ im_tab[b] = w;
+#endif
+#ifdef IM4_SET
+ im_tab[0][b] = w;
+ im_tab[1][b] = upr(w,1);
+ im_tab[2][b] = upr(w,2);
+ im_tab[3][b] = upr(w,3);
+#endif
+
+#ifdef ISB_SET
+ inv_s_box[i] = b;
+#endif
+#ifdef IT1_SET /* tables for a normal decryption round */
+ it_tab[i] = w;
+#endif
+#ifdef IT4_SET
+ it_tab[0][i] = w;
+ it_tab[1][i] = upr(w,1);
+ it_tab[2][i] = upr(w,2);
+ it_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+#ifdef IL1_SET /* tables for last decryption round */
+ il_tab[i] = w;
+#endif
+#ifdef IL4_SET
+ il_tab[0][i] = w;
+ il_tab[1][i] = upr(w,1);
+ il_tab[2][i] = upr(w,2);
+ il_tab[3][i] = upr(w,3);
+#endif
+ }
+
+ tab_init = 1;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/makefile b/CPP/7zip/Crypto/AES/makefile
new file mode 100755
index 00000000..28f99965
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/makefile
@@ -0,0 +1,31 @@
+PROG = AES.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+AES_OBJS = \
+ $O\DllExports.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(AES_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(AES_OBJS): $(*B).cpp
+ $(COMPL)
+$(AES_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(AES_ORIG_OBJS): $(*B).c
+ $(COMPL_O2_W3)
diff --git a/CPP/7zip/Crypto/AES/resource.rc b/CPP/7zip/Crypto/AES/resource.rc
new file mode 100755
index 00000000..1ea1bfe7
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("AES Codec", "AES")
diff --git a/CPP/7zip/Crypto/Codec.def b/CPP/7zip/Crypto/Codec.def
new file mode 100755
index 00000000..ebf73a3b
--- /dev/null
+++ b/CPP/7zip/Crypto/Codec.def
@@ -0,0 +1,4 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.cpp b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
new file mode 100755
index 00000000..a5c20a75
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
@@ -0,0 +1,109 @@
+// HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void CHmac::SetKey(const Byte *key, size_t keySize)
+{
+ Byte keyTemp[kBlockSize];
+ size_t i;
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ _sha.Init();
+ _sha.Update(key, keySize);
+ _sha.Final(keyTemp);
+ keySize = kDigestSize;
+ }
+ else
+ for (i = 0; i < keySize; i++)
+ keyTemp[i] = key[i];
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSize);
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36 ^ 0x5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSize);
+}
+
+void CHmac::Final(Byte *mac, size_t macSize)
+{
+ Byte digest[kDigestSize];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSize);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+
+void CHmac32::SetKey(const Byte *key, size_t keySize)
+{
+ UInt32 keyTemp[kBlockSizeInWords];
+ size_t i;
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ CContext sha;
+ sha.Init();
+ sha.Update(key, keySize);
+ Byte digest[kDigestSize];
+ sha.Final(digest);
+
+ for (int i = 0 ; i < kDigestSizeInWords; i++)
+ keyTemp[i] =
+ ((UInt32)(digest[i * 4 + 0]) << 24) |
+ ((UInt32)(digest[i * 4 + 1]) << 16) |
+ ((UInt32)(digest[i * 4 + 2]) << 8) |
+ ((UInt32)(digest[i * 4 + 3]));
+ keySize = kDigestSizeInWords;
+ }
+ else
+ for (size_t i = 0; i < keySize; i++)
+ keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3)));
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSizeInWords);
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSizeInWords);
+}
+
+void CHmac32::Final(UInt32 *mac, size_t macSize)
+{
+ UInt32 digest[kDigestSizeInWords];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSizeInWords);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration)
+{
+ UInt32 block[kBlockSizeInWords];
+ UInt32 block2[kBlockSizeInWords];
+ _sha.PrepareBlock(block, kDigestSizeInWords);
+ _sha2.PrepareBlock(block2, kDigestSizeInWords);
+ for(unsigned int s = 0; s < kDigestSizeInWords; s++)
+ block[s] = mac[s];
+ for(UInt32 i = 0; i < numIteration; i++)
+ {
+ _sha.GetBlockDigest(block, block2);
+ _sha2.GetBlockDigest(block2, block);
+ for (unsigned int s = 0; s < kDigestSizeInWords; s++)
+ mac[s] ^= block[s];
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.h b/CPP/7zip/Crypto/Hash/HmacSha1.h
new file mode 100755
index 00000000..bca5bcf8
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.h
@@ -0,0 +1,39 @@
+// HmacSha1.h
+// Implements HMAC-SHA-1 (RFC2104, FIPS-198)
+
+#ifndef _HMAC_H
+#define _HMAC_H
+
+#include "Sha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize);
+
+class CHmac
+{
+ CContext _sha;
+ CContext _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(Byte *mac, size_t macSize = kDigestSize);
+};
+
+class CHmac32
+{
+ CContext32 _sha;
+ CContext32 _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(UInt32 *mac, size_t macSize = kDigestSizeInWords);
+
+ // It'sa for hmac function. in,out: mac[kDigestSizeInWords].
+ void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
new file mode 100755
index 00000000..b11881b7
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
@@ -0,0 +1,83 @@
+// Pbkdf2HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize)
+{
+ CHmac baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) };
+ const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize;
+ ctx.Update(u, 4);
+ ctx.Final(u, kDigestSize);
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSize);
+ ctx.Final(u, kDigestSize);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize)
+{
+ CHmac32 baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac32 ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ UInt32 u[kDigestSizeInWords] = { i };
+ const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords;
+ ctx.Update(u, 1);
+ ctx.Final(u, kDigestSizeInWords);
+
+ // Speed-optimized code start
+ ctx = baseCtx;
+ ctx.GetLoopXorDigest(u, numIterations - 1);
+ // Speed-optimized code end
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ /*
+ // Default code start
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSizeInWords);
+ ctx.Final(u, kDigestSizeInWords);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+ // Default code end
+ */
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
new file mode 100755
index 00000000..00a5e009
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
@@ -0,0 +1,21 @@
+// Pbkdf2HmacSha1.h
+// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1
+
+#ifndef __PBKDF2HMACSHA1_H
+#define __PBKDF2HMACSHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize);
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RandGen.cpp b/CPP/7zip/Crypto/Hash/RandGen.cpp
new file mode 100755
index 00000000..480e04ca
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.cpp
@@ -0,0 +1,78 @@
+// RandGen.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "Windows/Synchronization.h"
+
+#include "RandGen.h"
+
+// This is not very good random number generator.
+// Please use it only for salt.
+// First genrated data block depends from timer.
+// Other genrated data blocks depend from previous state
+// Maybe it's possible to restore original timer vaue from generated value.
+
+void CRandomGenerator::Init()
+{
+ NCrypto::NSha1::CContext hash;
+ hash.Init();
+
+ #ifdef _WIN32
+ DWORD w = ::GetCurrentProcessId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ w = ::GetCurrentThreadId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ #endif
+
+ for (int i = 0; i < 1000; i++)
+ {
+ #ifdef _WIN32
+ LARGE_INTEGER v;
+ if (::QueryPerformanceCounter(&v))
+ hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart));
+ #endif
+
+ DWORD tickCount = ::GetTickCount();
+ hash.Update((const Byte *)&tickCount, sizeof(tickCount));
+
+ for (int j = 0; j < 100; j++)
+ {
+ hash.Final(_buff);
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ }
+ }
+ hash.Final(_buff);
+ _needInit = false;
+}
+
+static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
+
+void CRandomGenerator::Generate(Byte *data, unsigned int size)
+{
+ g_CriticalSection.Enter();
+ if (_needInit)
+ Init();
+ while (size > 0)
+ {
+ NCrypto::NSha1::CContext hash;
+
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ hash.Final(_buff);
+
+ hash.Init();
+ UInt32 salt = 0xF672ABD1;
+ hash.Update((const Byte *)&salt, sizeof(salt));
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ Byte buff[NCrypto::NSha1::kDigestSize];
+ hash.Final(buff);
+ for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--)
+ *data++ = buff[i];
+ }
+ g_CriticalSection.Leave();
+}
+
+CRandomGenerator g_RandomGenerator;
diff --git a/CPP/7zip/Crypto/Hash/RandGen.h b/CPP/7zip/Crypto/Hash/RandGen.h
new file mode 100755
index 00000000..3b58a032
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.h
@@ -0,0 +1,21 @@
+// RandGen.h
+
+#ifndef __RANDGEN_H
+#define __RANDGEN_H
+
+#include "Sha1.h"
+
+class CRandomGenerator
+{
+ Byte _buff[NCrypto::NSha1::kDigestSize];
+ bool _needInit;
+
+ void Init();
+public:
+ CRandomGenerator(): _needInit(true) {};
+ void Generate(Byte *data, unsigned int size);
+};
+
+extern CRandomGenerator g_RandomGenerator;
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RotateDefs.h b/CPP/7zip/Crypto/Hash/RotateDefs.h
new file mode 100755
index 00000000..832e7357
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RotateDefs.h
@@ -0,0 +1,19 @@
+// RotateDefs.h
+
+#ifndef __ROTATEDEFS_H
+#define __ROTATEDEFS_H
+
+#ifdef _MSC_VER
+
+#include <stddef.h>
+#define rotlFixed(x, n) _rotl((x), (n))
+#define rotrFixed(x, n) _rotr((x), (n))
+
+#else
+
+#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
+
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha1.cpp b/CPP/7zip/Crypto/Hash/Sha1.cpp
new file mode 100755
index 00000000..0e1d2ecf
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.cpp
@@ -0,0 +1,210 @@
+// Sha1.cpp
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#include "StdAfx.h"
+
+#include "Sha1.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// define it for speed optimization
+// #define _SHA1_UNROLL
+
+static const unsigned int kNumW =
+ #ifdef _SHA1_UNROLL
+ 16;
+ #else
+ 80;
+ #endif
+
+
+#define w0(i) (W[(i)] = data[(i)])
+
+#ifdef _SHA1_UNROLL
+#define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))
+#else
+#define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))
+#endif
+
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+
+#define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30);
+
+#define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)
+#define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)
+#define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)
+#define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)
+#define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)
+
+#define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4);
+#define RX_5(rx, i) RX_1_4(rx, rx, i);
+
+void CContextBase::Init()
+{
+ _state[0] = 0x67452301;
+ _state[1] = 0xEFCDAB89;
+ _state[2] = 0x98BADCFE;
+ _state[3] = 0x10325476;
+ _state[4] = 0xC3D2E1F0;
+ _count = 0;
+}
+
+void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)
+{
+ UInt32 a, b, c, d, e;
+ UInt32 W[kNumW];
+
+ a = _state[0];
+ b = _state[1];
+ c = _state[2];
+ d = _state[3];
+ e = _state[4];
+ #ifdef _SHA1_UNROLL
+ RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);
+ #else
+ int i;
+ for (i = 0; i < 15; i += 5) { RX_5(R0, i); }
+ #endif
+
+ RX_1_4(R0, R1, 15);
+
+
+ #ifdef _SHA1_UNROLL
+ RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);
+ RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);
+ RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);
+ #else
+ i = 20;
+ for (; i < 40; i += 5) { RX_5(R2, i); }
+ for (; i < 60; i += 5) { RX_5(R3, i); }
+ for (; i < 80; i += 5) { RX_5(R4, i); }
+ #endif
+
+ destDigest[0] = _state[0] + a;
+ destDigest[1] = _state[1] + b;
+ destDigest[2] = _state[2] + c;
+ destDigest[3] = _state[3] + d;
+ destDigest[4] = _state[4] + e;
+
+ if (returnRes)
+ for (int i = 0 ; i < 16; i++)
+ data[i] = W[kNumW - 16 + i];
+
+ // Wipe variables
+ // a = b = c = d = e = 0;
+}
+
+void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const
+{
+ unsigned int curBufferPos = size & 0xF;
+ block[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ block[curBufferPos++] = 0;
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);
+ block[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ block[curBufferPos++] = (UInt32)(lenInBits);
+}
+
+void CContext::Update(Byte *data, size_t size, bool rar350Mode)
+{
+ bool returnRes = false;
+ unsigned int curBufferPos = _count2;
+ while (size-- > 0)
+ {
+ int pos = (int)(curBufferPos & 3);
+ if (pos == 0)
+ _buffer[curBufferPos >> 2] = 0;
+ _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));
+ if (++curBufferPos == kBlockSize)
+ {
+ curBufferPos = 0;
+ CContextBase::UpdateBlock(_buffer, returnRes);
+ if (returnRes)
+ for (int i = 0; i < kBlockSizeInWords; i++)
+ {
+ UInt32 d = _buffer[i];
+ data[i * 4 + 0 - kBlockSize] = (Byte)(d);
+ data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);
+ data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);
+ data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);
+ }
+ returnRes = rar350Mode;
+ }
+ }
+ _count2 = curBufferPos;
+}
+
+void CContext::Final(Byte *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
+ unsigned int curBufferPos = _count2;
+ int pos = (int)(curBufferPos & 3);
+ curBufferPos >>= 2;
+ if (pos == 0)
+ _buffer[curBufferPos] = 0;
+ _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));
+
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ UpdateBlock();
+
+ int i;
+ for (i = 0; i < kDigestSizeInWords; i++)
+ {
+ UInt32 state = _state[i] & 0xFFFFFFFF;
+ *digest++ = (Byte)(state >> 24);
+ *digest++ = (Byte)(state >> 16);
+ *digest++ = (Byte)(state >> 8);
+ *digest++ = (Byte)(state);
+ }
+ Init();
+}
+
+///////////////////////////
+// Words version
+
+void CContext32::Update(const UInt32 *data, size_t size)
+{
+ while (size-- > 0)
+ {
+ _buffer[_count2++] = *data++;
+ if (_count2 == kBlockSizeInWords)
+ {
+ _count2 = 0;
+ UpdateBlock();
+ }
+ }
+}
+
+void CContext32::Final(UInt32 *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
+ unsigned int curBufferPos = _count2;
+ _buffer[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ GetBlockDigest(_buffer, digest);
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha1.h b/CPP/7zip/Crypto/Hash/Sha1.h
new file mode 100755
index 00000000..ebb11142
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.h
@@ -0,0 +1,68 @@
+// Sha1.h
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#ifndef __SHA1_H
+#define __SHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+// Sha1 implementation in RAR before version 3.60 has bug:
+// it changes data bytes in some cases.
+// So this class supports both versions: normal_SHA and rar3Mode
+
+namespace NCrypto {
+namespace NSha1 {
+
+const unsigned int kBlockSize = 64;
+const unsigned int kDigestSize = 20;
+
+const unsigned int kBlockSizeInWords = (kBlockSize >> 2);
+const unsigned int kDigestSizeInWords = (kDigestSize >> 2);
+
+class CContextBase
+{
+protected:
+ UInt32 _state[5];
+ UInt64 _count;
+ void UpdateBlock(UInt32 *data, bool returnRes = false)
+ {
+ GetBlockDigest(data, _state, returnRes);
+ _count++;
+ }
+public:
+ void Init();
+ void GetBlockDigest(UInt32 *blockData, UInt32 *destDigest, bool returnRes = false);
+ // PrepareBlock can be used only when size <= 13. size in Words
+ void PrepareBlock(UInt32 *block, unsigned int size) const;
+};
+
+class CContextBase2: public CContextBase
+{
+protected:
+ unsigned int _count2;
+ UInt32 _buffer[kBlockSizeInWords];
+ void UpdateBlock() { CContextBase::UpdateBlock(_buffer); }
+public:
+ void Init() { CContextBase::Init(); _count2 = 0; }
+};
+
+class CContext: public CContextBase2
+{
+public:
+ void Update(Byte *data, size_t size, bool rar350Mode = false);
+ void Update(const Byte *data, size_t size) { Update((Byte *)data, size, false); }
+ void Final(Byte *digest);
+};
+
+class CContext32: public CContextBase2
+{
+public:
+ void Update(const UInt32 *data, size_t size);
+ void Final(UInt32 *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha256.cpp b/CPP/7zip/Crypto/Hash/Sha256.cpp
new file mode 100755
index 00000000..db236058
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.cpp
@@ -0,0 +1,210 @@
+// Crypto/Sha256.cpp
+// This code is based on code from Wei Dai's Crypto++ library.
+
+#include "StdAfx.h"
+
+#include "Sha256.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+// define it for speed optimization
+// #define _SHA256_UNROLL
+// #define _SHA256_UNROLL2
+
+void CContext::Init()
+{
+ _state[0] = 0x6a09e667;
+ _state[1] = 0xbb67ae85;
+ _state[2] = 0x3c6ef372;
+ _state[3] = 0xa54ff53a;
+ _state[4] = 0x510e527f;
+ _state[5] = 0x9b05688c;
+ _state[6] = 0x1f83d9ab;
+ _state[7] = 0x5be0cd19;
+
+ _count = 0;
+}
+
+#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
+#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
+#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
+#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
+
+#define blk0(i) (W[i] = data[i])
+#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))
+
+#define a(i) T[(0-(i))&7]
+#define b(i) T[(1-(i))&7]
+#define c(i) T[(2-(i))&7]
+#define d(i) T[(3-(i))&7]
+#define e(i) T[(4-(i))&7]
+#define f(i) T[(5-(i))&7]
+#define g(i) T[(6-(i))&7]
+#define h(i) T[(7-(i))&7]
+
+
+#ifdef _SHA256_UNROLL2
+
+#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
+ d += h; h += S0(a) + Maj(a, b, c)
+
+#define RX_8(i) \
+ R(a,b,c,d,e,f,g,h, i); \
+ R(h,a,b,c,d,e,f,g, i+1); \
+ R(g,h,a,b,c,d,e,f, i+2); \
+ R(f,g,h,a,b,c,d,e, i+3); \
+ R(e,f,g,h,a,b,c,d, i+4); \
+ R(d,e,f,g,h,a,b,c, i+5); \
+ R(c,d,e,f,g,h,a,b, i+6); \
+ R(b,c,d,e,f,g,h,a, i+7)
+
+#else
+
+#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
+ d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+
+#ifdef _SHA256_UNROLL
+
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+
+#endif
+
+#endif
+
+
+void CContext::Transform(UInt32 *state, const UInt32 *data)
+{
+ UInt32 W[16];
+
+ #ifdef _SHA256_UNROLL2
+ UInt32 a,b,c,d,e,f,g,h;
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+ #else
+ UInt32 T[8];
+ for (int s = 0; s < 8; s++)
+ T[s] = state[s];
+ #endif
+
+ for (unsigned int j = 0; j < 64; j += 16)
+ {
+ #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
+ RX_8(0); RX_8(8);
+ #else
+ for (unsigned int i = 0; i < 16; i++) { R(i); }
+ #endif
+ }
+
+ #ifdef _SHA256_UNROLL2
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+ #else
+ for (int i = 0; i < 8; i++)
+ state[i] += T[i];
+ #endif
+
+ // Wipe variables
+ // memset(W, 0, sizeof(W));
+ // memset(T, 0, sizeof(T));
+}
+
+const UInt32 CContext::K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+
+void CContext::WriteByteBlock()
+{
+ UInt32 data32[16];
+ for (int i = 0; i < 16; i++)
+ {
+ data32[i] = (UInt32(_buffer[i * 4]) << 24) +
+ (UInt32(_buffer[i * 4 + 1]) << 16) +
+ (UInt32(_buffer[i * 4 + 2]) << 8) +
+ UInt32(_buffer[i * 4 + 3]);
+ }
+ Transform(_state, data32);
+}
+
+void CContext::Update(const Byte *data, size_t size)
+{
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ while (size > 0)
+ {
+ _buffer[curBufferPos++] = *data++;
+ _count++;
+ size--;
+ if (curBufferPos == 64)
+ {
+ curBufferPos = 0;
+ WriteByteBlock();
+ }
+ }
+}
+
+void CContext::Final(Byte *digest)
+{
+ UInt64 lenInBits = (_count << 3);
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ _buffer[curBufferPos++] = 0x80;
+ while (curBufferPos != (64 - 8))
+ {
+ curBufferPos &= 0x3F;
+ if (curBufferPos == 0)
+ WriteByteBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ _buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
+ lenInBits <<= 8;
+ }
+ WriteByteBlock();
+
+ for (int j = 0; j < 8; j++)
+ {
+ *digest++ = (Byte)(_state[j] >> 24);
+ *digest++ = (Byte)(_state[j] >> 16);
+ *digest++ = (Byte)(_state[j] >> 8);
+ *digest++ = (Byte)(_state[j]);
+ }
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha256.h b/CPP/7zip/Crypto/Hash/Sha256.h
new file mode 100755
index 00000000..e4788f41
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.h
@@ -0,0 +1,30 @@
+// Crypto/Sha256.h
+
+#ifndef __CRYPTO_SHA256_H
+#define __CRYPTO_SHA256_H
+
+#include "Common/Types.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+class CContext
+{
+ static const UInt32 K[64];
+
+ UInt32 _state[8];
+ UInt64 _count;
+ Byte _buffer[64];
+ static void Transform(UInt32 *digest, const UInt32 *data);
+ void WriteByteBlock();
+public:
+ enum {DIGESTSIZE = 32};
+ CContext() { Init(); } ;
+ void Init();
+ void Update(const Byte *data, size_t size);
+ void Final(Byte *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/StdAfx.h b/CPP/7zip/Crypto/Hash/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp
new file mode 100755
index 00000000..27ccc493
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp
@@ -0,0 +1,76 @@
+// Crypto/Rar20Cipher.cpp
+
+#include "StdAfx.h"
+
+#include "Rar20Cipher.h"
+#include "Windows/Defs.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+static const int kBufferSize = 1 << 17;
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _coder.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ const UInt16 kBlockSize = 16;
+ if (size > 0 && size < kBlockSize)
+ return kBlockSize;
+ UInt32 i;
+ for (i = 0; i + kBlockSize <= size; i += kBlockSize)
+ {
+ _coder.DecryptBlock(data + i);
+ }
+ return i;
+}
+
+/*
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ UInt64 nowPos = 0;
+ UInt32 bufferPos = 0;
+ UInt32 processedSize;
+ for (;;)
+ {
+ UInt32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+
+ UInt32 anEndPos = bufferPos + processedSize;
+ for (;bufferPos + 16 <= anEndPos; bufferPos += 16)
+ _coder.DecryptBlock(_buffer + bufferPos);
+
+ if (bufferPos == 0)
+ return S_OK;
+
+ if (outSize != NULL && nowPos + bufferPos > *outSize)
+ bufferPos = UInt32(*outSize - nowPos);
+
+ RINOK(outStream->Write(_buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+
+ nowPos += processedSize;
+ if (outSize != NULL && nowPos == *outSize)
+ return S_OK;
+
+ int i = 0;
+ while(bufferPos < anEndPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+*/
+
+}}
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.h b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h
new file mode 100755
index 00000000..e2091cda
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h
@@ -0,0 +1,35 @@
+// Crypto/Rar20Cipher.h
+
+#ifndef __CRYPTO_RAR20_CIPHER_H
+#define __CRYPTO_RAR20_CIPHER_H
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "Common/MyCom.h"
+
+#include "Common/Types.h"
+#include "Rar20Crypto.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+class CDecoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+public:
+ CData _coder;
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp
new file mode 100755
index 00000000..d8be2279
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp
@@ -0,0 +1,124 @@
+// Crypto/Rar20/Crypto.cpp
+
+#include "StdAfx.h"
+
+#include "Rar20Crypto.h"
+#include "../../../Common/CRC.h"
+
+#define rol(x,n) (((x) << (n)) | ((x) >> (8 * sizeof(x) - (n))))
+#define ror(x,n) (((x) >> (n)) | ((x) << (8 * sizeof(x) - (n))))
+
+namespace NCrypto {
+namespace NRar20 {
+
+static const int kNumRounds = 32;
+
+static const Byte InitSubstTable[256] = {
+ 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42,
+ 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137,
+ 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6,
+ 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235,
+ 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36,
+ 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251,
+ 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11,
+ 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51,
+ 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7,
+ 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80,
+ 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129,
+ 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10,
+ 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108,
+ 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225,
+ 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52,
+ 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
+};
+
+void CData::UpdateKeys(const Byte *data)
+{
+ for (int i = 0; i < 16; i += 4)
+ for (int j = 0; j < 4; j++)
+ Keys[j] ^= CCRC::Table[data[i + j]];
+}
+
+static void Swap(Byte *b1, Byte *b2)
+{
+ Byte b = *b1;
+ *b1 = *b2;
+ *b2 = b;
+}
+
+void CData::SetPassword(const Byte *password, UInt32 passwordLength)
+{
+ // SetOldKeys(password);
+
+ Keys[0] = 0xD3A3B879L;
+ Keys[1] = 0x3F6D12F7L;
+ Keys[2] = 0x7515A235L;
+ Keys[3] = 0xA4E7F123L;
+
+ Byte psw[256];
+ memset(psw, 0, sizeof(psw));
+
+ memmove(psw, password, passwordLength);
+
+ memcpy(SubstTable, InitSubstTable, sizeof(SubstTable));
+ for (UInt32 j = 0; j < 256; j++)
+ for (UInt32 i = 0; i < passwordLength; i += 2)
+ {
+ UInt32 n2 = (Byte)CCRC::Table[(psw[i + 1] + j) & 0xFF];
+ UInt32 n1 = (Byte)CCRC::Table[(psw[i] - j) & 0xFF];
+ for (UInt32 k = 1; (n1 & 0xFF) != n2; n1++, k++)
+ Swap(&SubstTable[n1 & 0xFF], &SubstTable[(n1 + i + k) & 0xFF]);
+ }
+ for (UInt32 i = 0; i < passwordLength; i+= 16)
+ EncryptBlock(&psw[i]);
+}
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+static inline void WriteUInt32ToMemLE(UInt32 v, Byte *p)
+{
+ p[0] = (Byte)v;
+ p[1] = (Byte)(v >> 8);
+ p[2] = (Byte)(v >> 16);
+ p[3] = (Byte)(v >> 24);
+}
+
+void CData::CryptBlock(Byte *buf, bool encrypt)
+{
+ Byte inBuf[16];
+ UInt32 A, B, C, D, T, TA, TB;
+
+ A = GetUInt32FromMemLE(buf + 0) ^ Keys[0];
+ B = GetUInt32FromMemLE(buf + 4) ^ Keys[1];
+ C = GetUInt32FromMemLE(buf + 8) ^ Keys[2];
+ D = GetUInt32FromMemLE(buf + 12) ^ Keys[3];
+
+ if (!encrypt)
+ memcpy(inBuf, buf, sizeof(inBuf));
+
+ for(int i = 0; i < kNumRounds; i++)
+ {
+ UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
+ T = ((C + rol(D, 11)) ^ key);
+ TA = A ^ SubstLong(T);
+ T = ((D ^ rol(C, 17)) + key);
+ TB = B ^ SubstLong(T);
+ A = C;
+ B = D;
+ C = TA;
+ D = TB;
+ }
+
+ WriteUInt32ToMemLE(C ^ Keys[0], buf + 0);
+ WriteUInt32ToMemLE(D ^ Keys[1], buf + 4);
+ WriteUInt32ToMemLE(A ^ Keys[2], buf + 8);
+ WriteUInt32ToMemLE(B ^ Keys[3], buf + 12);
+
+ UpdateKeys(encrypt ? buf : inBuf);
+}
+
+
+}}
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h
new file mode 100755
index 00000000..071d01f1
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h
@@ -0,0 +1,33 @@
+// Crypto/Rar20/Crypto.h
+
+#ifndef __CRYPTO_RAR20_CRYPTO_H
+#define __CRYPTO_RAR20_CRYPTO_H
+
+#include "../../../Common/Types.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+class CData
+{
+ Byte SubstTable[256];
+ UInt32 Keys[4];
+ UInt32 SubstLong(UInt32 t)
+ {
+ return (UInt32)SubstTable[(int)t & 255] |
+ ((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) |
+ ((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) |
+ ((UInt32)SubstTable[(int)(t >> 24) & 255] << 24);
+ }
+
+ void UpdateKeys(const Byte *data);
+ void CryptBlock(Byte *buf, bool encrypt);
+public:
+ void EncryptBlock(Byte *buf) { CryptBlock(buf, true); }
+ void DecryptBlock(Byte *buf) { CryptBlock(buf, false); }
+ void SetPassword(const Byte *password, UInt32 passwordLength);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/StdAfx.h b/CPP/7zip/Crypto/Rar20/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/RarAES/RarAES.cpp b/CPP/7zip/Crypto/RarAES/RarAES.cpp
new file mode 100755
index 00000000..ae22bb2a
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/RarAES.cpp
@@ -0,0 +1,187 @@
+// Crypto/RarAES/RarAES.h
+// This code is based on UnRar sources
+
+#include "StdAfx.h"
+
+#include "RarAES.h"
+#include "../Hash/Sha1.h"
+
+extern void GetCryptoFolderPrefix(TCHAR *path);
+
+namespace NCrypto {
+namespace NRar29 {
+
+CDecoder::CDecoder():
+ _thereIsSalt(false),
+ _needCalculate(true),
+ _rar350Mode(false)
+{
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = 0;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ bool thereIsSaltPrev = _thereIsSalt;
+ _thereIsSalt = false;
+ if (size == 0)
+ return S_OK;
+ if (size < 8)
+ return E_INVALIDARG;
+ _thereIsSalt = true;
+ bool same = false;
+ if (_thereIsSalt == thereIsSaltPrev)
+ {
+ same = true;
+ if (_thereIsSalt)
+ {
+ for (int i = 0; i < sizeof(_salt); i++)
+ if (_salt[i] != data[i])
+ {
+ same = false;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = data[i];
+ if (!_needCalculate && !same)
+ _needCalculate = true;
+ return S_OK;
+}
+
+static const int kMaxPasswordLength = 127 * 2;
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ if (size > kMaxPasswordLength)
+ size = kMaxPasswordLength;
+ bool same = false;
+ if (size == buffer.GetCapacity())
+ {
+ same = true;
+ for (UInt32 i = 0; i < size; i++)
+ if (data[i] != buffer[i])
+ {
+ same = false;
+ break;
+ }
+ }
+ if (!_needCalculate && !same)
+ _needCalculate = true;
+ buffer.SetCapacity(size);
+ memcpy(buffer, data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ Calculate();
+ RINOK(CreateFilter());
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ RINOK(cp->SetKey(aesKey, 16));
+ RINOK(cp->SetInitVector(aesInit, 16));
+ _aesFilter->Init();
+ return S_OK;
+}
+
+HRESULT CDecoder::CreateFilter()
+{
+ if (_aesFilter)
+ return S_OK;
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_CBC_Decoder, &_aesFilter);
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ return _aesFilter->Filter(data, size);
+}
+
+void CDecoder::Calculate()
+{
+ if (_needCalculate)
+ {
+ const int kSaltSize = 8;
+
+ Byte rawPassword[kMaxPasswordLength + kSaltSize];
+
+ memcpy(rawPassword, buffer, buffer.GetCapacity());
+
+ size_t rawLength = buffer.GetCapacity();
+
+ if (_thereIsSalt)
+ {
+ memcpy(rawPassword + rawLength, _salt, kSaltSize);
+ rawLength += kSaltSize;
+ }
+
+ NSha1::CContext sha;
+ sha.Init();
+
+ // seems rar reverts hash for sha.
+ const int hashRounds = 0x40000;
+ int i;
+ for (i = 0; i < hashRounds; i++)
+ {
+ sha.Update(rawPassword, rawLength, _rar350Mode);
+ Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
+ sha.Update(pswNum, 3, _rar350Mode);
+ if (i % (hashRounds / 16) == 0)
+ {
+ NSha1::CContext shaTemp = sha;
+ Byte digest[NSha1::kDigestSize];
+ shaTemp.Final(digest);
+ aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3];
+ }
+ }
+ /*
+ // it's test message for sha
+ const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ sha.Update((const Byte *)message, strlen(message));
+ */
+ Byte digest[20];
+ sha.Final(digest);
+ for (i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]);
+ }
+ _needCalculate = false;
+}
+
+
+
+/*
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UInt64 const *inSize,
+ const UInt64 *outSize,ICompressProgressInfo *progress)
+{
+ Calculate();
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ CCoderLibrary aesLib;
+ CMyComPtr<ICompressCoder2> aesDecoder;
+ RINOK(aesLib.LoadAndCreateCoder2(aesLibPath, CLSID_CCrypto_AES128_Decoder, &aesDecoder));
+
+ CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
+ ivStreamSpec->Init(aesInit, 16);
+
+ CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
+ keyStreamSpec->Init(aesKey, 16);
+
+ ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
+ UInt64 ivSize = 16;
+ UInt64 keySize = 16;
+ const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
+ return aesDecoder->Code(inStreams, inSizes, 3,
+ &outStream, &outSize, 1, progress);
+}
+*/
+
+}}
diff --git a/CPP/7zip/Crypto/RarAES/RarAES.h b/CPP/7zip/Crypto/RarAES/RarAES.h
new file mode 100755
index 00000000..4b435b5e
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/RarAES.h
@@ -0,0 +1,61 @@
+// Crypto/CRarAES/RarAES.h
+
+#ifndef __CRYPTO_RARAES_H
+#define __CRYPTO_RARAES_H
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Archive/Common/CoderLoader.h"
+
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+namespace NCrypto {
+namespace NRar29 {
+
+class CDecoder:
+ public ICompressFilter,
+ public ICompressSetDecoderProperties2,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+ Byte _salt[8];
+ bool _thereIsSalt;
+ CByteBuffer buffer;
+ Byte aesKey[16];
+ Byte aesInit[16];
+ bool _needCalculate;
+
+ CCoderLibrary _aesLib;
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ bool _rar350Mode;
+
+ void Calculate();
+ HRESULT CreateFilter();
+
+public:
+
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize);
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ CDecoder();
+ void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/RarAES/StdAfx.h b/CPP/7zip/Crypto/RarAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.cpp b/CPP/7zip/Crypto/WzAES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.h b/CPP/7zip/Crypto/WzAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/WzAES/WzAES.cpp b/CPP/7zip/Crypto/WzAES/WzAES.cpp
new file mode 100755
index 00000000..8bf53b43
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/WzAES.cpp
@@ -0,0 +1,246 @@
+// WzAES.cpp
+/*
+This code implements Brian Gladman's scheme
+specified in password Based File Encryption Utility.
+*/
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+#include "../Hash/Pbkdf2HmacSha1.h"
+#include "../Hash/RandGen.h"
+
+#include "WzAES.h"
+
+#ifdef CRYPTO_AES
+#include "../AES/MyAES.h"
+#else
+extern void GetCryptoFolderPrefix(TCHAR *path);
+#endif
+
+// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1
+// #define _NO_WZAES_OPTIMIZATIONS
+
+namespace NCrypto {
+namespace NWzAES {
+
+const unsigned int kAesKeySizeMax = 32;
+
+static const UInt32 kNumKeyGenIterations = 1000;
+
+STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ if(size > kPasswordSizeMax)
+ return E_INVALIDARG;
+ _key.Password.SetCapacity(size);
+ memcpy(_key.Password, data, size);
+ return S_OK;
+}
+
+void CBaseCoder::EncryptData(Byte *data, UInt32 size)
+{
+ unsigned int pos = _blockPos;
+ for (; size > 0; size--)
+ {
+ if (pos == kAesBlockSize)
+ {
+ int j;
+ for (j = 0; j < 8 && ++_counter[j] == 0; j++);
+ for (j = 0; j < 8; j++)
+ _buffer[j] = _counter[j];
+ for (; j < kAesBlockSize; j++)
+ _buffer[j] = 0;
+ _aesFilter->Filter(_buffer, kAesBlockSize);
+ pos = 0;
+ }
+ *data++ ^= _buffer[pos++];
+ }
+ _blockPos = pos;
+}
+
+#ifndef _NO_WZAES_OPTIMIZATIONS
+
+static void BytesToBeUInt32s(const Byte *src, UInt32 *dest, int destSize)
+{
+ for (int i = 0 ; i < destSize; i++)
+ dest[i] =
+ ((UInt32)(src[i * 4 + 0]) << 24) |
+ ((UInt32)(src[i * 4 + 1]) << 16) |
+ ((UInt32)(src[i * 4 + 2]) << 8) |
+ ((UInt32)(src[i * 4 + 3]));
+}
+
+#endif
+
+STDMETHODIMP CBaseCoder::Init()
+{
+ UInt32 keySize = _key.GetKeySize();
+ UInt32 keysTotalSize = 2 * keySize + kPwdVerifCodeSize;
+ Byte buf[2 * kAesKeySizeMax + kPwdVerifCodeSize];
+
+ // for (int ii = 0; ii < 1000; ii++)
+ {
+ #ifdef _NO_WZAES_OPTIMIZATIONS
+
+ NSha1::Pbkdf2Hmac(
+ _key.Password, _key.Password.GetCapacity(),
+ _key.Salt, _key.GetSaltSize(),
+ kNumKeyGenIterations,
+ buf, keysTotalSize);
+
+ #else
+
+ UInt32 buf32[(2 * kAesKeySizeMax + kPwdVerifCodeSize + 3) / 4];
+ UInt32 key32SizeTotal = (keysTotalSize + 3) / 4;
+ UInt32 salt[kSaltSizeMax * 4];
+ UInt32 saltSizeInWords = _key.GetSaltSize() / 4;
+ BytesToBeUInt32s(_key.Salt, salt, saltSizeInWords);
+ NSha1::Pbkdf2Hmac32(
+ _key.Password, _key.Password.GetCapacity(),
+ salt, saltSizeInWords,
+ kNumKeyGenIterations,
+ buf32, key32SizeTotal);
+ for (UInt32 j = 0; j < keysTotalSize; j++)
+ buf[j] = (Byte)(buf32[j / 4] >> (24 - 8 * (j & 3)));
+
+ #endif
+ }
+
+ _hmac.SetKey(buf + keySize, keySize);
+ memcpy(_key.PwdVerifComputed, buf + 2 * keySize, kPwdVerifCodeSize);
+
+ _blockPos = kAesBlockSize;
+ for (int i = 0; i < 8; i++)
+ _counter[i] = 0;
+
+ RINOK(CreateFilters());
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ return cp->SetKey(buf, keySize);
+}
+
+static HRESULT SafeWrite(ISequentialOutStream *outStream, const Byte *data, UInt32 size)
+{
+ UInt32 processedSize;
+ RINOK(WriteStream(outStream, data, size, &processedSize));
+ return ((processedSize == size) ? S_OK : E_FAIL);
+}
+
+/*
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte keySizeMode = 3;
+ return outStream->Write(&keySizeMode, 1, NULL);
+}
+*/
+
+HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
+{
+ UInt32 saltSize = _key.GetSaltSize();
+ g_RandomGenerator.Generate(_key.Salt, saltSize);
+ Init();
+ RINOK(SafeWrite(outStream, _key.Salt, saltSize));
+ return SafeWrite(outStream, _key.PwdVerifComputed, kPwdVerifCodeSize);
+}
+
+HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream)
+{
+ Byte mac[kMacSize];
+ _hmac.Final(mac, kMacSize);
+ return SafeWrite(outStream, mac, kMacSize);
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size != 1)
+ return E_INVALIDARG;
+ _key.Init();
+ Byte keySizeMode = data[0];
+ if (keySizeMode < 1 || keySizeMode > 3)
+ return E_INVALIDARG;
+ _key.KeySizeMode = keySizeMode;
+ return S_OK;
+}
+
+HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
+{
+ UInt32 saltSize = _key.GetSaltSize();
+ UInt32 extraSize = saltSize + kPwdVerifCodeSize;
+ Byte temp[kSaltSizeMax + kPwdVerifCodeSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, temp, extraSize, &processedSize));
+ if (processedSize != extraSize)
+ return E_FAIL;
+ UInt32 i;
+ for (i = 0; i < saltSize; i++)
+ _key.Salt[i] = temp[i];
+ for (i = 0; i < kPwdVerifCodeSize; i++)
+ _pwdVerifFromArchive[i] = temp[saltSize + i];
+ return S_OK;
+}
+
+static bool CompareArrays(const Byte *p1, const Byte *p2, UInt32 size)
+{
+ for (UInt32 i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+
+bool CDecoder::CheckPasswordVerifyCode()
+{
+ return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifCodeSize);
+}
+
+HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK)
+{
+ isOK = false;
+ UInt32 processedSize;
+ Byte mac1[kMacSize];
+ RINOK(ReadStream(inStream, mac1, kMacSize, &processedSize));
+ if (processedSize != kMacSize)
+ return E_FAIL;
+ Byte mac2[kMacSize];
+ _hmac.Final(mac2, kMacSize);
+ isOK = CompareArrays(mac1, mac2, kMacSize);
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
+{
+ EncryptData(data, size);
+ _hmac.Update(data, size);
+ return size;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ _hmac.Update(data, size);
+ EncryptData(data, size);
+ return size;
+}
+
+
+HRESULT CBaseCoder::CreateFilters()
+{
+ if (!_aesFilter)
+ {
+ #ifdef CRYPTO_AES
+
+ _aesFilter = new CAES_ECB_Encoder;
+
+ #else
+
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ RINOK(_aesLibrary.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_ECB_Encoder, &_aesFilter));
+
+ #endif
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Crypto/WzAES/WzAES.h b/CPP/7zip/Crypto/WzAES/WzAES.h
new file mode 100755
index 00000000..c27bd326
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/WzAES.h
@@ -0,0 +1,126 @@
+// WzAES.h
+/*
+This code implements Brian Gladman's scheme
+specified in password Based File Encryption Utility:
+ - AES encryption (128,192,256-bit) in Counter (CTR) mode.
+ - HMAC-SHA1 authentication for encrypted data (10 bytes)
+ - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and
+ Salt (saltSize = aesKeySize / 2).
+ - 2 bytes contain Password Verifier's Code
+*/
+
+#ifndef __CRYPTO_WZ_AES_H
+#define __CRYPTO_WZ_AES_H
+
+#include "../Hash/HmacSha1.h"
+
+#include "Common/MyCom.h"
+#include "Common/Buffer.h"
+#include "Common/Vector.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#ifndef CRYPTO_AES
+#include "../../Archive/Common/CoderLoader.h"
+#endif
+
+DEFINE_GUID(CLSID_CCrypto_AES_ECB_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+namespace NCrypto {
+namespace NWzAES {
+
+const unsigned int kAesBlockSize = 16;
+const unsigned int kSaltSizeMax = 16;
+const unsigned int kMacSize = 10;
+
+const UInt32 kPasswordSizeMax = 99; // 128;
+
+// Password Verification Code Size
+const unsigned int kPwdVerifCodeSize = 2;
+
+class CKeyInfo
+{
+public:
+ Byte KeySizeMode; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
+ Byte Salt[kSaltSizeMax];
+ Byte PwdVerifComputed[kPwdVerifCodeSize];
+
+ CByteBuffer Password;
+
+ UInt32 GetKeySize() const { return (8 * (KeySizeMode & 3) + 8); }
+ UInt32 GetSaltSize() const { return (4 * (KeySizeMode & 3) + 4); }
+
+ CKeyInfo() { Init(); }
+ void Init() { KeySizeMode = 3; }
+};
+
+class CBaseCoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+protected:
+ CKeyInfo _key;
+ Byte _counter[8];
+ Byte _buffer[kAesBlockSize];
+ NSha1::CHmac _hmac;
+ unsigned int _blockPos;
+ Byte _pwdVerifFromArchive[kPwdVerifCodeSize];
+
+ void EncryptData(Byte *data, UInt32 size);
+
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesLibrary;
+ #endif
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ HRESULT CreateFilters();
+public:
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0;
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ UInt32 GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifCodeSize; }
+};
+
+class CEncoder:
+ public CBaseCoder
+ // public ICompressWriteCoderProperties
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+ // ICompressWriteCoderProperties
+ // STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ HRESULT WriteHeader(ISequentialOutStream *outStream);
+ HRESULT WriteFooter(ISequentialOutStream *outStream);
+ bool SetKeyMode(Byte mode)
+ {
+ if (mode < 1 || mode > 3)
+ return false;
+ _key.KeySizeMode = mode;
+ return true;
+ }
+};
+
+class CDecoder:
+ public CBaseCoder,
+ public ICompressSetDecoderProperties2
+{
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ HRESULT ReadHeader(ISequentialInStream *inStream);
+ bool CheckPasswordVerifyCode();
+ HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/StdAfx.h b/CPP/7zip/Crypto/Zip/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.cpp b/CPP/7zip/Crypto/Zip/ZipCipher.cpp
new file mode 100755
index 00000000..639776ce
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCipher.cpp
@@ -0,0 +1,85 @@
+// Crypto/ZipCipher.h
+
+#include "StdAfx.h"
+
+#include "ZipCipher.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+#include "../Hash/RandGen.h"
+
+namespace NCrypto {
+namespace NZip {
+
+STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _cipher.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc)
+{
+ _crc = crc;
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::Init()
+{
+ return S_OK;
+}
+
+HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
+{
+ Byte header[kHeaderSize];
+ g_RandomGenerator.Generate(header, kHeaderSize - 2);
+
+ header[kHeaderSize - 1] = Byte(_crc >> 24);
+ header[kHeaderSize - 2] = Byte(_crc >> 16);
+
+ UInt32 processedSize;
+ _cipher.EncryptHeader(header);
+ RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 i;
+ for (i = 0; i < size; i++)
+ data[i] = _cipher.EncryptByte(data[i]);
+ return i;
+}
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _cipher.SetPassword(data, size);
+ return S_OK;
+}
+
+HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
+{
+ Byte header[kHeaderSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+ _cipher.DecryptHeader(header);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 i;
+ for (i = 0; i < size; i++)
+ data[i] = _cipher.DecryptByte(data[i]);
+ return i;
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.h b/CPP/7zip/Crypto/Zip/ZipCipher.h
new file mode 100755
index 00000000..d750336c
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCipher.h
@@ -0,0 +1,59 @@
+// Crypto/ZipCipher.h
+
+#ifndef __CRYPTO_ZIPCIPHER_H
+#define __CRYPTO_ZIPCIPHER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#include "ZipCrypto.h"
+
+namespace NCrypto {
+namespace NZip {
+
+class CEncoder :
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public ICryptoSetCRC,
+ public CMyUnknownImp
+{
+ CCipher _cipher;
+ UInt32 _crc;
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICryptoSetCRC
+ )
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ STDMETHOD(CryptoSetCRC)(UInt32 crc);
+ HRESULT WriteHeader(ISequentialOutStream *outStream);
+};
+
+
+class CDecoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+ // public CBuffer2
+{
+ CCipher _cipher;
+public:
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ HRESULT ReadHeader(ISequentialInStream *inStream);
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.cpp b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp
new file mode 100755
index 00000000..79f0953c
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp
@@ -0,0 +1,65 @@
+// Crypto/ZipCrypto.cpp
+
+#include "StdAfx.h"
+
+#include "ZipCipher.h"
+#include "../../../Common/CRC.h"
+
+namespace NCrypto {
+namespace NZip {
+
+static inline UInt32 ZipCRC32(UInt32 c, Byte b)
+{
+ return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8);
+}
+
+void CCipher::UpdateKeys(Byte b)
+{
+ Keys[0] = ZipCRC32(Keys[0], b);
+ Keys[1] += Keys[0] & 0xff;
+ Keys[1] = Keys[1] * 134775813L + 1;
+ Keys[2] = ZipCRC32(Keys[2], (Byte)(Keys[1] >> 24));
+}
+
+void CCipher::SetPassword(const Byte *password, UInt32 passwordLength)
+{
+ Keys[0] = 305419896L;
+ Keys[1] = 591751049L;
+ Keys[2] = 878082192L;
+ for (UInt32 i = 0; i < passwordLength; i++)
+ UpdateKeys(password[i]);
+}
+
+Byte CCipher::DecryptByteSpec()
+{
+ UInt32 temp = Keys[2] | 2;
+ return (Byte)((temp * (temp ^ 1)) >> 8);
+}
+
+Byte CCipher::DecryptByte(Byte encryptedByte)
+{
+ Byte c = (Byte)(encryptedByte ^ DecryptByteSpec());
+ UpdateKeys(c);
+ return c;
+}
+
+Byte CCipher::EncryptByte(Byte b)
+{
+ Byte c = (Byte)(b ^ DecryptByteSpec());
+ UpdateKeys(b);
+ return c;
+}
+
+void CCipher::DecryptHeader(Byte *buffer)
+{
+ for (int i = 0; i < 12; i++)
+ buffer[i] = DecryptByte(buffer[i]);
+}
+
+void CCipher::EncryptHeader(Byte *buffer)
+{
+ for (int i = 0; i < 12; i++)
+ buffer[i] = EncryptByte(buffer[i]);
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.h b/CPP/7zip/Crypto/Zip/ZipCrypto.h
new file mode 100755
index 00000000..6b4ecaaa
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCrypto.h
@@ -0,0 +1,26 @@
+// Crypto/ZipCrypto.h
+
+#ifndef __CRYPTO_ZIP_CRYPTO_H
+#define __CRYPTO_ZIP_CRYPTO_H
+
+namespace NCrypto {
+namespace NZip {
+
+const int kHeaderSize = 12;
+class CCipher
+{
+ UInt32 Keys[3];
+ void UpdateKeys(Byte b);
+ Byte DecryptByteSpec();
+public:
+ void SetPassword(const Byte *password, UInt32 passwordLength);
+ Byte DecryptByte(Byte encryptedByte);
+ Byte EncryptByte(Byte b);
+ void DecryptHeader(Byte *buffer);
+ void EncryptHeader(Byte *buffer);
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/makefile b/CPP/7zip/Crypto/makefile
new file mode 100755
index 00000000..61f59603
--- /dev/null
+++ b/CPP/7zip/Crypto/makefile
@@ -0,0 +1,8 @@
+DIRS = \
+ 7zAES\~ \
+ AES\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"