diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Crypto/ZipStrong.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Crypto/ZipStrong.cpp | 164 |
1 files changed, 0 insertions, 164 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Crypto/ZipStrong.cpp b/src/libs/7zip/win/CPP/7zip/Crypto/ZipStrong.cpp deleted file mode 100644 index 1554b3489..000000000 --- a/src/libs/7zip/win/CPP/7zip/Crypto/ZipStrong.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Crypto/ZipStrong.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/CpuArch.h" - -#include "../Common/StreamUtils.h" - -#include "MyAes.h" -#include "Sha1.h" -#include "ZipStrong.h" - -namespace NCrypto { -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. - -static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) -{ - Byte buf[64]; - memset(buf, c, 64); - for (unsigned i = 0; i < NSha1::kDigestSize; i++) - buf[i] ^= digest[i]; - NSha1::CContext sha; - sha.Init(); - sha.Update(buf, 64); - sha.Final(dest); -} - -static void DeriveKey(NSha1::CContext &sha, Byte *key) -{ - Byte digest[NSha1::kDigestSize]; - sha.Final(digest); - Byte temp[NSha1::kDigestSize * 2]; - DeriveKey2(digest, 0x36, temp); - DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); - memcpy(key, temp, 32); -} - -void CKeyInfo::SetPassword(const Byte *data, UInt32 size) -{ - NSha1::CContext sha; - sha.Init(); - sha.Update(data, size); - DeriveKey(sha, MasterKey); -} - -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - _key.SetPassword(data, size); - return S_OK; -} - -HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 /* crc */, UInt64 /* unpackSize */) -{ - Byte temp[4]; - RINOK(ReadStream_FALSE(inStream, temp, 2)); - _ivSize = GetUi16(temp); - if (_ivSize == 0) - { - return E_NOTIMPL; - /* - SetUi32(_iv, crc); - for (int i = 0; i < 8; i++) - _iv[4 + i] = (Byte)(unpackSize >> (8 * i)); - SetUi32(_iv + 12, 0); - */ - } - else if (_ivSize == 16) - { - RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)); - } - else - return E_NOTIMPL; - RINOK(ReadStream_FALSE(inStream, temp, 4)); - _remSize = GetUi32(temp); - const UInt32 kAlign = 16; - if (_remSize < 16 || _remSize > (1 << 18)) - return E_NOTIMPL; - if (_remSize + kAlign > _buf.GetCapacity()) - { - _buf.Free(); - _buf.SetCapacity(_remSize + kAlign); - _bufAligned = (Byte *)((ptrdiff_t)((Byte *)_buf + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1)); - } - return ReadStream_FALSE(inStream, _bufAligned, _remSize); -} - -HRESULT CDecoder::CheckPassword(bool &passwOK) -{ - passwOK = false; - if (_remSize < 16) - return E_NOTIMPL; - Byte *p = _bufAligned; - UInt16 format = GetUi16(p); - if (format != 3) - return E_NOTIMPL; - UInt16 algId = GetUi16(p + 2); - if (algId < kAES128) - return E_NOTIMPL; - algId -= kAES128; - if (algId > 2) - return E_NOTIMPL; - UInt16 bitLen = GetUi16(p + 4); - UInt16 flags = GetUi16(p + 6); - if (algId * 64 + 128 != bitLen) - return E_NOTIMPL; - _key.KeySize = 16 + algId * 8; - if ((flags & 1) == 0) - return E_NOTIMPL; - if ((flags & 0x4000) != 0) - { - // Use 3DES - return E_NOTIMPL; - } - - UInt32 rdSize = GetUi16(p + 8); - if ((rdSize & 0xF) != 0 || rdSize + 16 > _remSize) - return E_NOTIMPL; - memmove(p, p + 10, rdSize); - Byte *validData = p + rdSize + 16; - if (GetUi32(validData - 6) != 0) // reserved - return E_NOTIMPL; - UInt32 validSize = GetUi16(validData - 2); - if ((validSize & 0xF) != 0 || 16 + rdSize + validSize != _remSize) - return E_NOTIMPL; - - - { - RINOK(SetKey(_key.MasterKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - Init(); - Filter(p, rdSize); - } - - Byte fileKey[32]; - NSha1::CContext sha; - sha.Init(); - sha.Update(_iv, 16); - sha.Update(p, rdSize - 16); // we don't use last 16 bytes (PAD bytes) - DeriveKey(sha, fileKey); - - RINOK(SetKey(fileKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - Init(); - Filter(validData, validSize); - - if (validSize < 4) - return E_NOTIMPL; - validSize -= 4; - if (GetUi32(validData + validSize) != CrcCalc(validData, validSize)) - return S_OK; - passwOK = true; - Init(); - return S_OK; -} - -}} |