mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-15 22:11:39 -06:00
4.27 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
31e7b924e8
commit
d66cf2fcf3
@@ -5,6 +5,7 @@
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "7zAES.h"
|
||||
// #include "../../Hash/Common/CryptoHashInterface.h"
|
||||
@@ -169,11 +170,11 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
RINOK(outStream->Write(&secondByte, 1, NULL));
|
||||
if (_key.SaltSize > 0)
|
||||
{
|
||||
RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL));
|
||||
RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL));
|
||||
}
|
||||
if (ivSize > 0)
|
||||
{
|
||||
RINOK(outStream->Write(_iv, ivSize, NULL));
|
||||
RINOK(WriteStream(outStream, _iv, ivSize, NULL));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -154,6 +154,14 @@ SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -22,6 +22,7 @@ WIN_OBJS = \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\StreamObjects.obj \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace NRar29 {
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_thereIsSalt(false),
|
||||
_needCalculate(true)
|
||||
_needCalculate(true),
|
||||
_rar350Mode(false)
|
||||
{
|
||||
for (int i = 0; i < sizeof(_salt); i++)
|
||||
_salt[i] = 0;
|
||||
@@ -53,8 +54,12 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const int kMaxPasswordLength = 127 * 2;
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size > kMaxPasswordLength)
|
||||
size = kMaxPasswordLength;
|
||||
bool same = false;
|
||||
if (size == buffer.GetCapacity())
|
||||
{
|
||||
@@ -104,10 +109,9 @@ void CDecoder::Calculate()
|
||||
{
|
||||
if (_needCalculate)
|
||||
{
|
||||
const int MAXPASSWORD = 128;
|
||||
const int SALT_SIZE = 8;
|
||||
const int kSaltSize = 8;
|
||||
|
||||
Byte rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
|
||||
Byte rawPassword[kMaxPasswordLength + kSaltSize];
|
||||
|
||||
memcpy(rawPassword, buffer, buffer.GetCapacity());
|
||||
|
||||
@@ -115,24 +119,24 @@ void CDecoder::Calculate()
|
||||
|
||||
if (_thereIsSalt)
|
||||
{
|
||||
memcpy(rawPassword + rawLength, _salt, SALT_SIZE);
|
||||
rawLength += SALT_SIZE;
|
||||
memcpy(rawPassword + rawLength, _salt, kSaltSize);
|
||||
rawLength += kSaltSize;
|
||||
}
|
||||
|
||||
CSHA1 sha;
|
||||
sha.Init();
|
||||
|
||||
|
||||
// seems rar reverts hash for sha.
|
||||
const int hashRounds = 0x40000;
|
||||
int i;
|
||||
for (i = 0; i < hashRounds; i++)
|
||||
{
|
||||
sha.Update(rawPassword, rawLength);
|
||||
sha.Update(rawPassword, rawLength, _rar350Mode);
|
||||
Byte pswNum[3];
|
||||
pswNum[0] = (Byte)i;
|
||||
pswNum[1] = (Byte)(i >> 8);
|
||||
pswNum[2] = (Byte)(i >> 16);
|
||||
sha.Update(pswNum, 3);
|
||||
sha.Update(pswNum, 3, _rar350Mode);
|
||||
if (i % (hashRounds / 16) == 0)
|
||||
{
|
||||
CSHA1 shaTemp = sha;
|
||||
|
||||
@@ -30,6 +30,8 @@ class CDecoder:
|
||||
CCoderLibrary _aesLib;
|
||||
CMyComPtr<ICompressFilter> _aesFilter;
|
||||
|
||||
bool _rar350Mode;
|
||||
|
||||
void Calculate();
|
||||
HRESULT CreateFilter();
|
||||
|
||||
@@ -48,6 +50,7 @@ public:
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
CDecoder();
|
||||
void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
static inline rotlFixed(UInt32 x, int n)
|
||||
static inline UInt32 rotlFixed(UInt32 x, int n)
|
||||
{
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
@@ -29,7 +29,7 @@ static inline rotlFixed(UInt32 x, int n)
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
|
||||
void CSHA1::Transform(const UInt32 data[16])
|
||||
void CSHA1::Transform(UInt32 data[16], bool returnRes)
|
||||
{
|
||||
UInt32 a, b, c, d, e;
|
||||
UInt32 W[16];
|
||||
@@ -67,6 +67,9 @@ void CSHA1::Transform(const UInt32 data[16])
|
||||
m_State[2] += c;
|
||||
m_State[3] += d;
|
||||
m_State[4] += e;
|
||||
if (returnRes)
|
||||
for (int i = 0 ; i < 16; i++)
|
||||
data[i] = W[i];
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
@@ -84,10 +87,11 @@ void CSHA1::Init()
|
||||
}
|
||||
|
||||
|
||||
void CSHA1::WriteByteBlock()
|
||||
void CSHA1::WriteByteBlock(bool returnRes)
|
||||
{
|
||||
UInt32 data32[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
data32[i] =
|
||||
(UInt32(_buffer[i * 4 + 0]) << 24) +
|
||||
@@ -95,11 +99,21 @@ void CSHA1::WriteByteBlock()
|
||||
(UInt32(_buffer[i * 4 + 2]) << 8) +
|
||||
UInt32(_buffer[i * 4 + 3]);
|
||||
}
|
||||
Transform(data32);
|
||||
Transform(data32, returnRes);
|
||||
if (returnRes)
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
UInt32 d = data32[i];
|
||||
_buffer[i * 4 + 0] = (Byte)(d >> 0);
|
||||
_buffer[i * 4 + 1] = (Byte)(d >> 8);
|
||||
_buffer[i * 4 + 2] = (Byte)(d >> 16);
|
||||
_buffer[i * 4 + 3] = (Byte)(d >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
void CSHA1::Update(const Byte *data, size_t size)
|
||||
void CSHA1::Update(Byte *data, size_t size, bool rar350Mode)
|
||||
{
|
||||
bool returnRes = false;
|
||||
UInt32 curBufferPos = UInt32(m_Count) & 0x3F;
|
||||
while (size > 0)
|
||||
{
|
||||
@@ -112,7 +126,11 @@ void CSHA1::Update(const Byte *data, size_t size)
|
||||
if (curBufferPos == 64)
|
||||
{
|
||||
curBufferPos = 0;
|
||||
WriteByteBlock();
|
||||
WriteByteBlock(returnRes);
|
||||
if (returnRes)
|
||||
for (int i = 0; i < 64; i++)
|
||||
data[i - 64] = _buffer[i];
|
||||
returnRes = rar350Mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +147,8 @@ void CSHA1::Final(Byte *digest)
|
||||
WriteByteBlock();
|
||||
_buffer[curBufferPos++] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
_buffer[curBufferPos++] = Byte(lenInBits >> 56);
|
||||
lenInBits <<= 8;
|
||||
|
||||
@@ -10,17 +10,22 @@
|
||||
|
||||
#define HW 5
|
||||
|
||||
// Sha1 implementation in RAR before version 3.60 has bug:
|
||||
// it changes data bytes in some cases.
|
||||
// So this class supports both versions: normal_SHA and rar3Mode
|
||||
|
||||
struct CSHA1
|
||||
{
|
||||
UInt32 m_State[5];
|
||||
UInt64 m_Count;
|
||||
unsigned char _buffer[64];
|
||||
|
||||
void Transform(const UInt32 data[16]);
|
||||
void WriteByteBlock();
|
||||
void Transform(UInt32 data[16], bool returnRes = false);
|
||||
void WriteByteBlock(bool returnRes = false);
|
||||
|
||||
public:
|
||||
void Init();
|
||||
void Update(const Byte *data, size_t size);
|
||||
void Update(Byte *data, size_t size, bool rar350Mode = false);
|
||||
void Final(Byte *digest);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "ZipCipher.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
@@ -56,7 +58,7 @@ HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
|
||||
|
||||
UInt32 processedSize;
|
||||
_cipher.EncryptHeader(header);
|
||||
RINOK(outStream->Write(header, kHeaderSize, &processedSize));
|
||||
RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize));
|
||||
if (processedSize != kHeaderSize)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
@@ -81,7 +83,7 @@ HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
|
||||
UInt64 nowPos = 0;
|
||||
Byte header[kHeaderSize];
|
||||
UInt32 processedSize;
|
||||
RINOK(inStream->Read(header, kHeaderSize, &processedSize));
|
||||
RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize));
|
||||
if (processedSize != kHeaderSize)
|
||||
return E_FAIL;
|
||||
_cipher.DecryptHeader(header);
|
||||
|
||||
Reference in New Issue
Block a user