This commit is contained in:
Igor Pavlov
2017-04-30 00:00:00 +00:00
committed by Kornel
parent 603abd5528
commit 2efa10565a
442 changed files with 15479 additions and 8525 deletions

View File

@@ -30,6 +30,8 @@ class CAesCbcCoder:
public:
CAesCbcCoder(bool encodeMode, unsigned keySize);
virtual ~CAesCbcCoder() {}; // we need virtual destructor for derived classes
MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
INTERFACE_ICompressFilter(;)

View File

@@ -68,7 +68,7 @@ void CData::SetPassword(const Byte *data, unsigned size)
for (unsigned i = 0; i < size; i += 2)
{
unsigned n1 = (Byte)g_CrcTable[(psw[i] - j) & 0xFF];
unsigned n2 = (Byte)g_CrcTable[(psw[i + 1] + j) & 0xFF];
unsigned n2 = (Byte)g_CrcTable[(psw[(size_t)i + 1] + j) & 0xFF];
for (unsigned k = 1; (n1 & 0xFF) != n2; n1++, k++)
Swap(SubstTable[n1 & 0xFF], SubstTable[(n1 + i + k) & 0xFF]);
}

View File

@@ -20,10 +20,10 @@ class CData
UInt32 SubstLong(UInt32 t) const
{
return (UInt32)SubstTable[(unsigned)t & 255]
| ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8)
return (UInt32)SubstTable[(unsigned)t & 255]
| ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8)
| ((UInt32)SubstTable[(unsigned)(t >> 16) & 255] << 16)
| ((UInt32)SubstTable[(unsigned)(t >> 24) & 255] << 24);
| ((UInt32)SubstTable[(unsigned)(t >> 24) ] << 24);
}
void UpdateKeys(const Byte *data);
void CryptBlock(Byte *buf, bool encrypt);

View File

@@ -105,6 +105,8 @@ public:
_key.KeySizeMode = (EKeySizeMode)mode;
return true;
}
virtual ~CBaseCoder() {}
};
class CEncoder:

View File

@@ -50,6 +50,8 @@ public:
MY_UNKNOWN_IMP1(ICryptoSetPassword)
STDMETHOD(Init)();
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
virtual ~CCipher() {}
};
class CEncoder: public CCipher

View File

@@ -15,10 +15,14 @@ namespace NZipStrong {
static const UInt16 kAES128 = 0x660E;
// DeriveKey* function is similar to CryptDeriveKey() from Windows.
// But MSDN tells that we need such scheme only if
// "the required key length is longer than the hash value"
// but ZipStrong uses it always.
/*
DeriveKey() function is similar to CryptDeriveKey() from Windows.
New version of MSDN contains the following condition in CryptDeriveKey() description:
"If the hash is not a member of the SHA-2 family and the required key is for either 3DES or AES".
Now we support ZipStrong for AES only. And it uses SHA1.
Our DeriveKey() code is equal to CryptDeriveKey() in Windows for such conditions: (SHA1 + AES).
if (method != AES && method != 3DES), probably we need another code.
*/
static void DeriveKey2(const Byte *digest, Byte c, Byte *dest)
{
@@ -116,7 +120,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if ((flags & 0x4000) != 0)
{
// Use 3DES
// Use 3DES for rd data
return E_NOTIMPL;
}
@@ -135,17 +139,21 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (rdSize + 16 > _remSize)
return E_NOTIMPL;
const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd
/*
if (cert)
{
// how to filter rd, if ((rdSize & 0xF) != 0) ?
if ((rdSize & 0x7) != 0)
return E_NOTIMPL;
}
else
*/
{
if ((rdSize & 0xF) != 0)
// PKCS7 padding
if (rdSize < kPadSize)
return E_NOTIMPL;
if ((rdSize & (kPadSize - 1)) != 0)
return E_NOTIMPL;
}
@@ -198,13 +206,18 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
RINOK(SetInitVector(_iv, 16));
RINOK(Init());
Filter(p, rdSize);
rdSize -= kPadSize;
for (unsigned i = 0; i < kPadSize; i++)
if (p[(size_t)rdSize + i] != kPadSize)
return S_OK; // passwOK = false;
}
Byte fileKey[32];
NSha1::CContext sha;
sha.Init();
sha.Update(_iv, _ivSize);
sha.Update(p, rdSize - 16); // we don't use last 16 bytes (PAD bytes)
sha.Update(p, rdSize);
DeriveKey(sha, fileKey);
RINOK(SetKey(fileKey, _key.KeySize));

View File

@@ -42,6 +42,8 @@ public:
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
};
const unsigned kAesPadAllign = AES_BLOCK_SIZE;
class CDecoder: public CBaseCoder
{
UInt32 _ivSize;
@@ -51,6 +53,12 @@ public:
MY_UNKNOWN_IMP1(ICryptoSetPassword)
HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize);
HRESULT Init_and_CheckPassword(bool &passwOK);
UInt32 GetPadSize(UInt32 packSize32) const
{
// Padding is to align to blockSize of cipher.
// Change it, if is not AES
return kAesPadAllign - (packSize32 & (kAesPadAllign - 1));
}
};
}}