mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 05:15:01 -06:00
4.63
This commit is contained in:
committed by
Kornel Lesiński
parent
c1f1243a70
commit
3a524e5ba2
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,21 +1,20 @@
|
||||
// 7zAES.cpp
|
||||
// 7zAes.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
#include "../AES/MyAES.h"
|
||||
#include "7zAES.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Sha256.h"
|
||||
#include "../../../C/Sha256.h"
|
||||
}
|
||||
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../Common/StreamObjects.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
#include "7zAes.h"
|
||||
#include "MyAes.h"
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
#include "../Hash/RandGen.h"
|
||||
#include "RandGen.h"
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
@@ -1,15 +1,14 @@
|
||||
// 7zAES.h
|
||||
// 7zAes.h
|
||||
|
||||
#ifndef __CRYPTO_7Z_AES_H
|
||||
#define __CRYPTO_7Z_AES_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/MyVector.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NSevenZ {
|
||||
@@ -1,10 +1,10 @@
|
||||
// BranchRegister.cpp
|
||||
// 7zAesRegister.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterCodec.h"
|
||||
#include "../Common/RegisterCodec.h"
|
||||
#include "7zAes.h"
|
||||
|
||||
#include "7zAES.h"
|
||||
static void *CreateCodec() { return (void *)(ICompressFilter *)(new NCrypto::NSevenZ::CDecoder()); }
|
||||
#ifndef EXTRACT_ONLY
|
||||
static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new NCrypto::NSevenZ::CEncoder()); }
|
||||
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,8 @@
|
||||
// HmacSha1.h
|
||||
// Implements HMAC-SHA-1 (RFC2104, FIPS-198)
|
||||
|
||||
#ifndef _HMAC_H
|
||||
#define _HMAC_H
|
||||
#ifndef __CRYPTO_HMAC_SHA1_H
|
||||
#define __CRYPTO_HMAC_SHA1_H
|
||||
|
||||
#include "Sha1.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Crypto/AES/MyAES.cpp
|
||||
// Crypto/MyAes.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MyAES.h"
|
||||
#include "MyAes.h"
|
||||
|
||||
namespace NCrypto {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// Crypto/AES/MyAES.h
|
||||
// Crypto/MyAes.h
|
||||
|
||||
#ifndef __CIPHER_MYAES_H
|
||||
#define __CIPHER_MYAES_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#ifndef __CRYPTO_MY_AES_H
|
||||
#define __CRYPTO_MY_AES_H
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Aes.h"
|
||||
#include "../../../C/Aes.h"
|
||||
}
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
#include "../../Common/Types.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
|
||||
namespace NCrypto {
|
||||
|
||||
class CAesCbcEncoder:
|
||||
@@ -1,11 +1,11 @@
|
||||
// Pbkdf2HmacSha1.h
|
||||
// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1
|
||||
|
||||
#ifndef __PBKDF2HMACSHA1_H
|
||||
#define __PBKDF2HMACSHA1_H
|
||||
#ifndef __CRYPTO_PBKDF2_HMAC_SHA1_H
|
||||
#define __CRYPTO_PBKDF2_HMAC_SHA1_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../../../Common/Types.h"
|
||||
#include "../../Common/Types.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NSha1 {
|
||||
@@ -3,9 +3,7 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Windows/Synchronization.h"
|
||||
|
||||
#include "RandGen.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -1,7 +1,7 @@
|
||||
// RandGen.h
|
||||
|
||||
#ifndef __RANDGEN_H
|
||||
#define __RANDGEN_H
|
||||
#ifndef __CRYPTO_RAND_GEN_H
|
||||
#define __CRYPTO_RAND_GEN_H
|
||||
|
||||
#include "Sha1.h"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Crypto/Rar20Cipher.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Cipher.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Crypto/Rar20Cipher.h
|
||||
|
||||
#ifndef __CRYPTO_RAR20_CIPHER_H
|
||||
#define __CRYPTO_RAR20_CIPHER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Rar20Crypto.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
|
||||
class CDecoder:
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CData _coder;
|
||||
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,15 @@
|
||||
// Crypto/Rar20/Crypto.cpp
|
||||
// Crypto/Rar20Crypto.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Crypto.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
#include "../../../C/7zCrc.h"
|
||||
#include "../../../C/CpuArch.h"
|
||||
#include "../../../C/RotateDefs.h"
|
||||
}
|
||||
|
||||
#define rol(x,n) (((x) << (n)) | ((x) >> (8 * sizeof(x) - (n))))
|
||||
#define ror(x,n) (((x) >> (n)) | ((x) << (8 * sizeof(x) - (n))))
|
||||
#include "Rar20Crypto.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
@@ -49,10 +49,8 @@ static void Swap(Byte *b1, Byte *b2)
|
||||
*b2 = b;
|
||||
}
|
||||
|
||||
void CData::SetPassword(const Byte *password, UInt32 passwordLength)
|
||||
void CData::SetPassword(const Byte *password, UInt32 passwordLen)
|
||||
{
|
||||
// SetOldKeys(password);
|
||||
|
||||
Keys[0] = 0xD3A3B879L;
|
||||
Keys[1] = 0x3F6D12F7L;
|
||||
Keys[2] = 0x7515A235L;
|
||||
@@ -60,54 +58,40 @@ void CData::SetPassword(const Byte *password, UInt32 passwordLength)
|
||||
|
||||
Byte psw[256];
|
||||
memset(psw, 0, sizeof(psw));
|
||||
|
||||
memmove(psw, password, passwordLength);
|
||||
|
||||
memcpy(psw, password, passwordLen);
|
||||
memcpy(SubstTable, InitSubstTable, sizeof(SubstTable));
|
||||
|
||||
for (UInt32 j = 0; j < 256; j++)
|
||||
for (UInt32 i = 0; i < passwordLength; i += 2)
|
||||
for (UInt32 i = 0; i < passwordLen; i += 2)
|
||||
{
|
||||
UInt32 n2 = (Byte)g_CrcTable[(psw[i + 1] + j) & 0xFF];
|
||||
UInt32 n1 = (Byte)g_CrcTable[(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)
|
||||
for (UInt32 i = 0; i < passwordLen; i+= 16)
|
||||
EncryptBlock(&psw[i]);
|
||||
}
|
||||
|
||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
||||
{
|
||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
||||
}
|
||||
|
||||
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];
|
||||
A = GetUi32(buf + 0) ^ Keys[0];
|
||||
B = GetUi32(buf + 4) ^ Keys[1];
|
||||
C = GetUi32(buf + 8) ^ Keys[2];
|
||||
D = GetUi32(buf + 12) ^ Keys[3];
|
||||
|
||||
if (!encrypt)
|
||||
memcpy(inBuf, buf, sizeof(inBuf));
|
||||
|
||||
for(int i = 0; i < kNumRounds; i++)
|
||||
for (int i = 0; i < kNumRounds; i++)
|
||||
{
|
||||
UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
|
||||
T = ((C + rol(D, 11)) ^ key);
|
||||
T = ((C + rotlFixed(D, 11)) ^ key);
|
||||
TA = A ^ SubstLong(T);
|
||||
T = ((D ^ rol(C, 17)) + key);
|
||||
T = ((D ^ rotlFixed(C, 17)) + key);
|
||||
TB = B ^ SubstLong(T);
|
||||
A = C;
|
||||
B = D;
|
||||
@@ -115,13 +99,38 @@ void CData::CryptBlock(Byte *buf, bool encrypt)
|
||||
D = TB;
|
||||
}
|
||||
|
||||
WriteUInt32ToMemLE(C ^ Keys[0], buf + 0);
|
||||
WriteUInt32ToMemLE(D ^ Keys[1], buf + 4);
|
||||
WriteUInt32ToMemLE(A ^ Keys[2], buf + 8);
|
||||
WriteUInt32ToMemLE(B ^ Keys[3], buf + 12);
|
||||
SetUi32(buf + 0, C ^ Keys[0]);
|
||||
SetUi32(buf + 4, D ^ Keys[1]);
|
||||
SetUi32(buf + 8, A ^ Keys[2]);
|
||||
SetUi32(buf + 12, B ^ Keys[3]);
|
||||
|
||||
UpdateKeys(encrypt ? buf : inBuf);
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_cipher.SetPassword(data, size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Init()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const UInt32 kBlockSize = 16;
|
||||
|
||||
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
if (size < kBlockSize)
|
||||
return kBlockSize;
|
||||
UInt32 i;
|
||||
size -= kBlockSize;
|
||||
for (i = 0; i <= size; i += kBlockSize)
|
||||
_cipher.DecryptBlock(data + i);
|
||||
return i;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,9 +1,12 @@
|
||||
// Crypto/Rar20/Crypto.h
|
||||
// Crypto/Rar20Crypto.h
|
||||
|
||||
#ifndef __CRYPTO_RAR20_CRYPTO_H
|
||||
#define __CRYPTO_RAR20_CRYPTO_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar20 {
|
||||
@@ -12,6 +15,7 @@ class CData
|
||||
{
|
||||
Byte SubstTable[256];
|
||||
UInt32 Keys[4];
|
||||
|
||||
UInt32 SubstLong(UInt32 t)
|
||||
{
|
||||
return (UInt32)SubstTable[(int)t & 255] |
|
||||
@@ -19,13 +23,26 @@ class CData
|
||||
((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) |
|
||||
((UInt32)SubstTable[(int)(t >> 24) & 255] << 24);
|
||||
}
|
||||
|
||||
void UpdateKeys(const Byte *data);
|
||||
void CryptBlock(Byte *buf, bool encrypt);
|
||||
public:
|
||||
void EncryptBlock(Byte *buf) { CryptBlock(buf, true); }
|
||||
void DecryptBlock(Byte *buf) { CryptBlock(buf, false); }
|
||||
void SetPassword(const Byte *password, UInt32 passwordLength);
|
||||
void SetPassword(const Byte *password, UInt32 passwordLen);
|
||||
};
|
||||
|
||||
class CDecoder:
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CData _cipher;
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,10 @@
|
||||
// RarAES.cpp
|
||||
// Note: you must include Crypto/AES/MyAES.cpp to project to initialize AES tables
|
||||
// Crypto/RarAes.cpp
|
||||
// Note: you must include MyAes.cpp to project to initialize AES tables
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "RarAES.h"
|
||||
#include "../../Common/MethodId.h"
|
||||
#include "../Hash/Sha1.h"
|
||||
#include "RarAes.h"
|
||||
#include "Sha1.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar29 {
|
||||
@@ -1,20 +1,19 @@
|
||||
// RarAES.h
|
||||
// Crypto/RarAes.h
|
||||
|
||||
#ifndef __CRYPTO_RARAES_H
|
||||
#define __CRYPTO_RARAES_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#ifndef __CRYPTO_RAR_AES_H
|
||||
#define __CRYPTO_RAR_AES_H
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Aes.h"
|
||||
#include "../../../C/Aes.h"
|
||||
}
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NRar29 {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Sha1.cpp
|
||||
// Crypto/Sha1.cpp
|
||||
// This file is based on public domain
|
||||
// Steve Reid and Wei Dai's code from Crypto++
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Sha1.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/RotateDefs.h"
|
||||
#include "../../../C/RotateDefs.h"
|
||||
}
|
||||
|
||||
namespace NCrypto {
|
||||
@@ -16,7 +16,7 @@ namespace NSha1 {
|
||||
// define it for speed optimization
|
||||
// #define _SHA1_UNROLL
|
||||
|
||||
static const unsigned int kNumW =
|
||||
static const unsigned kNumW =
|
||||
#ifdef _SHA1_UNROLL
|
||||
16;
|
||||
#else
|
||||
@@ -103,9 +103,9 @@ void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnR
|
||||
// a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const
|
||||
void CContextBase::PrepareBlock(UInt32 *block, unsigned size) const
|
||||
{
|
||||
unsigned int curBufferPos = size & 0xF;
|
||||
unsigned curBufferPos = size & 0xF;
|
||||
block[curBufferPos++] = 0x80000000;
|
||||
while (curBufferPos != (16 - 2))
|
||||
block[curBufferPos++] = 0;
|
||||
@@ -117,7 +117,7 @@ void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const
|
||||
void CContext::Update(Byte *data, size_t size, bool rar350Mode)
|
||||
{
|
||||
bool returnRes = false;
|
||||
unsigned int curBufferPos = _count2;
|
||||
unsigned curBufferPos = _count2;
|
||||
while (size-- > 0)
|
||||
{
|
||||
int pos = (int)(curBufferPos & 3);
|
||||
@@ -146,7 +146,7 @@ void CContext::Update(Byte *data, size_t size, bool rar350Mode)
|
||||
void CContext::Final(Byte *digest)
|
||||
{
|
||||
const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
|
||||
unsigned int curBufferPos = _count2;
|
||||
unsigned curBufferPos = _count2;
|
||||
int pos = (int)(curBufferPos & 3);
|
||||
curBufferPos >>= 2;
|
||||
if (pos == 0)
|
||||
@@ -195,7 +195,7 @@ void CContext32::Update(const UInt32 *data, size_t size)
|
||||
void CContext32::Final(UInt32 *digest)
|
||||
{
|
||||
const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
|
||||
unsigned int curBufferPos = _count2;
|
||||
unsigned curBufferPos = _count2;
|
||||
_buffer[curBufferPos++] = 0x80000000;
|
||||
while (curBufferPos != (16 - 2))
|
||||
{
|
||||
@@ -1,12 +1,12 @@
|
||||
// Sha1.h
|
||||
// Crypto/Sha1.h
|
||||
// This file is based on public domain
|
||||
// Steve Reid and Wei Dai's code from Crypto++
|
||||
|
||||
#ifndef __SHA1_H
|
||||
#define __SHA1_H
|
||||
#ifndef __CRYPTO_SHA1_H
|
||||
#define __CRYPTO_SHA1_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../../../Common/Types.h"
|
||||
#include "../../Common/Types.h"
|
||||
|
||||
// Sha1 implementation in RAR before version 3.60 has bug:
|
||||
// it changes data bytes in some cases.
|
||||
@@ -15,11 +15,11 @@
|
||||
namespace NCrypto {
|
||||
namespace NSha1 {
|
||||
|
||||
const unsigned int kBlockSize = 64;
|
||||
const unsigned int kDigestSize = 20;
|
||||
const unsigned kBlockSize = 64;
|
||||
const unsigned kDigestSize = 20;
|
||||
|
||||
const unsigned int kBlockSizeInWords = (kBlockSize >> 2);
|
||||
const unsigned int kDigestSizeInWords = (kDigestSize >> 2);
|
||||
const unsigned kBlockSizeInWords = (kBlockSize >> 2);
|
||||
const unsigned kDigestSizeInWords = (kDigestSize >> 2);
|
||||
|
||||
class CContextBase
|
||||
{
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
class CContextBase2: public CContextBase
|
||||
{
|
||||
protected:
|
||||
unsigned int _count2;
|
||||
unsigned _count2;
|
||||
UInt32 _buffer[kBlockSizeInWords];
|
||||
void UpdateBlock() { CContextBase::UpdateBlock(_buffer); }
|
||||
public:
|
||||
@@ -3,6 +3,6 @@
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
#include "../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,26 +1,25 @@
|
||||
// WzAES.cpp
|
||||
// Crypto/WzAes.cpp
|
||||
/*
|
||||
This code implements Brian Gladman's scheme
|
||||
specified in password Based File Encryption Utility.
|
||||
|
||||
Note: you must include Crypto/AES/MyAES.cpp to project to initialize AES tables
|
||||
Note: you must include MyAes.cpp to project to initialize AES tables
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
#include "../Hash/Pbkdf2HmacSha1.h"
|
||||
#include "../Hash/RandGen.h"
|
||||
#include "../Common/StreamObjects.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
#include "WzAES.h"
|
||||
#include "Pbkdf2HmacSha1.h"
|
||||
#include "RandGen.h"
|
||||
#include "WzAes.h"
|
||||
|
||||
// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1
|
||||
// #define _NO_WZAES_OPTIMIZATIONS
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NWzAES {
|
||||
namespace NWzAes {
|
||||
|
||||
const unsigned int kAesKeySizeMax = 32;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// WzAES.h
|
||||
// Crypto/WzAes.h
|
||||
/*
|
||||
This code implements Brian Gladman's scheme
|
||||
specified in password Based File Encryption Utility:
|
||||
@@ -12,22 +12,22 @@ specified in password Based File Encryption Utility:
|
||||
#ifndef __CRYPTO_WZ_AES_H
|
||||
#define __CRYPTO_WZ_AES_H
|
||||
|
||||
#include "../Hash/HmacSha1.h"
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/MyVector.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Aes.h"
|
||||
#include "../../../C/Aes.h"
|
||||
}
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/MyVector.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
#include "HmacSha1.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NWzAES {
|
||||
namespace NWzAes {
|
||||
|
||||
const unsigned int kSaltSizeMax = 16;
|
||||
const unsigned int kMacSize = 10;
|
||||
@@ -1,8 +0,0 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
// Crypto/ZipCrypto.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipCipher.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
void CCipher::UpdateKeys(Byte b)
|
||||
{
|
||||
Keys[0] = CRC_UPDATE_BYTE(Keys[0], b);
|
||||
Keys[1] += Keys[0] & 0xff;
|
||||
Keys[1] = Keys[1] * 134775813L + 1;
|
||||
Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24));
|
||||
}
|
||||
|
||||
void CCipher::SetPassword(const Byte *password, UInt32 passwordLength)
|
||||
{
|
||||
Keys[0] = 305419896L;
|
||||
Keys[1] = 591751049L;
|
||||
Keys[2] = 878082192L;
|
||||
for (UInt32 i = 0; i < passwordLength; i++)
|
||||
UpdateKeys(password[i]);
|
||||
}
|
||||
|
||||
Byte CCipher::DecryptByteSpec()
|
||||
{
|
||||
UInt32 temp = Keys[2] | 2;
|
||||
return (Byte)((temp * (temp ^ 1)) >> 8);
|
||||
}
|
||||
|
||||
Byte CCipher::DecryptByte(Byte encryptedByte)
|
||||
{
|
||||
Byte c = (Byte)(encryptedByte ^ DecryptByteSpec());
|
||||
UpdateKeys(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
Byte CCipher::EncryptByte(Byte b)
|
||||
{
|
||||
Byte c = (Byte)(b ^ DecryptByteSpec());
|
||||
UpdateKeys(b);
|
||||
return c;
|
||||
}
|
||||
|
||||
void CCipher::DecryptHeader(Byte *buffer)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
buffer[i] = DecryptByte(buffer[i]);
|
||||
}
|
||||
|
||||
void CCipher::EncryptHeader(Byte *buffer)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
buffer[i] = EncryptByte(buffer[i]);
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Crypto/ZipCrypto.h
|
||||
|
||||
#ifndef __CRYPTO_ZIP_CRYPTO_H
|
||||
#define __CRYPTO_ZIP_CRYPTO_H
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
const int kHeaderSize = 12;
|
||||
class CCipher
|
||||
{
|
||||
UInt32 Keys[3];
|
||||
void UpdateKeys(Byte b);
|
||||
Byte DecryptByteSpec();
|
||||
public:
|
||||
void SetPassword(const Byte *password, UInt32 passwordLength);
|
||||
Byte DecryptByte(Byte encryptedByte);
|
||||
Byte EncryptByte(Byte b);
|
||||
void DecryptHeader(Byte *buffer);
|
||||
void EncryptHeader(Byte *buffer);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,16 +1,69 @@
|
||||
// Crypto/ZipCipher.h
|
||||
// Crypto/ZipCrypto.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipCipher.h"
|
||||
#include "Windows/Defs.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
#include "../Hash/RandGen.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
#include "RandGen.h"
|
||||
#include "ZipCrypto.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
void CCipher::UpdateKeys(Byte b)
|
||||
{
|
||||
Keys[0] = CRC_UPDATE_BYTE(Keys[0], b);
|
||||
Keys[1] += Keys[0] & 0xff;
|
||||
Keys[1] = Keys[1] * 134775813L + 1;
|
||||
Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24));
|
||||
}
|
||||
|
||||
void CCipher::SetPassword(const Byte *password, UInt32 passwordLen)
|
||||
{
|
||||
Keys[0] = 305419896L;
|
||||
Keys[1] = 591751049L;
|
||||
Keys[2] = 878082192L;
|
||||
for (UInt32 i = 0; i < passwordLen; i++)
|
||||
UpdateKeys(password[i]);
|
||||
}
|
||||
|
||||
Byte CCipher::DecryptByteSpec()
|
||||
{
|
||||
UInt32 temp = Keys[2] | 2;
|
||||
return (Byte)((temp * (temp ^ 1)) >> 8);
|
||||
}
|
||||
|
||||
Byte CCipher::DecryptByte(Byte b)
|
||||
{
|
||||
Byte c = (Byte)(b ^ DecryptByteSpec());
|
||||
UpdateKeys(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
Byte CCipher::EncryptByte(Byte b)
|
||||
{
|
||||
Byte c = (Byte)(b ^ DecryptByteSpec());
|
||||
UpdateKeys(b);
|
||||
return c;
|
||||
}
|
||||
|
||||
void CCipher::DecryptHeader(Byte *buf)
|
||||
{
|
||||
for (unsigned i = 0; i < kHeaderSize; i++)
|
||||
buf[i] = DecryptByte(buf[i]);
|
||||
}
|
||||
|
||||
void CCipher::EncryptHeader(Byte *buf)
|
||||
{
|
||||
for (unsigned i = 0; i < kHeaderSize; i++)
|
||||
buf[i] = EncryptByte(buf[i]);
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
||||
{
|
||||
_cipher.SetPassword(data, size);
|
||||
@@ -1,19 +1,32 @@
|
||||
// Crypto/ZipCipher.h
|
||||
// Crypto/ZipCrypto.h
|
||||
|
||||
#ifndef __CRYPTO_ZIPCIPHER_H
|
||||
#define __CRYPTO_ZIPCIPHER_H
|
||||
#ifndef __CRYPTO_ZIP_CRYPTO_H
|
||||
#define __CRYPTO_ZIP_CRYPTO_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "ZipCrypto.h"
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZip {
|
||||
|
||||
const unsigned kHeaderSize = 12;
|
||||
|
||||
class CCipher
|
||||
{
|
||||
UInt32 Keys[3];
|
||||
|
||||
void UpdateKeys(Byte b);
|
||||
Byte DecryptByteSpec();
|
||||
public:
|
||||
void SetPassword(const Byte *password, UInt32 passwordLen);
|
||||
Byte DecryptByte(Byte b);
|
||||
Byte EncryptByte(Byte b);
|
||||
void DecryptHeader(Byte *buf);
|
||||
void EncryptHeader(Byte *buf);
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
@@ -40,20 +53,19 @@ class CDecoder:
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
// public CBuffer2
|
||||
{
|
||||
CCipher _cipher;
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
|
||||
HRESULT ReadHeader(ISequentialInStream *inStream);
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
180
CPP/7zip/Crypto/ZipStrong.cpp
Executable file
180
CPP/7zip/Crypto/ZipStrong.cpp
Executable file
@@ -0,0 +1,180 @@
|
||||
// Crypto/ZipStrong.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
STDMETHODIMP CBaseCoder::Init()
|
||||
{
|
||||
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);
|
||||
if (_remSize > _buf.GetCapacity())
|
||||
{
|
||||
_buf.Free();
|
||||
_buf.SetCapacity(_remSize);
|
||||
}
|
||||
return ReadStream_FALSE(inStream, _buf, _remSize);
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CheckPassword(bool &passwOK)
|
||||
{
|
||||
passwOK = false;
|
||||
if (_remSize < 10)
|
||||
return E_NOTIMPL;
|
||||
Byte *p = _buf;
|
||||
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;
|
||||
UInt32 rdSize = GetUi16(p + 8);
|
||||
UInt32 pos = 10;
|
||||
Byte *rd = p + pos;
|
||||
pos += rdSize;
|
||||
if (pos + 4 > _remSize)
|
||||
return E_NOTIMPL;
|
||||
UInt32 reserved = GetUi32(p + pos);
|
||||
pos += 4;
|
||||
if (reserved != 0)
|
||||
return E_NOTIMPL;
|
||||
if (pos + 2 > _remSize)
|
||||
return E_NOTIMPL;
|
||||
UInt32 validSize = GetUi16(p + pos);
|
||||
pos += 2;
|
||||
Byte *validData = p + pos;
|
||||
if (pos + validSize != _remSize)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (!_aesFilter)
|
||||
_aesFilter = new CAesCbcDecoder;
|
||||
|
||||
CMyComPtr<ICryptoProperties> cp;
|
||||
RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
|
||||
{
|
||||
RINOK(cp->SetKey(_key.MasterKey, _key.KeySize));
|
||||
RINOK(cp->SetInitVector(_iv, 16));
|
||||
_aesFilter->Init();
|
||||
if (_aesFilter->Filter(rd, rdSize) != rdSize)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
Byte fileKey[32];
|
||||
NSha1::CContext sha;
|
||||
sha.Init();
|
||||
sha.Update(_iv, 16);
|
||||
sha.Update(rd, rdSize - 16); // we don't use last 16 bytes (PAD bytes)
|
||||
DeriveKey(sha, fileKey);
|
||||
|
||||
RINOK(cp->SetKey(fileKey, _key.KeySize));
|
||||
RINOK(cp->SetInitVector(_iv, 16));
|
||||
_aesFilter->Init();
|
||||
if (_aesFilter->Filter(validData, validSize) != validSize)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (validSize < 4)
|
||||
return E_NOTIMPL;
|
||||
validSize -= 4;
|
||||
if (GetUi32(validData + validSize) != CrcCalc(validData, validSize))
|
||||
return S_OK;
|
||||
passwOK = true;
|
||||
_aesFilter->Init();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
return _aesFilter->Filter(data, size);
|
||||
}
|
||||
|
||||
}}
|
||||
53
CPP/7zip/Crypto/ZipStrong.h
Executable file
53
CPP/7zip/Crypto/ZipStrong.h
Executable file
@@ -0,0 +1,53 @@
|
||||
// Crypto/ZipStrong.h
|
||||
|
||||
#ifndef __CRYPTO_ZIP_STRONG_H
|
||||
#define __CRYPTO_ZIP_STRONG_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
namespace NCrypto {
|
||||
namespace NZipStrong {
|
||||
|
||||
struct CKeyInfo
|
||||
{
|
||||
Byte MasterKey[32];
|
||||
UInt32 KeySize;
|
||||
void SetPassword(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
class CBaseCoder:
|
||||
public ICompressFilter,
|
||||
public ICryptoSetPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
protected:
|
||||
CKeyInfo _key;
|
||||
CMyComPtr<ICompressFilter> _aesFilter;
|
||||
CByteBuffer _buf;
|
||||
public:
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0;
|
||||
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
class CDecoder:
|
||||
public CBaseCoder
|
||||
{
|
||||
UInt32 _ivSize;
|
||||
Byte _iv[16];
|
||||
UInt32 _remSize;
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize);
|
||||
HRESULT CheckPassword(bool &passwOK);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
DIRS = \
|
||||
7zAES\~ \
|
||||
|
||||
all: $(DIRS)
|
||||
|
||||
$(DIRS):
|
||||
!include "../SubBuild.mak"
|
||||
Reference in New Issue
Block a user