2
// Note: you must include Crypto/AES/MyAES.cpp to project to initialize AES tables
7
#include "../../Common/MethodId.h"
8
#include "../Hash/Sha1.h"
18
for (int i = 0; i < sizeof(_salt); i++)
22
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
24
bool thereIsSaltPrev = _thereIsSalt;
32
if (_thereIsSalt == thereIsSaltPrev)
37
for (int i = 0; i < sizeof(_salt); i++)
38
if (_salt[i] != data[i])
45
for (int i = 0; i < sizeof(_salt); i++)
47
if (!_needCalculate && !same)
48
_needCalculate = true;
52
static const int kMaxPasswordLength = 127 * 2;
54
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
56
if (size > kMaxPasswordLength)
57
size = kMaxPasswordLength;
59
if (size == buffer.GetCapacity())
62
for (UInt32 i = 0; i < size; i++)
63
if (data[i] != buffer[i])
69
if (!_needCalculate && !same)
70
_needCalculate = true;
71
buffer.SetCapacity(size);
72
memcpy(buffer, data, size);
76
STDMETHODIMP CDecoder::Init()
79
Aes_SetKeyDecode(&Aes.aes, aesKey, kRarAesKeySize);
80
AesCbc_Init(&Aes, aesInit);
84
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
86
return (UInt32)AesCbc_Decode(&Aes, data, size);
89
void CDecoder::Calculate()
93
const int kSaltSize = 8;
95
Byte rawPassword[kMaxPasswordLength + kSaltSize];
97
memcpy(rawPassword, buffer, buffer.GetCapacity());
99
size_t rawLength = buffer.GetCapacity();
103
memcpy(rawPassword + rawLength, _salt, kSaltSize);
104
rawLength += kSaltSize;
110
// seems rar reverts hash for sha.
111
const int hashRounds = 0x40000;
113
for (i = 0; i < hashRounds; i++)
115
sha.Update(rawPassword, rawLength, _rar350Mode);
116
Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
117
sha.Update(pswNum, 3, _rar350Mode);
118
if (i % (hashRounds / 16) == 0)
120
NSha1::CContext shaTemp = sha;
121
Byte digest[NSha1::kDigestSize];
122
shaTemp.Final(digest);
123
aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3];
127
// it's test message for sha
128
const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
129
sha.Update((const Byte *)message, strlen(message));
133
for (i = 0; i < 4; i++)
134
for (int j = 0; j < 4; j++)
135
aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]);
137
_needCalculate = false;