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

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