mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 10:11:38 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -1,4 +1,4 @@
|
||||
// 7z_AES.h
|
||||
// 7z_AES.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -28,7 +28,7 @@ bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const
|
||||
{
|
||||
if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)
|
||||
return false;
|
||||
for (UINT32 i = 0; i < SaltSize; i++)
|
||||
for (UInt32 i = 0; i < SaltSize; i++)
|
||||
if (Salt[i] != a.Salt[i])
|
||||
return false;
|
||||
return (Password == a.Password);
|
||||
@@ -38,40 +38,28 @@ void CKeyInfo::CalculateDigest()
|
||||
{
|
||||
if (NumCyclesPower == 0x3F)
|
||||
{
|
||||
UINT32 pos;
|
||||
UInt32 pos;
|
||||
for (pos = 0; pos < SaltSize; pos++)
|
||||
Key[pos] = Salt[pos];
|
||||
for (UINT32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++)
|
||||
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++)
|
||||
const UInt64 numRounds = UInt64(1) << (NumCyclesPower);
|
||||
Byte temp[8] = { 0,0,0,0,0,0,0,0 };
|
||||
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));
|
||||
sha.Update(temp, 8);
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (++(temp[i]) != 0)
|
||||
break;
|
||||
}
|
||||
// return sha->GetDigest(Key);
|
||||
sha.Final(Key);
|
||||
}
|
||||
}
|
||||
@@ -133,30 +121,30 @@ void CBase::CalculateDigest()
|
||||
|
||||
|
||||
/*
|
||||
static void GetRandomData(BYTE *data)
|
||||
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;
|
||||
UInt64 tempValue;
|
||||
SYSTEMTIME systemTime;
|
||||
FILETIME fileTime;
|
||||
::GetSystemTime(&systemTime);
|
||||
::SystemTimeToFileTime(&systemTime, &fileTime);
|
||||
tempValue = *(const UINT64 *)&fileTime;
|
||||
tempValue = *(const UInt64 *)&fileTime;
|
||||
LARGE_INTEGER counter;
|
||||
::QueryPerformanceCounter(&counter);
|
||||
tempValue += *(const UINT64 *)&counter;
|
||||
tempValue += (UINT64)(GetTickCount()) << 32;
|
||||
*(UINT64 *)data = tempValue;
|
||||
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++)
|
||||
for (UInt32 i = 0; i < sizeof(_iv); i++)
|
||||
_iv[i] = 0;
|
||||
|
||||
_key.SaltSize = 0;
|
||||
@@ -169,16 +157,16 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
// _key.NumCyclesPower = 0x3F;
|
||||
_key.NumCyclesPower = 18;
|
||||
|
||||
BYTE firstByte = _key.NumCyclesPower |
|
||||
Byte firstByte = _key.NumCyclesPower |
|
||||
(((_key.SaltSize == 0) ? 0 : 1) << 7) |
|
||||
(((ivSize == 0) ? 0 : 1) << 6);
|
||||
RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL));
|
||||
RINOK(outStream->Write(&firstByte, 1, 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));
|
||||
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, 1, NULL));
|
||||
if (_key.SaltSize > 0)
|
||||
{
|
||||
RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL));
|
||||
@@ -190,56 +178,40 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
_key.Init();
|
||||
for (int i = 0; i < sizeof(_iv); i++)
|
||||
UInt32 i;
|
||||
for (i = 0; i < sizeof(_iv); i++)
|
||||
_iv[i] = 0;
|
||||
UINT32 processedSize;
|
||||
BYTE firstByte;
|
||||
RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processedSize));
|
||||
if (processedSize == 0)
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
UInt32 pos = 0;
|
||||
Byte firstByte = data[pos++];
|
||||
|
||||
_key.NumCyclesPower = firstByte & 0x3F;
|
||||
if ((firstByte & 0xC0) == 0)
|
||||
return S_OK;
|
||||
_key.SaltSize = (firstByte >> 7) & 1;
|
||||
UINT32 ivSize = (firstByte >> 6) & 1;
|
||||
UInt32 ivSize = (firstByte >> 6) & 1;
|
||||
|
||||
BYTE secondByte;
|
||||
RINOK(inStream->Read(&secondByte, sizeof(secondByte), &processedSize));
|
||||
if (processedSize == 0)
|
||||
if (pos >= size)
|
||||
return E_INVALIDARG;
|
||||
Byte secondByte = data[pos++];
|
||||
|
||||
_key.SaltSize += (secondByte >> 4);
|
||||
ivSize += (secondByte & 0x0F);
|
||||
|
||||
RINOK(inStream->Read(_key.Salt,
|
||||
_key.SaltSize, &processedSize));
|
||||
if (processedSize != _key.SaltSize)
|
||||
if (pos + _key.SaltSize + ivSize > size)
|
||||
return E_INVALIDARG;
|
||||
|
||||
RINOK(inStream->Read(_iv, ivSize, &processedSize));
|
||||
if (processedSize != ivSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
for (i = 0; i < _key.SaltSize; i++)
|
||||
_key.Salt[i] = data[pos++];
|
||||
for (i = 0; i < ivSize; i++)
|
||||
_iv[i] = data[pos++];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP 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)
|
||||
STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_key.Password.SetCapacity(size);
|
||||
memcpy(_key.Password, data, size);
|
||||
@@ -247,12 +219,12 @@ STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
}
|
||||
|
||||
/*
|
||||
static BYTE *WideToRaw(const wchar_t *src, BYTE *dest, int destSize=0x10000000)
|
||||
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);
|
||||
dest[i * 2] = (Byte)*src;
|
||||
dest[i * 2 + 1]= (Byte)(*src >> 8);
|
||||
if (*src == 0)
|
||||
break;
|
||||
}
|
||||
@@ -276,80 +248,57 @@ bool GetAESLibPath(TCHAR *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
STDMETHODIMP CBaseCoder::Init()
|
||||
{
|
||||
CalculateDigest();
|
||||
|
||||
if (_aesEncoder == 0)
|
||||
if (_aesFilter == 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
|
||||
RINOK(CreateFilter());
|
||||
}
|
||||
|
||||
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);
|
||||
CMyComPtr<ICryptoProperties> cp;
|
||||
RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
|
||||
RINOK(cp->SetKey(_key.Key, sizeof(_key.Key)));
|
||||
RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
CalculateDigest();
|
||||
return _aesFilter->Filter(data, size);
|
||||
}
|
||||
|
||||
if (_aesDecoder == 0)
|
||||
#ifndef CRYPTO_AES
|
||||
HRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID)
|
||||
{
|
||||
if (!_aesLibrary)
|
||||
{
|
||||
#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
|
||||
TCHAR filePath[MAX_PATH + 2];
|
||||
if (!GetAESLibPath(filePath))
|
||||
return ::GetLastError();
|
||||
return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
|
||||
ivStreamSpec->Init(_iv, sizeof(_iv));
|
||||
HRESULT CEncoder::CreateFilter()
|
||||
{
|
||||
#ifdef CRYPTO_AES
|
||||
_aesFilter = new CAES256_CBC_Encoder;
|
||||
return S_OK;
|
||||
#else
|
||||
return CreateFilterFromDLL(CLSID_CCrypto_AES256_Encoder);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
HRESULT CDecoder::CreateFilter()
|
||||
{
|
||||
#ifdef CRYPTO_AES
|
||||
_aesFilter = new CAES256_CBC_Decoder;
|
||||
return S_OK;
|
||||
#else
|
||||
return CreateFilterFromDLL(CLSID_CCrypto_AES256_Decoder);
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -122,6 +122,14 @@ SOURCE=.\StdAfx.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -148,6 +156,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
@@ -169,6 +185,14 @@ SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\CoderLoader.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zAES.cpp
|
||||
|
||||
@@ -32,18 +32,15 @@ class CKeyInfo
|
||||
{
|
||||
public:
|
||||
int NumCyclesPower;
|
||||
UINT32 SaltSize;
|
||||
BYTE Salt[16];
|
||||
UInt32 SaltSize;
|
||||
Byte Salt[16];
|
||||
CByteBuffer Password;
|
||||
BYTE Key[kKeySize];
|
||||
Byte Key[kKeySize];
|
||||
|
||||
bool IsEqualTo(const CKeyInfo &a) const;
|
||||
void CalculateDigest();
|
||||
|
||||
CKeyInfo()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
CKeyInfo() { Init(); }
|
||||
void Init()
|
||||
{
|
||||
NumCyclesPower = 0;
|
||||
@@ -69,69 +66,57 @@ class CBase
|
||||
CKeyInfoCache _cachedKeys;
|
||||
protected:
|
||||
CKeyInfo _key;
|
||||
BYTE _iv[16];
|
||||
Byte _iv[16];
|
||||
// int _ivSize;
|
||||
void CalculateDigest();
|
||||
CBase();
|
||||
};
|
||||
|
||||
class CEncoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
class CBaseCoder:
|
||||
public ICompressFilter,
|
||||
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);
|
||||
|
||||
protected:
|
||||
#ifndef CRYPTO_AES
|
||||
CCoderLibrary _aesEncoderLibrary;
|
||||
CCoderLibrary _aesLibrary;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder2> _aesEncoder;
|
||||
CMyComPtr<ICompressFilter> _aesFilter;
|
||||
|
||||
virtual HRESULT CreateFilter() = 0;
|
||||
#ifndef CRYPTO_AES
|
||||
HRESULT CreateFilterFromDLL(REFCLSID clsID);
|
||||
#endif
|
||||
public:
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
class CEncoder:
|
||||
public CBaseCoder,
|
||||
public ICompressWriteCoderProperties
|
||||
{
|
||||
virtual HRESULT CreateFilter();
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICompressWriteCoderProperties)
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
};
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp,
|
||||
public CBase
|
||||
public CBaseCoder,
|
||||
public ICompressSetDecoderProperties2
|
||||
{
|
||||
virtual HRESULT CreateFilter();
|
||||
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);
|
||||
|
||||
#ifndef CRYPTO_AES
|
||||
CCoderLibrary _aesDecoderLibrary;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder2> _aesDecoder;
|
||||
ICompressSetDecoderProperties2)
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "7zAES.h"
|
||||
|
||||
@@ -35,23 +34,23 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
int correctInterface = (*iid == IID_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
if (*clsid == CLSID_CCrypto7zAESDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCrypto::NSevenZ::CDecoder();
|
||||
filter = (ICompressFilter *)new NCrypto::NSevenZ::CDecoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCrypto7zAESEncoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCrypto::NSevenZ::CEncoder();
|
||||
filter = (ICompressFilter *)new NCrypto::NSevenZ::CEncoder();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
*outObject = filter.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Crypto/HASH/SHA256/SHA256.cpp
|
||||
// Crypto/SHA256.cpp
|
||||
// This code is based on code from Wei Dai's Crypto++ library.
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -58,10 +58,10 @@ void SHA256::Init()
|
||||
#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)
|
||||
void SHA256::Transform(UInt32 *state, const UInt32 *data)
|
||||
{
|
||||
UINT32 W[16];
|
||||
UINT32 T[8];
|
||||
UInt32 W[16];
|
||||
UInt32 T[8];
|
||||
/* Copy context->state[] to working vars */
|
||||
// memcpy(T, state, sizeof(T));
|
||||
for (int s = 0; s < 8; s++)
|
||||
@@ -101,7 +101,7 @@ void SHA256::Transform(UINT32 *state, const UINT32 *data)
|
||||
// memset(T, 0, sizeof(T));
|
||||
}
|
||||
|
||||
const UINT32 SHA256::K[64] = {
|
||||
const UInt32 SHA256::K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
@@ -127,20 +127,20 @@ const UINT32 SHA256::K[64] = {
|
||||
|
||||
void SHA256::WriteByteBlock()
|
||||
{
|
||||
UINT32 data32[16];
|
||||
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]);
|
||||
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)
|
||||
void SHA256::Update(const Byte *data, UInt32 size)
|
||||
{
|
||||
UINT32 curBufferPos = UINT32(m_count) & 0x3F;
|
||||
UInt32 curBufferPos = UInt32(m_count) & 0x3F;
|
||||
while (size > 0)
|
||||
{
|
||||
while(curBufferPos < 64 && size > 0)
|
||||
@@ -157,10 +157,10 @@ void SHA256::Update(const BYTE *data, UINT32 size)
|
||||
}
|
||||
}
|
||||
|
||||
void SHA256::Final(BYTE *digest)
|
||||
void SHA256::Final(Byte *digest)
|
||||
{
|
||||
UINT64 lenInBits = (m_count << 3);
|
||||
UINT32 curBufferPos = UINT32(m_count) & 0x3F;
|
||||
UInt64 lenInBits = (m_count << 3);
|
||||
UInt32 curBufferPos = UInt32(m_count) & 0x3F;
|
||||
_buffer[curBufferPos++] = 0x80;
|
||||
while (curBufferPos != (64 - 8))
|
||||
{
|
||||
@@ -171,7 +171,7 @@ void SHA256::Final(BYTE *digest)
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
_buffer[curBufferPos++] = BYTE(lenInBits >> 56);
|
||||
_buffer[curBufferPos++] = Byte(lenInBits >> 56);
|
||||
lenInBits <<= 8;
|
||||
}
|
||||
WriteByteBlock();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Crypto/SHA/SHA256.h
|
||||
// Crypto/SHA256.h
|
||||
|
||||
#ifndef __CRYPTO_SHA256_H
|
||||
#define __CRYPTO_SHA256_H
|
||||
@@ -10,19 +10,19 @@ namespace NSHA256 {
|
||||
|
||||
class SHA256
|
||||
{
|
||||
static const UINT32 K[64];
|
||||
static const UInt32 K[64];
|
||||
|
||||
UINT32 m_digest[8];
|
||||
UINT64 m_count;
|
||||
BYTE _buffer[64];
|
||||
static void Transform(UINT32 *digest, const UINT32 *data);
|
||||
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);
|
||||
void Update(const Byte *data, UInt32 size);
|
||||
void Final(Byte *digest);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -84,15 +84,15 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7z-AES Crypto\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileDescription", "7z-AES Crypto Codec\0"
|
||||
VALUE "FileVersion", "4, 16, 0, 0\0"
|
||||
VALUE "InternalName", "7zAES\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 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 "ProductVersion", "4, 16, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -101,6 +101,10 @@ SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"StdAfx.h"
|
||||
# End Source File
|
||||
@@ -109,26 +113,6 @@ SOURCE=.\StdAfx.cpp
|
||||
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 ""
|
||||
@@ -215,9 +199,5 @@ SOURCE=.\MyAES.cpp
|
||||
|
||||
SOURCE=.\MyAES.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
|
||||
#include "aescpp.h"
|
||||
|
||||
class CAES_CBCEncoder: public AESclass
|
||||
class CAES_CBC: public AESclass
|
||||
{
|
||||
BYTE _prevBlock[16];
|
||||
protected:
|
||||
Byte _prevBlock[16];
|
||||
public:
|
||||
void Init(const BYTE *iv)
|
||||
void Init(const Byte *iv)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
_prevBlock[i] = iv[i];
|
||||
}
|
||||
void ProcessData(BYTE *outBlock, const BYTE *inBlock)
|
||||
void Encode(const Byte *inBlock, Byte *outBlock)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
@@ -23,18 +24,8 @@ public:
|
||||
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)
|
||||
void Decode(const Byte *inBlock, Byte *outBlock)
|
||||
{
|
||||
dec_blk(inBlock, outBlock);
|
||||
int i;
|
||||
|
||||
@@ -2,87 +2,10 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#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*/)
|
||||
{
|
||||
@@ -91,13 +14,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
|
||||
#define MY_CreateClass(n) \
|
||||
if (*clsid == CLSID_CCrypto_ ## n ## _Encoder) { \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder2 *)new C ## n ## _Encoder(); \
|
||||
if (!correctInterface) return E_NOINTERFACE; \
|
||||
filter = (ICompressFilter *)new C ## n ## _Encoder(); \
|
||||
} else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder2 *)new C ## n ## _Decoder(); \
|
||||
if (!correctInterface) return E_NOINTERFACE; \
|
||||
filter = (ICompressFilter *)new C ## n ## _Decoder(); \
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
@@ -107,15 +28,15 @@ STDAPI CreateObject(
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*interfaceID == IID_ICompressCoder2);
|
||||
CMyComPtr<ICompressCoder2> coder;
|
||||
int correctInterface = (*interfaceID == IID_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
|
||||
MY_CreateClass(AES128_CBC)
|
||||
else
|
||||
MY_CreateClass(AES256_CBC)
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
*outObject = filter.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -173,12 +94,6 @@ STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
(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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Crypto/Rar20/Encoder.h
|
||||
// Crypto/AES/MyAES.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -6,193 +6,70 @@
|
||||
|
||||
#include "MyAES.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "AES_CBC.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "aesopt.h"
|
||||
static const int kAESBlockSize = 16;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "aesopt.h"
|
||||
}
|
||||
|
||||
class CTabInit
|
||||
{
|
||||
public:
|
||||
CTabInit()
|
||||
{
|
||||
gen_tabs();
|
||||
}
|
||||
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)
|
||||
STDMETHODIMP CAESFilter::Init()
|
||||
{
|
||||
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; }
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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)
|
||||
STDMETHODIMP_(UInt32) CAESFilter::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
try
|
||||
if (size > 0 && size < kAESBlockSize)
|
||||
return kAESBlockSize;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize)
|
||||
{
|
||||
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;
|
||||
Byte outBlock[kAESBlockSize];
|
||||
SubFilter(data + i, outBlock);
|
||||
for (int j = 0; j < kAESBlockSize; j++)
|
||||
data[i + j] = outBlock[j];
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
#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); \
|
||||
STDMETHODIMP CAESFilter::SetInitVector(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size != 16)
|
||||
return E_INVALIDARG;
|
||||
AES.Init(data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
MyClassCryptoImp(AES128_CBC, 16)
|
||||
MyClassCryptoImp(AES256_CBC, 32)
|
||||
STDMETHODIMP CAESEncoder::SetKey(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (AES.enc_key(data, size) != aes_good)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CAESEncoder::SubFilter(const Byte *inBlock, Byte *outBlock)
|
||||
{
|
||||
AES.Encode(inBlock, outBlock);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAESDecoder::SetKey(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (AES.dec_key(data, size) != aes_good)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CAESDecoder::SubFilter(const Byte *inBlock, Byte *outBlock)
|
||||
{
|
||||
AES.Decode(inBlock, outBlock);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// Cipher/AES/MyAES.h
|
||||
|
||||
#pragma once
|
||||
// Crypto/AES/MyAES.h
|
||||
|
||||
#ifndef __CIPHER_MYAES_H
|
||||
#define __CIPHER_MYAES_H
|
||||
@@ -9,37 +7,53 @@
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "AES_CBC.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); \
|
||||
class CAESFilter:
|
||||
public ICompressFilter,
|
||||
public ICryptoProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
protected:
|
||||
CAES_CBC AES;
|
||||
// Byte Key[32];
|
||||
// Byte IV[kAESBlockSize];
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoProperties)
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0;
|
||||
STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
|
||||
virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0;
|
||||
};
|
||||
|
||||
class CAESEncoder: public CAESFilter
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetKey)(const Byte *data, UInt32 size);
|
||||
virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
|
||||
};
|
||||
|
||||
class CAESDecoder: public CAESFilter
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetKey)(const Byte *data, UInt32 size);
|
||||
virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
|
||||
};
|
||||
|
||||
#define MyClassCrypto3E(Name) class C ## Name: public CAESEncoder { };
|
||||
#define MyClassCrypto3D(Name) class C ## Name: public CAESDecoder { };
|
||||
|
||||
// {23170F69-40C1-278B-0601-000000000000}
|
||||
#define MyClassCrypto2(Name, id, encodingId) \
|
||||
DEFINE_GUID(CLSID_CCrypto_ ## Name, \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00); \
|
||||
MyClassCrypto3(Name) \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00);
|
||||
|
||||
#define MyClassCrypto(Name, id) \
|
||||
MyClassCrypto2(Name ## _Encoder, id, 0x01) \
|
||||
MyClassCrypto2(Name ## _Decoder, id, 0x00)
|
||||
MyClassCrypto3E(Name ## _Encoder) \
|
||||
MyClassCrypto2(Name ## _Decoder, id, 0x00) \
|
||||
MyClassCrypto3D(Name ## _Decoder) \
|
||||
|
||||
MyClassCrypto(AES128_CBC, 0x01)
|
||||
MyClassCrypto(AES256_CBC, 0x81)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
|
||||
// 2003-09-16: Changed by Igor Pavlov. Check it.
|
||||
// #if defined(__GNUC__) || defined(__GNU_LIBRARY__)
|
||||
#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(WIN32)
|
||||
#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(_WIN32)
|
||||
|
||||
# include <endian.h>
|
||||
# include <byteswap.h>
|
||||
@@ -183,7 +183,7 @@
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# include <stdlib.h>
|
||||
#elif !defined(WIN32)
|
||||
#elif !defined(_WIN32)
|
||||
# include <stdlib.h>
|
||||
# if !defined (_ENDIAN_H)
|
||||
# include <sys/param.h>
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -84,15 +84,15 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "AES Crypto\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileDescription", "AES Crypto Codec\0"
|
||||
VALUE "FileVersion", "4, 16, 0, 0\0"
|
||||
VALUE "InternalName", "AES\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 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 "ProductVersion", "4, 16, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -10,36 +10,44 @@ 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)
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_coder.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Init()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
const UInt16 kBlockSize = 16;
|
||||
if (size > 0 && size < kBlockSize)
|
||||
return kBlockSize;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kBlockSize <= size; i += kBlockSize)
|
||||
{
|
||||
_coder.DecryptBlock(data + i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
UINT64 nowPos = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT32 processedSize;
|
||||
UInt64 nowPos = 0;
|
||||
UInt32 bufferPos = 0;
|
||||
UInt32 processedSize;
|
||||
while(true)
|
||||
{
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
UInt32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
|
||||
|
||||
UINT32 anEndPos = bufferPos + processedSize;
|
||||
UInt32 anEndPos = bufferPos + processedSize;
|
||||
for (;bufferPos + 16 <= anEndPos; bufferPos += 16)
|
||||
_coder.DecryptBlock(_buffer + bufferPos);
|
||||
|
||||
@@ -47,7 +55,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
return S_OK;
|
||||
|
||||
if (outSize != NULL && nowPos + bufferPos > *outSize)
|
||||
bufferPos = UINT32(*outSize - nowPos);
|
||||
bufferPos = UInt32(*outSize - nowPos);
|
||||
|
||||
RINOK(outStream->Write(_buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
@@ -63,5 +71,6 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
bufferPos = i;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,24 +14,19 @@ namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressFilter,
|
||||
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);
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Crypto.h"
|
||||
#include "Common/Crc.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))))
|
||||
#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]={
|
||||
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,
|
||||
@@ -32,23 +32,22 @@ static const BYTE InitSubstTable[256]={
|
||||
116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
|
||||
};
|
||||
|
||||
void CData::UpdateKeys(const BYTE *data)
|
||||
void CData::UpdateKeys(const Byte *data)
|
||||
{
|
||||
for (int i = 0; i < 16; i += 4)
|
||||
for (int j = 0; j < 4; j ++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
Keys[j] ^= CCRC::Table[data[i + j]];
|
||||
}
|
||||
|
||||
static void Swap(BYTE *Ch1, BYTE *Ch2)
|
||||
static void Swap(Byte *b1, Byte *b2)
|
||||
{
|
||||
BYTE Ch = *Ch1;
|
||||
*Ch1 = *Ch2;
|
||||
*Ch2 = Ch;
|
||||
Byte b = *b1;
|
||||
*b1 = *b2;
|
||||
*b2 = b;
|
||||
}
|
||||
|
||||
void CData::SetPassword(const BYTE *password, UINT32 passwordLength)
|
||||
void CData::SetPassword(const Byte *password, UInt32 passwordLength)
|
||||
{
|
||||
|
||||
// SetOldKeys(password);
|
||||
|
||||
Keys[0] = 0xD3A3B879L;
|
||||
@@ -56,41 +55,56 @@ void CData::SetPassword(const BYTE *password, UINT32 passwordLength)
|
||||
Keys[2] = 0x7515A235L;
|
||||
Keys[3] = 0xA4E7F123L;
|
||||
|
||||
BYTE Psw[256];
|
||||
memset(Psw, 0, sizeof(Psw));
|
||||
Byte psw[256];
|
||||
memset(psw, 0, sizeof(psw));
|
||||
|
||||
memmove(Psw, password, passwordLength);
|
||||
memmove(psw, password, passwordLength);
|
||||
|
||||
memcpy(SubstTable, InitSubstTable, sizeof(SubstTable));
|
||||
for (UINT32 j = 0; j < 256; j++)
|
||||
for (UINT32 i = 0; i < passwordLength; i += 2)
|
||||
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++)
|
||||
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]);
|
||||
for (UInt32 i = 0; i < passwordLength; i+= 16)
|
||||
EncryptBlock(&psw[i]);
|
||||
}
|
||||
|
||||
void CData::EncryptBlock(BYTE *Buf)
|
||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
||||
{
|
||||
UINT32 A, B, C, D, T, TA, TB;
|
||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
||||
}
|
||||
|
||||
UINT32 *BufPtr;
|
||||
BufPtr = (UINT32 *)Buf;
|
||||
static inline void WriteUInt32ToMemLE(UInt32 v, Byte *p)
|
||||
{
|
||||
p[0] = (Byte)v;
|
||||
p[1] = (Byte)(v >> 8);
|
||||
p[2] = (Byte)(v >> 16);
|
||||
p[3] = (Byte)(v >> 24);
|
||||
}
|
||||
|
||||
void CData::CryptBlock(Byte *buf, bool encrypt)
|
||||
{
|
||||
Byte inBuf[16];
|
||||
UInt32 A, B, C, D, T, TA, TB;
|
||||
|
||||
A = GetUInt32FromMemLE(buf + 0) ^ Keys[0];
|
||||
B = GetUInt32FromMemLE(buf + 4) ^ Keys[1];
|
||||
C = GetUInt32FromMemLE(buf + 8) ^ Keys[2];
|
||||
D = GetUInt32FromMemLE(buf + 12) ^ Keys[3];
|
||||
|
||||
if (!encrypt)
|
||||
memcpy(inBuf, buf, sizeof(inBuf));
|
||||
|
||||
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]);
|
||||
UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
|
||||
T = ((C + rol(D, 11)) ^ key);
|
||||
TA = A ^ SubstLong(T);
|
||||
T=((D ^ rol(C, 17)) + Keys[i & 3]);
|
||||
T = ((D ^ rol(C, 17)) + key);
|
||||
TB = B ^ SubstLong(T);
|
||||
A = C;
|
||||
B = D;
|
||||
@@ -98,47 +112,13 @@ void CData::EncryptBlock(BYTE *Buf)
|
||||
D = TB;
|
||||
}
|
||||
|
||||
BufPtr[0] = C ^ Keys[0];
|
||||
BufPtr[1] = D ^ Keys[1];
|
||||
BufPtr[2] = A ^ Keys[2];
|
||||
BufPtr[3] = B ^ Keys[3];
|
||||
WriteUInt32ToMemLE(C ^ Keys[0], buf + 0);
|
||||
WriteUInt32ToMemLE(D ^ Keys[1], buf + 4);
|
||||
WriteUInt32ToMemLE(A ^ Keys[2], buf + 8);
|
||||
WriteUInt32ToMemLE(B ^ Keys[3], buf + 12);
|
||||
|
||||
UpdateKeys(Buf);
|
||||
UpdateKeys(encrypt ? buf : inBuf);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
// Crypto/Rar20/Crypto.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CRYPTO_RAR20_CRYPTO_H
|
||||
#define __CRYPTO_RAR20_CRYPTO_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
|
||||
class CData
|
||||
{
|
||||
BYTE SubstTable[256];
|
||||
UINT32 Keys[4];
|
||||
UINT32 SubstLong(UINT32 t)
|
||||
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);
|
||||
return (UInt32)SubstTable[(int)t & 255] |
|
||||
((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) |
|
||||
((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) |
|
||||
((UInt32)SubstTable[(int)(t >> 24) & 255] << 24);
|
||||
}
|
||||
|
||||
void UpdateKeys(const BYTE *data);
|
||||
void UpdateKeys(const Byte *data);
|
||||
void CryptBlock(Byte *buf, bool encrypt);
|
||||
public:
|
||||
void EncryptBlock(BYTE *Buf);
|
||||
void DecryptBlock(BYTE *Buf);
|
||||
void SetPassword(const BYTE *password, UINT32 passwordLength);
|
||||
void EncryptBlock(Byte *buf) { CryptBlock(buf, true); }
|
||||
void DecryptBlock(Byte *buf) { CryptBlock(buf, false); }
|
||||
void SetPassword(const Byte *password, UInt32 passwordLength);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
8
7zip/Crypto/Rar20/StdAfx.h
Executable file
8
7zip/Crypto/Rar20/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -3,11 +3,6 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Archive/Common/CoderLoader.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "RarAES.h"
|
||||
#include "sha1.h"
|
||||
|
||||
@@ -28,16 +23,13 @@ CDecoder::CDecoder():
|
||||
_salt[i] = 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
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))
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
if (size < 8)
|
||||
return E_INVALIDARG;
|
||||
_thereIsSalt = true;
|
||||
bool same = false;
|
||||
@@ -47,7 +39,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
if (_thereIsSalt)
|
||||
{
|
||||
for (int i = 0; i < sizeof(_salt); i++)
|
||||
if (_salt[i] != salt[i])
|
||||
if (_salt[i] != data[i])
|
||||
{
|
||||
same = false;
|
||||
break;
|
||||
@@ -55,19 +47,19 @@ STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < sizeof(_salt); i++)
|
||||
_salt[i] = salt[i];
|
||||
_salt[i] = data[i];
|
||||
if (!_needCalculate && !same)
|
||||
_needCalculate = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
bool same = false;
|
||||
if (size == buffer.GetCapacity())
|
||||
{
|
||||
same = true;
|
||||
for (UINT32 i = 0; i < size; i++)
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
if (data[i] != buffer[i])
|
||||
{
|
||||
same = false;
|
||||
@@ -81,16 +73,41 @@ STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress)
|
||||
STDMETHODIMP CDecoder::Init()
|
||||
{
|
||||
Calculate();
|
||||
CreateFilter();
|
||||
CMyComPtr<ICryptoProperties> cp;
|
||||
RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
|
||||
RINOK(cp->SetKey(aesKey, 16));
|
||||
RINOK(cp->SetInitVector(aesInit, 16));
|
||||
_aesFilter->Init();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CreateFilter()
|
||||
{
|
||||
if (_aesFilter)
|
||||
return S_OK;
|
||||
TCHAR aesLibPath[MAX_PATH + 64];
|
||||
GetCryptoFolderPrefix(aesLibPath);
|
||||
lstrcat(aesLibPath, TEXT("AES.dll"));
|
||||
return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES128_Decoder, &_aesFilter);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
return _aesFilter->Filter(data, size);
|
||||
}
|
||||
|
||||
void CDecoder::Calculate()
|
||||
{
|
||||
if (_needCalculate)
|
||||
{
|
||||
const MAXPASSWORD = 128;
|
||||
const SALT_SIZE = 8;
|
||||
const int MAXPASSWORD = 128;
|
||||
const int SALT_SIZE = 8;
|
||||
|
||||
BYTE rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
|
||||
Byte rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
|
||||
|
||||
memcpy(rawPassword, buffer, buffer.GetCapacity());
|
||||
|
||||
@@ -110,27 +127,36 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
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);
|
||||
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];
|
||||
UInt32 digest[5];
|
||||
hash_final(&tempc, digest);
|
||||
aesInit[i / (hashRounds / 16)] = (BYTE)digest[4];
|
||||
aesInit[i / (hashRounds / 16)] = (Byte)digest[4];
|
||||
}
|
||||
}
|
||||
UINT32 digest[5];
|
||||
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));
|
||||
aesKey[i * 4 + j] = (Byte)(digest[i] >> (j * 8));
|
||||
}
|
||||
_needCalculate = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UInt64 const *inSize,
|
||||
const UInt64 *outSize,ICompressProgressInfo *progress)
|
||||
{
|
||||
Calculate();
|
||||
TCHAR aesLibPath[MAX_PATH + 64];
|
||||
GetCryptoFolderPrefix(aesLibPath);
|
||||
lstrcat(aesLibPath, TEXT("AES.dll"));
|
||||
@@ -147,11 +173,12 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
keyStreamSpec->Init(aesKey, 16);
|
||||
|
||||
ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
|
||||
UINT64 ivSize = 16;
|
||||
UINT64 keySize = 16;
|
||||
const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
|
||||
UInt64 ivSize = 16;
|
||||
UInt64 keySize = 16;
|
||||
const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
|
||||
return aesDecoder->Code(inStreams, inSizes, 3,
|
||||
&outStream, &outSize, 1, progress);
|
||||
}
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Archive/Common/CoderLoader.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Buffer.h"
|
||||
@@ -14,31 +15,37 @@ namespace NCrypto {
|
||||
namespace NRar29 {
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICompressFilter,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE _salt[8];
|
||||
Byte _salt[8];
|
||||
bool _thereIsSalt;
|
||||
CByteBuffer buffer;
|
||||
BYTE aesKey[16];
|
||||
BYTE aesInit[16];
|
||||
Byte aesKey[16];
|
||||
Byte aesInit[16];
|
||||
bool _needCalculate;
|
||||
|
||||
CCoderLibrary _aesLib;
|
||||
CMyComPtr<ICompressFilter> _aesFilter;
|
||||
|
||||
void Calculate();
|
||||
HRESULT CreateFilter();
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICompressSetDecoderProperties)
|
||||
ICompressSetDecoderProperties2)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, UINT64 const *inSize,
|
||||
const UINT64 *outSize,ICompressProgressInfo *progress);
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize);
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
CDecoder();
|
||||
};
|
||||
|
||||
8
7zip/Crypto/RarAES/StdAfx.h
Executable file
8
7zip/Crypto/RarAES/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -52,12 +52,12 @@ By Steve Reid <steve@edmweb.com>
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
|
||||
void SHA1Transform(UINT32 state[5], unsigned char buffer[64])
|
||||
void SHA1Transform(UInt32 state[5], unsigned char buffer[64])
|
||||
{
|
||||
UINT32 a, b, c, d, e;
|
||||
UInt32 a, b, c, d, e;
|
||||
typedef union {
|
||||
unsigned char c[64];
|
||||
UINT32 l[16];
|
||||
UInt32 l[16];
|
||||
} CHAR64LONG16;
|
||||
CHAR64LONG16* block;
|
||||
#ifdef SHA1HANDSOFF
|
||||
@@ -82,7 +82,7 @@ void SHA1Transform(UINT32 state[5], unsigned char buffer[64])
|
||||
}
|
||||
pinit=true;
|
||||
}
|
||||
UINT32 s[5];
|
||||
UInt32 s[5];
|
||||
for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
|
||||
s[I]=state[I];
|
||||
|
||||
@@ -159,7 +159,7 @@ void hash_initial(hash_context* context)
|
||||
void hash_process( hash_context * context, unsigned char * data, unsigned len )
|
||||
{
|
||||
unsigned int i, j;
|
||||
UINT32 blen = ((UINT32)len)<<3;
|
||||
UInt32 blen = ((UInt32)len)<<3;
|
||||
|
||||
j = (context->count[0] >> 3) & 63;
|
||||
if ((context->count[0] += blen) < blen ) context->count[1]++;
|
||||
@@ -180,9 +180,9 @@ void hash_process( hash_context * context, unsigned char * data, unsigned len )
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
|
||||
void hash_final( hash_context* context, UINT32 digest[5] )
|
||||
void hash_final( hash_context* context, UInt32 digest[5] )
|
||||
{
|
||||
UINT32 i, j;
|
||||
UInt32 i, j;
|
||||
unsigned char finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
@@ -4,16 +4,18 @@
|
||||
#ifndef _RAR_SHA1_
|
||||
#define _RAR_SHA1_
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
#define HW 5
|
||||
|
||||
typedef struct {
|
||||
UINT32 state[5];
|
||||
UINT32 count[2];
|
||||
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] );
|
||||
void hash_final( hash_context * c, UInt32[HW] );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -8,111 +8,97 @@
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
/*
|
||||
const int kBufferSize = 1 << 17;
|
||||
|
||||
CBuffer2::CBuffer2():
|
||||
_buffer(0)
|
||||
{
|
||||
_buffer = new BYTE[kBufferSize];
|
||||
_buffer = new Byte[kBufferSize];
|
||||
}
|
||||
|
||||
CBuffer2::~CBuffer2()
|
||||
{
|
||||
delete []_buffer;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CEncoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_cipher.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::CryptoSetCRC(UINT32 crc)
|
||||
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)
|
||||
STDMETHODIMP CEncoder::Init()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
|
||||
{
|
||||
CRandom random;
|
||||
random.Init(::GetTickCount());
|
||||
|
||||
UINT64 nowPos = 0;
|
||||
BYTE header[kHeaderSize];
|
||||
UInt64 nowPos = 0;
|
||||
Byte header[kHeaderSize];
|
||||
for (int i = 0; i < kHeaderSize - 2; i++)
|
||||
{
|
||||
header[i] = BYTE(random.Generate());
|
||||
header[i] = Byte(random.Generate());
|
||||
}
|
||||
header[kHeaderSize - 1] = BYTE(_crc >> 24);
|
||||
header[kHeaderSize - 2] = BYTE(_crc >> 16);
|
||||
header[kHeaderSize - 1] = Byte(_crc >> 24);
|
||||
header[kHeaderSize - 2] = Byte(_crc >> 16);
|
||||
|
||||
UINT32 processedSize;
|
||||
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;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
|
||||
STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < size; i++)
|
||||
data[i] = _cipher.EncryptByte(data[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_cipher.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
|
||||
{
|
||||
UINT64 nowPos = 0;
|
||||
|
||||
if (inSize != NULL && *inSize == 0)
|
||||
return S_OK;
|
||||
|
||||
BYTE header[kHeaderSize];
|
||||
UINT32 processedSize;
|
||||
UInt64 nowPos = 0;
|
||||
Byte header[kHeaderSize];
|
||||
UInt32 processedSize;
|
||||
RINOK(inStream->Read(header, kHeaderSize, &processedSize));
|
||||
if (processedSize != kHeaderSize)
|
||||
return E_FAIL;
|
||||
_cipher.DecryptHeader(header);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
STDMETHODIMP CDecoder::Init()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < size; i++)
|
||||
data[i] = _cipher.DecryptByte(data[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -15,56 +15,56 @@
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
/*
|
||||
class CBuffer2
|
||||
{
|
||||
protected:
|
||||
BYTE *_buffer;
|
||||
Byte *_buffer;
|
||||
public:
|
||||
CBuffer2();
|
||||
~CBuffer2();
|
||||
};
|
||||
|
||||
*/
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public ICryptoSetCRC,
|
||||
public CMyUnknownImp,
|
||||
public CBuffer2
|
||||
public CMyUnknownImp
|
||||
// public CBuffer2
|
||||
{
|
||||
CCipher _cipher;
|
||||
UINT32 _crc;
|
||||
UInt32 _crc;
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICryptoSetPassword,
|
||||
ICryptoSetCRC
|
||||
)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
|
||||
STDMETHOD(CryptoSetCRC)(UINT32 crc);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
STDMETHOD(CryptoSetCRC)(UInt32 crc);
|
||||
HRESULT WriteHeader(ISequentialOutStream *outStream);
|
||||
};
|
||||
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp,
|
||||
public CBuffer2
|
||||
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(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
|
||||
HRESULT ReadHeader(ISequentialInStream *inStream);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -3,60 +3,60 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipCipher.h"
|
||||
#include "Common/Crc.h"
|
||||
#include "../../../Common/CRC.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
inline UINT32 CRC32(UINT32 c, BYTE b)
|
||||
static inline UInt32 ZipCRC32(UInt32 c, Byte b)
|
||||
{
|
||||
return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8);
|
||||
}
|
||||
|
||||
void CCipher::UpdateKeys(BYTE b)
|
||||
void CCipher::UpdateKeys(Byte b)
|
||||
{
|
||||
Keys[0] = CRC32(Keys[0], b);
|
||||
Keys[0] = ZipCRC32(Keys[0], b);
|
||||
Keys[1] += Keys[0] & 0xff;
|
||||
Keys[1] = Keys[1] * 134775813L + 1;
|
||||
Keys[2] = CRC32(Keys[2], Keys[1] >> 24);
|
||||
Keys[2] = ZipCRC32(Keys[2], Keys[1] >> 24);
|
||||
}
|
||||
|
||||
void CCipher::SetPassword(const BYTE *password, UINT32 passwordLength)
|
||||
void CCipher::SetPassword(const Byte *password, UInt32 passwordLength)
|
||||
{
|
||||
Keys[0] = 305419896L;
|
||||
Keys[1] = 591751049L;
|
||||
Keys[2] = 878082192L;
|
||||
for (UINT32 i = 0; i < passwordLength; i++)
|
||||
for (UInt32 i = 0; i < passwordLength; i++)
|
||||
UpdateKeys(password[i]);
|
||||
}
|
||||
|
||||
BYTE CCipher::DecryptByteSpec()
|
||||
Byte CCipher::DecryptByteSpec()
|
||||
{
|
||||
UINT32 temp = Keys[2] | 2;
|
||||
UInt32 temp = Keys[2] | 2;
|
||||
return (temp * (temp ^ 1)) >> 8;
|
||||
}
|
||||
|
||||
BYTE CCipher::DecryptByte(BYTE encryptedByte)
|
||||
Byte CCipher::DecryptByte(Byte encryptedByte)
|
||||
{
|
||||
BYTE c = encryptedByte ^ DecryptByteSpec();
|
||||
Byte c = encryptedByte ^ DecryptByteSpec();
|
||||
UpdateKeys(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
BYTE CCipher::EncryptByte(BYTE b)
|
||||
Byte CCipher::EncryptByte(Byte b)
|
||||
{
|
||||
BYTE c = b ^ DecryptByteSpec();
|
||||
Byte c = b ^ DecryptByteSpec();
|
||||
UpdateKeys(b);
|
||||
return c;
|
||||
}
|
||||
|
||||
void CCipher::DecryptHeader(BYTE *buffer)
|
||||
void CCipher::DecryptHeader(Byte *buffer)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
buffer[i] = DecryptByte(buffer[i]);
|
||||
}
|
||||
|
||||
void CCipher::EncryptHeader(BYTE *buffer)
|
||||
void CCipher::EncryptHeader(Byte *buffer)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
buffer[i] = EncryptByte(buffer[i]);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Crypto/ZipCrypto.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CRYPTO_ZIP_CRYPTO_H
|
||||
#define __CRYPTO_ZIP_CRYPTO_H
|
||||
|
||||
@@ -11,15 +9,15 @@ namespace NZip {
|
||||
const int kHeaderSize = 12;
|
||||
class CCipher
|
||||
{
|
||||
UINT32 Keys[3];
|
||||
void UpdateKeys(BYTE b);
|
||||
BYTE DecryptByteSpec();
|
||||
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);
|
||||
void SetPassword(const Byte *password, UInt32 passwordLength);
|
||||
Byte DecryptByte(Byte encryptedByte);
|
||||
Byte EncryptByte(Byte b);
|
||||
void DecryptHeader(Byte *buffer);
|
||||
void EncryptHeader(Byte *buffer);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user