This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -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
}
}}

View File

@@ -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

View File

@@ -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);
};
}}

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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);
};
}}

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -1,8 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -1,8 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
#endif
#endif

View File

@@ -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>

View File

@@ -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

View File

@@ -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;
}
}
*/
}}

View File

@@ -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);
};

View File

@@ -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);
}
}}

View File

@@ -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
View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#endif

View File

@@ -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);
}
*/
}}

View File

@@ -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
View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#endif

View File

@@ -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++) {

View File

@@ -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

View File

@@ -1,8 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
#endif
#endif

View File

@@ -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;
}
}}

View File

@@ -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);
};
}}

View File

@@ -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]);

View File

@@ -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);
};