mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 22:11:38 -06:00
3.13
This commit is contained in:
355
7zip/Crypto/7zAES/7zAES.cpp
Executable file
355
7zip/Crypto/7zAES/7zAES.cpp
Executable file
@@ -0,0 +1,355 @@
|
||||
// 7z_AES.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
#include "7zAES.h"
|
||||
// #include "../../Hash/Common/CryptoHashInterface.h"
|
||||
|
||||
#ifdef CRYPTO_AES
|
||||
#include "../AES/MyAES.h"
|
||||
#endif
|
||||
|
||||
#include "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
|
||||
{
|
||||
/*
|
||||
CMyComPtr<ICryptoHash> sha;
|
||||
RINOK(sha.CoCreateInstance(CLSID_CCrypto_Hash_SHA256));
|
||||
RINOK(sha->Init());
|
||||
*/
|
||||
|
||||
NCrypto::NSHA256::SHA256 sha;
|
||||
const UINT64 numRounds = UINT64(1) << (NumCyclesPower);
|
||||
for (UINT64 round = 0; round < numRounds; round++)
|
||||
{
|
||||
/*
|
||||
RINOK(sha->Update(Salt, SaltSize));
|
||||
RINOK(sha->Update(Password, Password.GetCapacity()));
|
||||
// change it if big endian;
|
||||
RINOK(sha->Update(&round, sizeof(round)));
|
||||
*/
|
||||
|
||||
// sha.Update(Salt, sizeof(Salt));
|
||||
sha.Update(Salt, SaltSize);
|
||||
sha.Update(Password, Password.GetCapacity());
|
||||
// change it if big endian;
|
||||
sha.Update((const BYTE *)&round, sizeof(round));
|
||||
}
|
||||
// return sha->GetDigest(Key);
|
||||
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 = _key.NumCyclesPower |
|
||||
(((_key.SaltSize == 0) ? 0 : 1) << 7) |
|
||||
(((ivSize == 0) ? 0 : 1) << 6);
|
||||
RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL));
|
||||
if (_key.SaltSize == 0 && ivSize == 0)
|
||||
return S_OK;
|
||||
BYTE saltSizeSpec = (_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1);
|
||||
BYTE ivSizeSpec = (ivSize == 0) ? 0 : (ivSize - 1);
|
||||
BYTE secondByte = ((saltSizeSpec) << 4) | ivSizeSpec;
|
||||
RINOK(outStream->Write(&secondByte, sizeof(secondByte), NULL));
|
||||
if (_key.SaltSize > 0)
|
||||
{
|
||||
RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL));
|
||||
}
|
||||
if (ivSize > 0)
|
||||
{
|
||||
RINOK(outStream->Write(_iv, ivSize, NULL));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
{
|
||||
_key.Init();
|
||||
for (int i = 0; i < sizeof(_iv); i++)
|
||||
_iv[i] = 0;
|
||||
UINT32 processedSize;
|
||||
BYTE firstByte;
|
||||
RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processedSize));
|
||||
if (processedSize == 0)
|
||||
return S_OK;
|
||||
|
||||
_key.NumCyclesPower = firstByte & 0x3F;
|
||||
if ((firstByte & 0xC0) == 0)
|
||||
return S_OK;
|
||||
_key.SaltSize = (firstByte >> 7) & 1;
|
||||
UINT32 ivSize = (firstByte >> 6) & 1;
|
||||
|
||||
BYTE secondByte;
|
||||
RINOK(inStream->Read(&secondByte, sizeof(secondByte), &processedSize));
|
||||
if (processedSize == 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
_key.SaltSize += (secondByte >> 4);
|
||||
ivSize += (secondByte & 0x0F);
|
||||
|
||||
RINOK(inStream->Read(_key.Salt,
|
||||
_key.SaltSize, &processedSize));
|
||||
if (processedSize != _key.SaltSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
RINOK(inStream->Read(_iv, ivSize, &processedSize));
|
||||
if (processedSize != ivSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
{
|
||||
_key.Password.SetCapacity(size);
|
||||
memcpy(_key.Password, data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::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 CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
{
|
||||
CalculateDigest();
|
||||
|
||||
if (_aesEncoder == 0)
|
||||
{
|
||||
#ifdef CRYPTO_AES
|
||||
_aesEncoder = new CAES256_CBC_Encoder;
|
||||
#else
|
||||
if ((HMODULE)_aesEncoderLibrary == 0)
|
||||
{
|
||||
TCHAR filePath[MAX_PATH + 2];
|
||||
if (!GetAESLibPath(filePath))
|
||||
return ::GetLastError();
|
||||
RINOK(_aesEncoderLibrary.LoadAndCreateCoder2(filePath,
|
||||
CLSID_CCrypto_AES256_Encoder, &_aesEncoder));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
|
||||
ivStreamSpec->Init(_iv, sizeof(_iv));
|
||||
|
||||
CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
|
||||
keyStreamSpec->Init(_key.Key, sizeof(_key.Key));
|
||||
|
||||
ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
|
||||
UINT64 ivSize = sizeof(_iv);
|
||||
UINT64 keySize = sizeof(_key.Key);
|
||||
const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
|
||||
return _aesEncoder->Code(inStreams, inSizes, 3,
|
||||
&outStream, &outSize, 1, progress);
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
{
|
||||
CalculateDigest();
|
||||
|
||||
if (_aesDecoder == 0)
|
||||
{
|
||||
#ifdef CRYPTO_AES
|
||||
_aesDecoder = new CAES256_CBC_Decoder;
|
||||
#else
|
||||
if ((HMODULE)_aesDecoderLibrary == 0)
|
||||
{
|
||||
TCHAR filePath[MAX_PATH + 2];
|
||||
if (!GetAESLibPath(filePath))
|
||||
return ::GetLastError();
|
||||
RINOK(_aesDecoderLibrary.LoadAndCreateCoder2(filePath,
|
||||
CLSID_CCrypto_AES256_Decoder, &_aesDecoder));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
|
||||
ivStreamSpec->Init(_iv, sizeof(_iv));
|
||||
|
||||
CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
|
||||
keyStreamSpec->Init(_key.Key, sizeof(_key.Key));
|
||||
|
||||
ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
|
||||
UINT64 ivSize = sizeof(_iv);
|
||||
UINT64 keySize = sizeof(_key.Key);
|
||||
const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
|
||||
return _aesDecoder->Code(inStreams, inSizes, 3,
|
||||
&outStream, &outSize, 1, progress);
|
||||
}
|
||||
|
||||
}}
|
||||
8
7zip/Crypto/7zAES/7zAES.def
Executable file
8
7zip/Crypto/7zAES/7zAES.def
Executable file
@@ -0,0 +1,8 @@
|
||||
; 7zAES.def
|
||||
|
||||
LIBRARY 7zAES.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetNumberOfMethods PRIVATE
|
||||
GetMethodProperty PRIVATE
|
||||
209
7zip/Crypto/7zAES/7zAES.dsp
Executable file
209
7zip/Crypto/7zAES/7zAES.dsp
Executable file
@@ -0,0 +1,209 @@
|
||||
# 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=.\7zAES.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# 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\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
|
||||
# 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 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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\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=.\SHA256.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Crypto/7zAES/7zAES.dsw
Executable file
29
7zip/Crypto/7zAES/7zAES.dsw
Executable file
@@ -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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
139
7zip/Crypto/7zAES/7zAES.h
Executable file
139
7zip/Crypto/7zAES/7zAES.h
Executable file
@@ -0,0 +1,139 @@
|
||||
// 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
|
||||
|
||||
// {23170F69-40C1-278B-0601-810000000100}
|
||||
DEFINE_GUID(CLSID_CCrypto_AES256_Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x81, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0601-810000000000}
|
||||
DEFINE_GUID(CLSID_CCrypto_AES256_Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x81, 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 CEncoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICryptoSetPassword,
|
||||
public ICompressWriteCoderProperties,
|
||||
public CMyUnknownImp,
|
||||
public CBase
|
||||
{
|
||||
MY_UNKNOWN_IMP3(
|
||||
ICryptoSetPassword,
|
||||
ICompressSetDecoderProperties,
|
||||
ICompressWriteCoderProperties
|
||||
)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
|
||||
// ICompressWriteCoderProperties
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
|
||||
#ifndef CRYPTO_AES
|
||||
CCoderLibrary _aesEncoderLibrary;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder2> _aesEncoder;
|
||||
};
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp,
|
||||
public CBase
|
||||
{
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICompressSetDecoderProperties
|
||||
)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
|
||||
// ICompressSetDecoderProperties
|
||||
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
|
||||
#ifndef CRYPTO_AES
|
||||
CCoderLibrary _aesDecoderLibrary;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder2> _aesDecoder;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
96
7zip/Crypto/7zAES/DllExports.cpp
Executable file
96
7zip/Crypto/7zAES/DllExports.cpp
Executable file
@@ -0,0 +1,96 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#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;
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
g_hInstance = hInstance;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
if (*clsid == CLSID_CCrypto7zAESDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCrypto::NSevenZ::CDecoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCrypto7zAESEncoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCrypto::NSevenZ::CEncoder();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.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)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;
|
||||
}
|
||||
|
||||
189
7zip/Crypto/7zAES/SHA256.cpp
Executable file
189
7zip/Crypto/7zAES/SHA256.cpp
Executable file
@@ -0,0 +1,189 @@
|
||||
// Crypto/HASH/SHA256/SHA256.cpp
|
||||
// This code is based on code from Wei Dai's Crypto++ library.
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SHA256.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
const int kBufferSize = 1 << 17;
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NSHA256 {
|
||||
|
||||
|
||||
template <class T> static inline T rotrFixed(T x, unsigned int y)
|
||||
{
|
||||
// assert(y < sizeof(T)*8);
|
||||
return (x>>y) | (x<<(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
#define blk0(i) (W[i] = data[i])
|
||||
|
||||
|
||||
void SHA256::Init()
|
||||
{
|
||||
m_digest[0] = 0x6a09e667;
|
||||
m_digest[1] = 0xbb67ae85;
|
||||
m_digest[2] = 0x3c6ef372;
|
||||
m_digest[3] = 0xa54ff53a;
|
||||
m_digest[4] = 0x510e527f;
|
||||
m_digest[5] = 0x9b05688c;
|
||||
m_digest[6] = 0x1f83d9ab;
|
||||
m_digest[7] = 0x5be0cd19;
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
#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]
|
||||
|
||||
#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))
|
||||
|
||||
// for SHA256
|
||||
#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))
|
||||
|
||||
void SHA256::Transform(UINT32 *state, const UINT32 *data)
|
||||
{
|
||||
UINT32 W[16];
|
||||
UINT32 T[8];
|
||||
/* Copy context->state[] to working vars */
|
||||
// memcpy(T, state, sizeof(T));
|
||||
for (int s = 0; s < 8; s++)
|
||||
T[s] = state[s];
|
||||
|
||||
|
||||
/* 64 operations, partially loop unrolled */
|
||||
for (unsigned int j = 0; j < 64; j += 16)
|
||||
{
|
||||
for (unsigned int i = 0; i < 16; i++)
|
||||
{
|
||||
R(i);
|
||||
}
|
||||
/*
|
||||
R( 0); R( 1); R( 2); R( 3);
|
||||
R( 4); R( 5); R( 6); R( 7);
|
||||
R( 8); R( 9); R(10); R(11);
|
||||
R(12); R(13); R(14); R(15);
|
||||
*/
|
||||
}
|
||||
/* Add the working vars back into context.state[] */
|
||||
/*
|
||||
state[0] += a(0);
|
||||
state[1] += b(0);
|
||||
state[2] += c(0);
|
||||
state[3] += d(0);
|
||||
state[4] += e(0);
|
||||
state[5] += f(0);
|
||||
state[6] += g(0);
|
||||
state[7] += h(0);
|
||||
*/
|
||||
for (int i = 0; i < 8; i++)
|
||||
state[i] += T[i];
|
||||
|
||||
/* Wipe variables */
|
||||
// memset(W, 0, sizeof(W));
|
||||
// memset(T, 0, sizeof(T));
|
||||
}
|
||||
|
||||
const UINT32 SHA256::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 SHA256::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(m_digest, data32);
|
||||
}
|
||||
|
||||
void SHA256::Update(const BYTE *data, UINT32 size)
|
||||
{
|
||||
UINT32 curBufferPos = UINT32(m_count) & 0x3F;
|
||||
while (size > 0)
|
||||
{
|
||||
while(curBufferPos < 64 && size > 0)
|
||||
{
|
||||
_buffer[curBufferPos++] = *data++;
|
||||
m_count++;
|
||||
size--;
|
||||
}
|
||||
if (curBufferPos == 64)
|
||||
{
|
||||
curBufferPos = 0;
|
||||
WriteByteBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHA256::Final(BYTE *digest)
|
||||
{
|
||||
UINT64 lenInBits = (m_count << 3);
|
||||
UINT32 curBufferPos = UINT32(m_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++ = m_digest[j] >> 24;
|
||||
*digest++ = m_digest[j] >> 16;
|
||||
*digest++ = m_digest[j] >> 8;
|
||||
*digest++ = m_digest[j];
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
}}
|
||||
30
7zip/Crypto/7zAES/SHA256.h
Executable file
30
7zip/Crypto/7zAES/SHA256.h
Executable file
@@ -0,0 +1,30 @@
|
||||
// Crypto/SHA/SHA256.h
|
||||
|
||||
#ifndef __CRYPTO_SHA256_H
|
||||
#define __CRYPTO_SHA256_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NSHA256 {
|
||||
|
||||
class SHA256
|
||||
{
|
||||
static const UINT32 K[64];
|
||||
|
||||
UINT32 m_digest[8];
|
||||
UINT64 m_count;
|
||||
BYTE _buffer[64];
|
||||
static void Transform(UINT32 *digest, const UINT32 *data);
|
||||
void WriteByteBlock();
|
||||
public:
|
||||
enum {DIGESTSIZE = 32};
|
||||
SHA256() { Init(); } ;
|
||||
void Init();
|
||||
void Update(const BYTE *data, UINT32 size);
|
||||
void Final(BYTE *digest);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
3
7zip/Crypto/7zAES/StdAfx.cpp
Executable file
3
7zip/Crypto/7zAES/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
8
7zip/Crypto/7zAES/StdAfx.h
Executable file
8
7zip/Crypto/7zAES/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
15
7zip/Crypto/7zAES/resource.h
Executable file
15
7zip/Crypto/7zAES/resource.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
121
7zip/Crypto/7zAES/resource.rc
Executable file
121
7zip/Crypto/7zAES/resource.rc
Executable file
@@ -0,0 +1,121 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7z-AES Crypto\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "InternalName", "7zAES\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "7zAES.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
8
7zip/Crypto/AES/AES.def
Executable file
8
7zip/Crypto/AES/AES.def
Executable file
@@ -0,0 +1,8 @@
|
||||
; AES.def
|
||||
|
||||
LIBRARY AES.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetNumberOfMethods PRIVATE
|
||||
GetMethodProperty PRIVATE
|
||||
223
7zip/Crypto/AES/AES.dsp
Executable file
223
7zip/Crypto/AES/AES.dsp
Executable file
@@ -0,0 +1,223 @@
|
||||
# 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=.\AES.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "7zip common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Crypto/AES/AES.dsw
Executable file
29
7zip/Crypto/AES/AES.dsw
Executable file
@@ -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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
48
7zip/Crypto/AES/AES_CBC.h
Executable file
48
7zip/Crypto/AES/AES_CBC.h
Executable file
@@ -0,0 +1,48 @@
|
||||
// AES_CBC.h
|
||||
|
||||
#ifndef __AES_CBC_H
|
||||
#define __AES_CBC_H
|
||||
|
||||
#include "aescpp.h"
|
||||
|
||||
class CAES_CBCEncoder: public AESclass
|
||||
{
|
||||
BYTE _prevBlock[16];
|
||||
public:
|
||||
void Init(const BYTE *iv)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
_prevBlock[i] = iv[i];
|
||||
}
|
||||
void ProcessData(BYTE *outBlock, const BYTE *inBlock)
|
||||
{
|
||||
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];
|
||||
}
|
||||
};
|
||||
|
||||
class CAES_CBCCBCDecoder: public AESclass
|
||||
{
|
||||
BYTE _prevBlock[16];
|
||||
public:
|
||||
void Init(const BYTE *iv)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
_prevBlock[i] = iv[i];
|
||||
}
|
||||
void ProcessData(BYTE *outBlock, const BYTE *inBlock)
|
||||
{
|
||||
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
|
||||
185
7zip/Crypto/AES/DllExports.cpp
Executable file
185
7zip/Crypto/AES/DllExports.cpp
Executable file
@@ -0,0 +1,185 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "MyAES.h"
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278B-0601-000000000100}
|
||||
DEFINE_GUID(CLSID_CCrypto_AES_Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0601-000000000000}
|
||||
DEFINE_GUID(CLSID_CCrypto_AES_Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
/*
|
||||
#include "Interface/ICoder.h"
|
||||
|
||||
#include "Alien/Crypto/CryptoPP/crc.h"
|
||||
#include "Alien/Crypto/CryptoPP/sha.h"
|
||||
#include "Alien/Crypto/CryptoPP/md2.h"
|
||||
#include "Alien/Crypto/CryptoPP/md5.h"
|
||||
#include "Alien/Crypto/CryptoPP/ripemd.h"
|
||||
#include "Alien/Crypto/CryptoPP/haval.h"
|
||||
// #include "Alien/Crypto/CryptoPP/tiger.h"
|
||||
|
||||
|
||||
using namespace CryptoPP;
|
||||
|
||||
#define CLSIDName(Name) CLSID_CCryptoHash ## Name
|
||||
#define ClassName(Name) aClass ## Name
|
||||
|
||||
// {23170F69-40C1-278B-17??-000000000000}
|
||||
#define MyClassID(Name, anID) DEFINE_GUID(CLSIDName(Name), \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x17, anID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
#define Pair(Name, anID) MyClassID(Name, anID)\
|
||||
typedef CHash<Name, &CLSIDName(Name)> ClassName(Name);
|
||||
|
||||
Pair(CRC32, 1)
|
||||
Pair(SHA1, 2)
|
||||
Pair(SHA256, 3)
|
||||
Pair(SHA384, 4)
|
||||
Pair(SHA512, 5)
|
||||
Pair(MD2, 6)
|
||||
Pair(MD5, 7)
|
||||
Pair(RIPEMD160, 8)
|
||||
Pair(HAVAL, 9)
|
||||
// Pair(Tiger, 18)
|
||||
|
||||
#define My_OBJECT_ENTRY(ID) OBJECT_ENTRY(CLSIDName(ID), ClassName(ID))
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
My_OBJECT_ENTRY(CRC32)
|
||||
My_OBJECT_ENTRY(SHA1)
|
||||
My_OBJECT_ENTRY(SHA256)
|
||||
My_OBJECT_ENTRY(SHA384)
|
||||
My_OBJECT_ENTRY(SHA512)
|
||||
My_OBJECT_ENTRY(MD2)
|
||||
My_OBJECT_ENTRY(MD5)
|
||||
My_OBJECT_ENTRY(RIPEMD160)
|
||||
My_OBJECT_ENTRY(HAVAL)
|
||||
// My_OBJECT_ENTRY(Tiger)
|
||||
END_OBJECT_MAP()
|
||||
*/
|
||||
|
||||
/*
|
||||
#define MyOBJECT_ENTRY(Name) \
|
||||
OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Encoder, C ## Name ## _Encoder) \
|
||||
OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Decoder, C ## Name ## _Decoder) \
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
MyOBJECT_ENTRY(_AES128_CBC)
|
||||
MyOBJECT_ENTRY(_AES256_CBC)
|
||||
END_OBJECT_MAP()
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Point
|
||||
|
||||
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; \
|
||||
coder = (ICompressCoder2 *)new C ## n ## _Encoder(); \
|
||||
} else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder2 *)new C ## n ## _Decoder(); \
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *clsid,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*interfaceID == IID_ICompressCoder2);
|
||||
CMyComPtr<ICompressCoder2> coder;
|
||||
|
||||
MY_CreateClass(AES128_CBC)
|
||||
else
|
||||
MY_CreateClass(AES256_CBC)
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.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(AES128_CBC, 0x01, L"AES128"),
|
||||
METHOD_ITEM(AES256_CBC, char(0x81), L"AES256")
|
||||
};
|
||||
|
||||
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;
|
||||
case NMethodPropID::kInStreams:
|
||||
{
|
||||
value->vt = VT_UI4;
|
||||
value->ulVal = 3;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
198
7zip/Crypto/AES/MyAES.cpp
Executable file
198
7zip/Crypto/AES/MyAES.cpp
Executable file
@@ -0,0 +1,198 @@
|
||||
// Crypto/Rar20/Encoder.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "MyAES.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "AES_CBC.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "aesopt.h"
|
||||
}
|
||||
class CTabInit
|
||||
{
|
||||
public:
|
||||
CTabInit()
|
||||
{
|
||||
gen_tabs();
|
||||
}
|
||||
} g_TabInit;
|
||||
|
||||
const int kBlockSize = 16;
|
||||
|
||||
static HRESULT Encode(
|
||||
CInBuffer &inBuffer,
|
||||
COutBuffer &outBuffer,
|
||||
ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
ICompressProgressInfo *progress,
|
||||
UINT32 keySize)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (numInStreams != 3 || numOutStreams != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
BYTE key[32];
|
||||
BYTE iv[kBlockSize];
|
||||
|
||||
/*
|
||||
int i;
|
||||
for (i = 0; i < kBlockSize; i++)
|
||||
iv[i] = 1;
|
||||
for (i = 0; i < keySize; i++)
|
||||
key[i] = 2;
|
||||
|
||||
RINOK(outStreams[1]->Write(iv, kBlockSize, NULL));
|
||||
RINOK(outStreams[2]->Write(key, keySize, NULL));
|
||||
*/
|
||||
UINT32 processedSize;
|
||||
RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize));
|
||||
if (processedSize != kBlockSize)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(inStreams[2]->Read(key, keySize, &processedSize));
|
||||
if (processedSize != keySize)
|
||||
return E_FAIL;
|
||||
|
||||
CAES_CBCEncoder encoder;
|
||||
encoder.enc_key(key, keySize);
|
||||
encoder.Init(iv);
|
||||
|
||||
inBuffer.Init(inStreams[0]);
|
||||
outBuffer.Init(outStreams[0]);
|
||||
|
||||
UINT64 nowPos = 0, posPrev = 0;
|
||||
while(true)
|
||||
{
|
||||
BYTE inBlock[kBlockSize], outBlock[kBlockSize];
|
||||
UINT32 numBytes;
|
||||
inBuffer.ReadBytes(inBlock, kBlockSize, numBytes);
|
||||
for (int i = numBytes; i < kBlockSize; i++)
|
||||
inBlock[i] = 0;
|
||||
encoder.ProcessData(outBlock, inBlock);
|
||||
outBuffer.WriteBytes(outBlock, kBlockSize);
|
||||
|
||||
nowPos += numBytes;
|
||||
if (progress != NULL && (nowPos - posPrev) > (1 << 18))
|
||||
{
|
||||
UINT64 outSize = nowPos - numBytes + kBlockSize;
|
||||
RINOK(progress->SetRatioInfo(&nowPos, &outSize));
|
||||
posPrev = nowPos;
|
||||
}
|
||||
if (numBytes < kBlockSize)
|
||||
break;
|
||||
}
|
||||
return outBuffer.Flush();
|
||||
// inBuffer.ReleaseStream();
|
||||
// outBuffer.ReleaseStream();
|
||||
// return S_OK;
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
static HRESULT Decode(
|
||||
CInBuffer &inBuffer,
|
||||
COutBuffer &outBuffer,
|
||||
ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
ICompressProgressInfo *progress,
|
||||
UINT32 keySize)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (numInStreams != 3 || numOutStreams != 1)
|
||||
return E_INVALIDARG;
|
||||
BYTE key[32];
|
||||
BYTE iv[kBlockSize];
|
||||
UINT32 processedSize;
|
||||
RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize));
|
||||
if (processedSize != kBlockSize)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(inStreams[2]->Read(key, keySize, &processedSize));
|
||||
if (processedSize != keySize)
|
||||
return E_FAIL;
|
||||
|
||||
CAES_CBCCBCDecoder decoder;
|
||||
decoder.dec_key(key, keySize);
|
||||
decoder.Init(iv);
|
||||
|
||||
inBuffer.Init(inStreams[0]);
|
||||
outBuffer.Init(outStreams[0]);
|
||||
|
||||
const UINT64 *outSize = outSizes[0];
|
||||
UINT64 nowPos = 0;
|
||||
UINT64 posPrev = 0;
|
||||
while(true)
|
||||
{
|
||||
BYTE inBlock[kBlockSize], outBlock[kBlockSize];
|
||||
UINT32 numBytes;
|
||||
inBuffer.ReadBytes(inBlock, kBlockSize, numBytes);
|
||||
if (numBytes == 0)
|
||||
break;
|
||||
decoder.ProcessData(outBlock, inBlock);
|
||||
UINT32 numBytesToWrite = kBlockSize;
|
||||
if (outSize != 0)
|
||||
numBytesToWrite = (UINT32)MyMin((*outSize - nowPos), UINT64(numBytesToWrite));
|
||||
outBuffer.WriteBytes(outBlock, numBytesToWrite);
|
||||
nowPos += numBytesToWrite;
|
||||
|
||||
if (progress != NULL && (nowPos - posPrev) > (1 << 18))
|
||||
{
|
||||
UINT64 inSize = inBuffer.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &nowPos));
|
||||
posPrev = nowPos;
|
||||
}
|
||||
|
||||
if (outSize != 0)
|
||||
if (nowPos >= *outSize)
|
||||
break;
|
||||
}
|
||||
return outBuffer.Flush();
|
||||
// inBuffer.ReleaseStream();
|
||||
// outBuffer.ReleaseStream();
|
||||
// return S_OK;
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
|
||||
#define MyClassCryptoImp(Name, keySize) \
|
||||
STDMETHODIMP C ## Name ## _Encoder::Code( \
|
||||
ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
|
||||
ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
|
||||
ICompressProgressInfo *progress) \
|
||||
{ \
|
||||
return Encode(_inByte, _outByte, inStreams, inSizes, numInStreams, \
|
||||
outStreams, outSizes, numOutStreams, progress, keySize); \
|
||||
} \
|
||||
STDMETHODIMP C ## Name ## _Decoder::Code( \
|
||||
ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
|
||||
ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
|
||||
ICompressProgressInfo *progress) \
|
||||
{ \
|
||||
return Decode(_inByte, _outByte, inStreams, inSizes, numInStreams, \
|
||||
outStreams, outSizes, numOutStreams, progress, keySize); \
|
||||
}
|
||||
|
||||
MyClassCryptoImp(AES128_CBC, 16)
|
||||
MyClassCryptoImp(AES256_CBC, 32)
|
||||
|
||||
47
7zip/Crypto/AES/MyAES.h
Executable file
47
7zip/Crypto/AES/MyAES.h
Executable file
@@ -0,0 +1,47 @@
|
||||
// Cipher/AES/MyAES.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CIPHER_MYAES_H
|
||||
#define __CIPHER_MYAES_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
|
||||
// #include "Alien/Crypto/CryptoPP/algparam.h"
|
||||
// #include "Alien/Crypto/CryptoPP/modes.h"
|
||||
// #include "Alien/Crypto/CryptoPP/aes.h"
|
||||
|
||||
#define MyClassCrypto3(Name) \
|
||||
class C ## Name: \
|
||||
public ICompressCoder2, \
|
||||
public CMyUnknownImp { \
|
||||
CInBuffer _inByte; \
|
||||
COutBuffer _outByte; \
|
||||
public: \
|
||||
MY_UNKNOWN_IMP \
|
||||
STDMETHOD(Code)( \
|
||||
ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
|
||||
ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
|
||||
ICompressProgressInfo *progress); \
|
||||
};
|
||||
|
||||
// {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); \
|
||||
MyClassCrypto3(Name) \
|
||||
|
||||
#define MyClassCrypto(Name, id) \
|
||||
MyClassCrypto2(Name ## _Encoder, id, 0x01) \
|
||||
MyClassCrypto2(Name ## _Decoder, id, 0x00)
|
||||
|
||||
MyClassCrypto(AES128_CBC, 0x01)
|
||||
MyClassCrypto(AES256_CBC, 0x81)
|
||||
|
||||
#endif
|
||||
3
7zip/Crypto/AES/StdAfx.cpp
Executable file
3
7zip/Crypto/AES/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
8
7zip/Crypto/AES/StdAfx.h
Executable file
8
7zip/Crypto/AES/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
103
7zip/Crypto/AES/aes.h
Executable file
103
7zip/Crypto/AES/aes.h
Executable file
@@ -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
|
||||
55
7zip/Crypto/AES/aescpp.h
Executable file
55
7zip/Crypto/AES/aescpp.h
Executable file
@@ -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
|
||||
421
7zip/Crypto/AES/aescrypt.c
Executable file
421
7zip/Crypto/AES/aescrypt.c
Executable file
@@ -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
|
||||
363
7zip/Crypto/AES/aeskey.c
Executable file
363
7zip/Crypto/AES/aeskey.c
Executable file
@@ -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
|
||||
839
7zip/Crypto/AES/aesopt.h
Executable file
839
7zip/Crypto/AES/aesopt.h
Executable file
@@ -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
|
||||
494
7zip/Crypto/AES/aestab.c
Executable file
494
7zip/Crypto/AES/aestab.c
Executable file
@@ -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
|
||||
15
7zip/Crypto/AES/resource.h
Executable file
15
7zip/Crypto/AES/resource.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
121
7zip/Crypto/AES/resource.rc
Executable file
121
7zip/Crypto/AES/resource.rc
Executable file
@@ -0,0 +1,121 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "AES Crypto\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "InternalName", "AES\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "AES.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
67
7zip/Crypto/Rar20/Rar20Cipher.cpp
Executable file
67
7zip/Crypto/Rar20/Rar20Cipher.cpp
Executable file
@@ -0,0 +1,67 @@
|
||||
// Crypto/Rar20Cipher.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Cipher.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
|
||||
static const int kBufferSize = 1 << 17;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_buffer(0)
|
||||
{
|
||||
_buffer = new BYTE[kBufferSize];
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
delete []_buffer;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
{
|
||||
_coder.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
UINT64 nowPos = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT32 processedSize;
|
||||
while(true)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
40
7zip/Crypto/Rar20/Rar20Cipher.h
Executable file
40
7zip/Crypto/Rar20/Rar20Cipher.h
Executable file
@@ -0,0 +1,40 @@
|
||||
// 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 ICompressCoder,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE *_buffer;
|
||||
public:
|
||||
CData _coder;
|
||||
|
||||
CDecoder();
|
||||
~CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
144
7zip/Crypto/Rar20/Rar20Crypto.cpp
Executable file
144
7zip/Crypto/Rar20/Rar20Crypto.cpp
Executable file
@@ -0,0 +1,144 @@
|
||||
// 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 *Ch1, BYTE *Ch2)
|
||||
{
|
||||
BYTE Ch = *Ch1;
|
||||
*Ch1 = *Ch2;
|
||||
*Ch2 = Ch;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
void CData::EncryptBlock(BYTE *Buf)
|
||||
{
|
||||
UINT32 A, B, C, D, T, TA, TB;
|
||||
|
||||
UINT32 *BufPtr;
|
||||
BufPtr = (UINT32 *)Buf;
|
||||
|
||||
A = BufPtr[0] ^ Keys[0];
|
||||
B = BufPtr[1] ^ Keys[1];
|
||||
C = BufPtr[2] ^ Keys[2];
|
||||
D = BufPtr[3] ^ Keys[3];
|
||||
|
||||
for(int i = 0; i < kNumRounds; i++)
|
||||
{
|
||||
T = ((C + rol(D, 11)) ^ Keys[i & 3]);
|
||||
TA = A ^ SubstLong(T);
|
||||
T=((D ^ rol(C, 17)) + Keys[i & 3]);
|
||||
TB = B ^ SubstLong(T);
|
||||
A = C;
|
||||
B = D;
|
||||
C = TA;
|
||||
D = TB;
|
||||
}
|
||||
|
||||
BufPtr[0] = C ^ Keys[0];
|
||||
BufPtr[1] = D ^ Keys[1];
|
||||
BufPtr[2] = A ^ Keys[2];
|
||||
BufPtr[3] = B ^ Keys[3];
|
||||
|
||||
UpdateKeys(Buf);
|
||||
}
|
||||
|
||||
void CData::DecryptBlock(BYTE *Buf)
|
||||
{
|
||||
BYTE InBuf[16];
|
||||
UINT32 A, B, C, D, T, TA, TB;
|
||||
|
||||
UINT32 *BufPtr;
|
||||
BufPtr = (UINT32 *)Buf;
|
||||
|
||||
A = BufPtr[0] ^ Keys[0];
|
||||
B = BufPtr[1] ^ Keys[1];
|
||||
C = BufPtr[2] ^ Keys[2];
|
||||
D = BufPtr[3] ^ Keys[3];
|
||||
|
||||
memcpy(InBuf, Buf, sizeof(InBuf));
|
||||
|
||||
for(int i = kNumRounds - 1; i >= 0; i--)
|
||||
{
|
||||
T = ((C + rol(D, 11)) ^ Keys[i & 3]);
|
||||
TA = A ^ SubstLong(T);
|
||||
T = ((D ^ rol(C, 17)) + Keys[i & 3]);
|
||||
TB = B ^ SubstLong(T);
|
||||
A = C;
|
||||
B = D;
|
||||
C = TA;
|
||||
D = TB;
|
||||
}
|
||||
|
||||
BufPtr[0] = C ^ Keys[0];
|
||||
BufPtr[1] = D ^ Keys[1];
|
||||
BufPtr[2] = A ^ Keys[2];
|
||||
BufPtr[3] = B ^ Keys[3];
|
||||
|
||||
UpdateKeys(InBuf);
|
||||
}
|
||||
|
||||
}}
|
||||
32
7zip/Crypto/Rar20/Rar20Crypto.h
Executable file
32
7zip/Crypto/Rar20/Rar20Crypto.h
Executable file
@@ -0,0 +1,32 @@
|
||||
// Crypto/Rar20/Crypto.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CRYPTO_RAR20_CRYPTO_H
|
||||
#define __CRYPTO_RAR20_CRYPTO_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);
|
||||
public:
|
||||
void EncryptBlock(BYTE *Buf);
|
||||
void DecryptBlock(BYTE *Buf);
|
||||
void SetPassword(const BYTE *password, UINT32 passwordLength);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
157
7zip/Crypto/RarAES/RarAES.cpp
Executable file
157
7zip/Crypto/RarAES/RarAES.cpp
Executable file
@@ -0,0 +1,157 @@
|
||||
// Crypto/RarAES/RarAES.h
|
||||
// This code is based on UnRar sources
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Archive/Common/CoderLoader.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "RarAES.h"
|
||||
#include "sha1.h"
|
||||
|
||||
extern void GetCryptoFolderPrefix(TCHAR *path);
|
||||
|
||||
// {23170F69-40C1-278B-0601-010000000000}
|
||||
DEFINE_GUID(CLSID_CCrypto_AES128_Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar29 {
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_thereIsSalt(false),
|
||||
_needCalculate(true)
|
||||
{
|
||||
for (int i = 0; i < sizeof(_salt); i++)
|
||||
_salt[i] = 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
{
|
||||
bool thereIsSaltPrev = _thereIsSalt;
|
||||
_thereIsSalt = false;
|
||||
UINT32 processedSize;
|
||||
BYTE salt[8];
|
||||
RINOK(inStream->Read(salt, sizeof(salt), &processedSize));
|
||||
if (processedSize == 0)
|
||||
_thereIsSalt = false;
|
||||
if (processedSize != sizeof(salt))
|
||||
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] != salt[i])
|
||||
{
|
||||
same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < sizeof(_salt); i++)
|
||||
_salt[i] = salt[i];
|
||||
if (!_needCalculate && !same)
|
||||
_needCalculate = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
{
|
||||
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::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
{
|
||||
if (_needCalculate)
|
||||
{
|
||||
const MAXPASSWORD = 128;
|
||||
const SALT_SIZE = 8;
|
||||
|
||||
BYTE rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
|
||||
|
||||
memcpy(rawPassword, buffer, buffer.GetCapacity());
|
||||
|
||||
int rawLength = buffer.GetCapacity();
|
||||
|
||||
if (_thereIsSalt)
|
||||
{
|
||||
memcpy(rawPassword + rawLength, _salt, SALT_SIZE);
|
||||
rawLength += SALT_SIZE;
|
||||
}
|
||||
|
||||
hash_context c;
|
||||
hash_initial(&c);
|
||||
|
||||
const int hashRounds = 0x40000;
|
||||
int i;
|
||||
for (i = 0; i < hashRounds; i++)
|
||||
{
|
||||
hash_process(&c, rawPassword, rawLength);
|
||||
BYTE pswNum[3];
|
||||
pswNum[0] = (BYTE)i;
|
||||
pswNum[1] = (BYTE)(i >> 8);
|
||||
pswNum[2] = (BYTE)(i >> 16);
|
||||
hash_process(&c, pswNum, 3);
|
||||
if (i % (hashRounds / 16) == 0)
|
||||
{
|
||||
hash_context tempc = c;
|
||||
UINT32 digest[5];
|
||||
hash_final(&tempc, digest);
|
||||
aesInit[i / (hashRounds / 16)] = (BYTE)digest[4];
|
||||
}
|
||||
}
|
||||
UINT32 digest[5];
|
||||
hash_final(&c, digest);
|
||||
for (i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
aesKey[i * 4 + j] = (BYTE)(digest[i] >> (j * 8));
|
||||
}
|
||||
_needCalculate = false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}}
|
||||
48
7zip/Crypto/RarAES/RarAES.h
Executable file
48
7zip/Crypto/RarAES/RarAES.h
Executable file
@@ -0,0 +1,48 @@
|
||||
// Crypto/CRarAES/RarAES.h
|
||||
|
||||
#ifndef __CRYPTO_RARAES_H
|
||||
#define __CRYPTO_RARAES_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar29 {
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE _salt[8];
|
||||
bool _thereIsSalt;
|
||||
CByteBuffer buffer;
|
||||
BYTE aesKey[16];
|
||||
BYTE aesInit[16];
|
||||
bool _needCalculate;
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICompressSetDecoderProperties)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
|
||||
CDecoder();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
214
7zip/Crypto/RarAES/sha1.cpp
Executable file
214
7zip/Crypto/RarAES/sha1.cpp
Executable file
@@ -0,0 +1,214 @@
|
||||
// sha1.cpp
|
||||
// This file from UnRar sources
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
/*
|
||||
SHA-1 in C
|
||||
By Steve Reid <steve@edmweb.com>
|
||||
100% Public Domain
|
||||
|
||||
Test Vectors (from FIPS PUB 180-1)
|
||||
"abc"
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
A million repetitions of "a"
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||
#if defined(_M_IX86) || defined(_M_I86) || defined(__alpha)
|
||||
#define LITTLE_ENDIAN
|
||||
#else
|
||||
#error "LITTLE_ENDIAN or BIG_ENDIAN must be defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
/* blk0() and blk() perform the initial expand. */
|
||||
/* I got the idea of expanding during the round function from SSLeay */
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|
||||
|(rol(block->l[i],8)&0x00FF00FF))
|
||||
#else
|
||||
#define blk0(i) block->l[i]
|
||||
#endif
|
||||
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);}
|
||||
#define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);}
|
||||
#define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);}
|
||||
#define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);}
|
||||
#define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);}
|
||||
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
|
||||
void SHA1Transform(UINT32 state[5], unsigned char buffer[64])
|
||||
{
|
||||
UINT32 a, b, c, d, e;
|
||||
typedef union {
|
||||
unsigned char c[64];
|
||||
UINT32 l[16];
|
||||
} CHAR64LONG16;
|
||||
CHAR64LONG16* block;
|
||||
#ifdef SHA1HANDSOFF
|
||||
static unsigned char workspace[64];
|
||||
block = (CHAR64LONG16*)workspace;
|
||||
memcpy(block, buffer, 64);
|
||||
#else
|
||||
block = (CHAR64LONG16*)buffer;
|
||||
#endif
|
||||
#ifdef SFX_MODULE
|
||||
static int pos[80][5];
|
||||
static bool pinit=false;
|
||||
if (!pinit)
|
||||
{
|
||||
for (int I=0,P=0;I<80;I++,P=(P ? P-1:4))
|
||||
{
|
||||
pos[I][0]=P;
|
||||
pos[I][1]=(P+1)%5;
|
||||
pos[I][2]=(P+2)%5;
|
||||
pos[I][3]=(P+3)%5;
|
||||
pos[I][4]=(P+4)%5;
|
||||
}
|
||||
pinit=true;
|
||||
}
|
||||
UINT32 s[5];
|
||||
for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
|
||||
s[I]=state[I];
|
||||
|
||||
for (int I=0;I<16;I++)
|
||||
R0(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||
for (int I=16;I<20;I++)
|
||||
R1(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||
for (int I=20;I<40;I++)
|
||||
R2(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||
for (int I=40;I<60;I++)
|
||||
R3(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||
for (int I=60;I<80;I++)
|
||||
R4(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||
|
||||
for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
|
||||
state[I]+=s[I];
|
||||
#else
|
||||
/* Copy context->state[] to working vars */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
memset(&a,0,sizeof(a));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Initialize new context */
|
||||
|
||||
void hash_initial(hash_context* context)
|
||||
{
|
||||
/* SHA1 initialization constants */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xC3D2E1F0;
|
||||
context->count[0] = context->count[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Run your data through this. */
|
||||
void hash_process( hash_context * context, unsigned char * data, unsigned len )
|
||||
{
|
||||
unsigned int i, j;
|
||||
UINT32 blen = ((UINT32)len)<<3;
|
||||
|
||||
j = (context->count[0] >> 3) & 63;
|
||||
if ((context->count[0] += blen) < blen ) context->count[1]++;
|
||||
context->count[1] += (len >> 29);
|
||||
if ((j + len) > 63) {
|
||||
memcpy(&context->buffer[j], data, (i = 64-j));
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
for ( ; i + 63 < len; i += 64) {
|
||||
SHA1Transform(context->state, &data[i]);
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
else i = 0;
|
||||
if (len > i)
|
||||
memcpy(&context->buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
|
||||
void hash_final( hash_context* context, UINT32 digest[5] )
|
||||
{
|
||||
UINT32 i, j;
|
||||
unsigned char finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
||||
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||
}
|
||||
unsigned char ch='\200';
|
||||
hash_process(context, &ch, 1);
|
||||
while ((context->count[0] & 504) != 448) {
|
||||
ch=0;
|
||||
hash_process(context, &ch, 1);
|
||||
}
|
||||
hash_process(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
for (i = 0; i < 5; i++) {
|
||||
digest[i] = context->state[i] & 0xffffffff;
|
||||
}
|
||||
/* Wipe variables */
|
||||
memset(&i,0,sizeof(i));
|
||||
memset(&j,0,sizeof(j));
|
||||
memset(context->buffer, 0, 64);
|
||||
memset(context->state, 0, 20);
|
||||
memset(context->count, 0, 8);
|
||||
memset(&finalcount, 0, 8);
|
||||
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
19
7zip/Crypto/RarAES/sha1.h
Executable file
19
7zip/Crypto/RarAES/sha1.h
Executable file
@@ -0,0 +1,19 @@
|
||||
// sha1.h
|
||||
// This file from UnRar sources
|
||||
|
||||
#ifndef _RAR_SHA1_
|
||||
#define _RAR_SHA1_
|
||||
|
||||
#define HW 5
|
||||
|
||||
typedef struct {
|
||||
UINT32 state[5];
|
||||
UINT32 count[2];
|
||||
unsigned char buffer[64];
|
||||
} hash_context;
|
||||
|
||||
void hash_initial( hash_context * c );
|
||||
void hash_process( hash_context * c, unsigned char * data, unsigned len );
|
||||
void hash_final( hash_context * c, UINT32[HW] );
|
||||
|
||||
#endif
|
||||
8
7zip/Crypto/Zip/StdAfx.h
Executable file
8
7zip/Crypto/Zip/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
118
7zip/Crypto/Zip/ZipCipher.cpp
Executable file
118
7zip/Crypto/Zip/ZipCipher.cpp
Executable file
@@ -0,0 +1,118 @@
|
||||
// Crypto/ZipCipher.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipCipher.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
const int kBufferSize = 1 << 17;
|
||||
|
||||
CBuffer2::CBuffer2():
|
||||
_buffer(0)
|
||||
{
|
||||
_buffer = new BYTE[kBufferSize];
|
||||
}
|
||||
|
||||
CBuffer2::~CBuffer2()
|
||||
{
|
||||
delete []_buffer;
|
||||
}
|
||||
|
||||
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::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
CRandom random;
|
||||
random.Init(::GetTickCount());
|
||||
|
||||
UINT64 nowPos = 0;
|
||||
BYTE header[kHeaderSize];
|
||||
for (int i = 0; i < kHeaderSize - 2; i++)
|
||||
{
|
||||
header[i] = BYTE(random.Generate());
|
||||
}
|
||||
header[kHeaderSize - 1] = BYTE(_crc >> 24);
|
||||
header[kHeaderSize - 2] = BYTE(_crc >> 16);
|
||||
|
||||
UINT32 processedSize;
|
||||
_cipher.EncryptHeader(header);
|
||||
RINOK(outStream->Write(header, kHeaderSize, &processedSize));
|
||||
if (processedSize != kHeaderSize)
|
||||
return E_FAIL;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if (outSize != NULL && nowPos == *outSize)
|
||||
return S_OK;
|
||||
RINOK(inStream->Read(_buffer, kBufferSize, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return S_OK;
|
||||
for (UINT32 i = 0; i < processedSize; i++)
|
||||
_buffer[i] = _cipher.EncryptByte(_buffer[i]);
|
||||
UINT32 size = processedSize;
|
||||
if (outSize != NULL && nowPos + size > *outSize)
|
||||
size = UINT32(*outSize - nowPos);
|
||||
RINOK(outStream->Write(_buffer, size, &processedSize));
|
||||
if (size != processedSize)
|
||||
return E_FAIL;
|
||||
nowPos += processedSize;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
{
|
||||
_cipher.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
UINT64 nowPos = 0;
|
||||
|
||||
if (inSize != NULL && *inSize == 0)
|
||||
return S_OK;
|
||||
|
||||
BYTE header[kHeaderSize];
|
||||
UINT32 processedSize;
|
||||
RINOK(inStream->Read(header, kHeaderSize, &processedSize));
|
||||
if (processedSize != kHeaderSize)
|
||||
return E_FAIL;
|
||||
_cipher.DecryptHeader(header);
|
||||
|
||||
while(true)
|
||||
{
|
||||
if (outSize != NULL && nowPos == *outSize)
|
||||
return S_OK;
|
||||
RINOK(inStream->Read(_buffer, kBufferSize, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return S_OK;
|
||||
for (UINT32 i = 0; i < processedSize; i++)
|
||||
_buffer[i] = _cipher.DecryptByte(_buffer[i]);
|
||||
UINT32 size = processedSize;
|
||||
if (outSize != NULL && nowPos + size > *outSize)
|
||||
size = UINT32(*outSize - nowPos);
|
||||
RINOK(outStream->Write(_buffer, size, &processedSize));
|
||||
if (size != processedSize)
|
||||
return E_FAIL;
|
||||
nowPos += processedSize;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
72
7zip/Crypto/Zip/ZipCipher.h
Executable file
72
7zip/Crypto/Zip/ZipCipher.h
Executable file
@@ -0,0 +1,72 @@
|
||||
// Crypto/ZipCipher.h
|
||||
|
||||
#ifndef __CRYPTO_ZIPCIPHER_H
|
||||
#define __CRYPTO_ZIPCIPHER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Random.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "ZipCrypto.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
class CBuffer2
|
||||
{
|
||||
protected:
|
||||
BYTE *_buffer;
|
||||
public:
|
||||
CBuffer2();
|
||||
~CBuffer2();
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICryptoSetPassword,
|
||||
public ICryptoSetCRC,
|
||||
public CMyUnknownImp,
|
||||
public CBuffer2
|
||||
{
|
||||
CCipher _cipher;
|
||||
UINT32 _crc;
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICryptoSetCRC
|
||||
)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
|
||||
STDMETHOD(CryptoSetCRC)(UINT32 crc);
|
||||
};
|
||||
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp,
|
||||
public CBuffer2
|
||||
{
|
||||
CCipher _cipher;
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
65
7zip/Crypto/Zip/ZipCrypto.cpp
Executable file
65
7zip/Crypto/Zip/ZipCrypto.cpp
Executable file
@@ -0,0 +1,65 @@
|
||||
// Crypto/ZipCrypto.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipCipher.h"
|
||||
#include "Common/Crc.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
inline UINT32 CRC32(UINT32 c, BYTE b)
|
||||
{
|
||||
return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8);
|
||||
}
|
||||
|
||||
void CCipher::UpdateKeys(BYTE b)
|
||||
{
|
||||
Keys[0] = CRC32(Keys[0], b);
|
||||
Keys[1] += Keys[0] & 0xff;
|
||||
Keys[1] = Keys[1] * 134775813L + 1;
|
||||
Keys[2] = CRC32(Keys[2], 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 (temp * (temp ^ 1)) >> 8;
|
||||
}
|
||||
|
||||
BYTE CCipher::DecryptByte(BYTE encryptedByte)
|
||||
{
|
||||
BYTE c = encryptedByte ^ DecryptByteSpec();
|
||||
UpdateKeys(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
BYTE CCipher::EncryptByte(BYTE b)
|
||||
{
|
||||
BYTE c = 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]);
|
||||
}
|
||||
|
||||
}}
|
||||
28
7zip/Crypto/Zip/ZipCrypto.h
Executable file
28
7zip/Crypto/Zip/ZipCrypto.h
Executable file
@@ -0,0 +1,28 @@
|
||||
// Crypto/ZipCrypto.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user