This commit is contained in:
Igor Pavlov
2021-07-22 23:00:14 +01:00
committed by Kornel
parent 4a960640a3
commit 585698650f
619 changed files with 34904 additions and 10859 deletions

View File

@@ -2,9 +2,11 @@
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../../C/Sha256.h"
#include "../../Common/ComTry.h"
#include "../../Common/MyBuffer2.h"
#ifndef _7ZIP_ST
#include "../../Windows/Synchronization.h"
@@ -48,31 +50,65 @@ void CKeyInfo::CalcKey()
}
else
{
size_t bufSize = 8 + SaltSize + Password.Size();
CObjArray<Byte> buf(bufSize);
const unsigned kUnrPow = 6;
const UInt32 numUnroll = (UInt32)1 << (NumCyclesPower <= kUnrPow ? (unsigned)NumCyclesPower : kUnrPow);
const size_t bufSize = 8 + SaltSize + Password.Size();
const size_t unrollSize = bufSize * numUnroll;
// MY_ALIGN (16)
// CSha256 sha;
CAlignedBuffer sha(sizeof(CSha256) + unrollSize + bufSize * 2);
Byte *buf = sha + sizeof(CSha256);
memcpy(buf, Salt, SaltSize);
memcpy(buf + SaltSize, Password, Password.Size());
memset(buf + bufSize - 8, 0, 8);
CSha256 sha;
Sha256_Init(&sha);
Byte *ctr = buf + SaltSize + Password.Size();
for (unsigned i = 0; i < 8; i++)
ctr[i] = 0;
Sha256_Init((CSha256 *)(void *)(Byte *)sha);
{
{
Byte *dest = buf;
for (UInt32 i = 1; i < numUnroll; i++)
{
dest += bufSize;
memcpy(dest, buf, bufSize);
}
}
const UInt32 numRounds = (UInt32)1 << NumCyclesPower;
UInt32 r = 0;
do
{
Byte *dest = buf + bufSize - 8;
UInt32 i = r;
r += numUnroll;
do
{
SetUi32(dest, i); i++; dest += bufSize;
// SetUi32(dest, i); i++; dest += bufSize;
}
while (i < r);
Sha256_Update((CSha256 *)(void *)(Byte *)sha, buf, unrollSize);
}
while (r < numRounds);
}
/*
UInt64 numRounds = (UInt64)1 << NumCyclesPower;
do
{
Sha256_Update(&sha, buf, bufSize);
Sha256_Update((CSha256 *)(Byte *)sha, buf, bufSize);
for (unsigned i = 0; i < 8; i++)
if (++(ctr[i]) != 0)
break;
}
while (--numRounds != 0);
*/
Sha256_Final(&sha, Key);
Sha256_Final((CSha256 *)(void *)(Byte *)sha, Key);
memset(sha, 0, sha.Size());
}
}
@@ -250,6 +286,7 @@ STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
{
COM_TRY_BEGIN
_key.Password.Wipe();
_key.Password.CopyFrom(data, (size_t)size);
return S_OK;

View File

@@ -37,6 +37,17 @@ public:
for (unsigned i = 0; i < sizeof(Salt); i++)
Salt[i] = 0;
}
void Wipe()
{
Password.Wipe();
NumCyclesPower = 0;
SaltSize = 0;
MY_memset_0_ARRAY(Salt);
MY_memset_0_ARRAY(Key);
}
~CKeyInfo() { Wipe(); }
};
class CKeyInfoCache

View File

@@ -9,9 +9,9 @@
namespace NCrypto {
namespace N7z {
REGISTER_FILTER_E(7zAES,
CDecoder(),
CEncoder(),
REGISTER_FILTER_E(_7zAES,
CDecoder,
CEncoder,
0x6F10701, "7zAES")
}}

View File

@@ -11,110 +11,82 @@ namespace NSha1 {
void CHmac::SetKey(const Byte *key, size_t keySize)
{
Byte keyTemp[kBlockSize];
MY_ALIGN (16)
UInt32 temp[SHA1_NUM_BLOCK_WORDS];
size_t i;
for (i = 0; i < kBlockSize; i++)
keyTemp[i] = 0;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
temp[i] = 0;
if (keySize > kBlockSize)
{
_sha.Init();
_sha.Update(key, keySize);
_sha.Final(keyTemp);
_sha.Final((Byte *)temp);
}
else
for (i = 0; i < keySize; i++)
keyTemp[i] = key[i];
memcpy(temp, key, keySize);
for (i = 0; i < kBlockSize; i++)
keyTemp[i] ^= 0x36;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
temp[i] ^= 0x36363636;
_sha.Init();
_sha.Update(keyTemp, kBlockSize);
_sha.Update((const Byte *)temp, kBlockSize);
for (i = 0; i < kBlockSize; i++)
keyTemp[i] ^= 0x36 ^ 0x5C;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
temp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
_sha2.Init();
_sha2.Update(keyTemp, kBlockSize);
}
void CHmac::Final(Byte *mac, size_t macSize)
{
Byte digest[kDigestSize];
_sha.Final(digest);
_sha2.Update(digest, kDigestSize);
_sha2.Final(digest);
for (size_t i = 0; i < macSize; i++)
mac[i] = digest[i];
_sha2.Update((const Byte *)temp, kBlockSize);
}
void CHmac32::SetKey(const Byte *key, size_t keySize)
void CHmac::Final(Byte *mac)
{
UInt32 keyTemp[kNumBlockWords];
size_t i;
for (i = 0; i < kNumBlockWords; i++)
keyTemp[i] = 0;
if (keySize > kBlockSize)
{
CContext sha;
sha.Init();
sha.Update(key, keySize);
Byte digest[kDigestSize];
sha.Final(digest);
for (i = 0 ; i < kNumDigestWords; i++)
keyTemp[i] = GetBe32(digest + i * 4 + 0);
}
else
for (i = 0; i < keySize; i++)
keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3)));
for (i = 0; i < kNumBlockWords; i++)
keyTemp[i] ^= 0x36363636;
_sha.Init();
_sha.Update(keyTemp, kNumBlockWords);
for (i = 0; i < kNumBlockWords; i++)
keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
_sha2.Init();
_sha2.Update(keyTemp, kNumBlockWords);
_sha.Final(mac);
_sha2.Update(mac, kDigestSize);
_sha2.Final(mac);
}
void CHmac32::Final(UInt32 *mac, size_t macSize)
{
UInt32 digest[kNumDigestWords];
_sha.Final(digest);
_sha2.Update(digest, kNumDigestWords);
_sha2.Final(digest);
for (size_t i = 0; i < macSize; i++)
mac[i] = digest[i];
}
void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration)
void CHmac::GetLoopXorDigest1(void *mac, UInt32 numIteration)
{
UInt32 block[kNumBlockWords];
UInt32 block2[kNumBlockWords];
MY_ALIGN (16) UInt32 block [SHA1_NUM_BLOCK_WORDS];
MY_ALIGN (16) UInt32 block2[SHA1_NUM_BLOCK_WORDS];
MY_ALIGN (16) UInt32 mac2 [SHA1_NUM_BLOCK_WORDS];
_sha.PrepareBlock(block, kNumDigestWords);
_sha2.PrepareBlock(block2, kNumDigestWords);
_sha. PrepareBlock((Byte *)block, SHA1_DIGEST_SIZE);
_sha2.PrepareBlock((Byte *)block2, SHA1_DIGEST_SIZE);
block[0] = ((const UInt32 *)mac)[0];
block[1] = ((const UInt32 *)mac)[1];
block[2] = ((const UInt32 *)mac)[2];
block[3] = ((const UInt32 *)mac)[3];
block[4] = ((const UInt32 *)mac)[4];
mac2[0] = block[0];
mac2[1] = block[1];
mac2[2] = block[2];
mac2[3] = block[3];
mac2[4] = block[4];
for (unsigned s = 0; s < kNumDigestWords; s++)
block[s] = mac[s];
for (UInt32 i = 0; i < numIteration; i++)
{
_sha.GetBlockDigest(block, block2);
_sha2.GetBlockDigest(block2, block);
for (unsigned s = 0; s < kNumDigestWords; s++)
mac[s] ^= block[s];
_sha. GetBlockDigest((const Byte *)block, (Byte *)block2);
_sha2.GetBlockDigest((const Byte *)block2, (Byte *)block);
mac2[0] ^= block[0];
mac2[1] ^= block[1];
mac2[2] ^= block[2];
mac2[3] ^= block[3];
mac2[4] ^= block[4];
}
((UInt32 *)mac)[0] = mac2[0];
((UInt32 *)mac)[1] = mac2[1];
((UInt32 *)mac)[2] = mac2[2];
((UInt32 *)mac)[3] = mac2[3];
((UInt32 *)mac)[4] = mac2[4];
}
}}

View File

@@ -9,7 +9,7 @@
namespace NCrypto {
namespace NSha1 {
// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize);
// Use: SetKey(key, keySize); for () Update(data, size); FinalFull(mac);
class CHmac
{
@@ -18,20 +18,12 @@ class CHmac
public:
void SetKey(const Byte *key, size_t keySize);
void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); }
void Final(Byte *mac, size_t macSize = kDigestSize);
};
class CHmac32
{
CContext32 _sha;
CContext32 _sha2;
public:
void SetKey(const Byte *key, size_t keySize);
void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); }
void Final(UInt32 *mac, size_t macSize = kNumDigestWords);
// It'sa for hmac function. in,out: mac[kNumDigestWords].
void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration);
// Final() : mac is recommended to be aligned for 4 bytes
// GetLoopXorDigest1() : mac is required to be aligned for 4 bytes
// The caller can use: UInt32 mac[NSha1::kNumDigestWords] and typecast to (Byte *) and (void *);
void Final(Byte *mac);
void GetLoopXorDigest1(void *mac, UInt32 numIteration);
};
}}

View File

@@ -9,39 +9,38 @@
namespace NCrypto {
namespace NSha256 {
static const unsigned kBlockSize = 64;
void CHmac::SetKey(const Byte *key, size_t keySize)
{
Byte temp[kBlockSize];
MY_ALIGN (16)
UInt32 temp[SHA256_NUM_BLOCK_WORDS];
size_t i;
for (i = 0; i < kBlockSize; i++)
for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++)
temp[i] = 0;
if (keySize > kBlockSize)
{
Sha256_Init(&_sha);
Sha256_Update(&_sha, key, keySize);
Sha256_Final(&_sha, temp);
Sha256_Final(&_sha, (Byte *)temp);
}
else
for (i = 0; i < keySize; i++)
temp[i] = key[i];
memcpy(temp, key, keySize);
for (i = 0; i < kBlockSize; i++)
temp[i] ^= 0x36;
for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++)
temp[i] ^= 0x36363636;
Sha256_Init(&_sha);
Sha256_Update(&_sha, temp, kBlockSize);
Sha256_Update(&_sha, (const Byte *)temp, kBlockSize);
for (i = 0; i < kBlockSize; i++)
temp[i] ^= 0x36 ^ 0x5C;
for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++)
temp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
Sha256_Init(&_sha2);
Sha256_Update(&_sha2, temp, kBlockSize);
Sha256_Update(&_sha2, (const Byte *)temp, kBlockSize);
}
void CHmac::Final(Byte *mac)
{
Sha256_Final(&_sha, mac);
@@ -49,14 +48,4 @@ void CHmac::Final(Byte *mac)
Sha256_Final(&_sha2, mac);
}
/*
void CHmac::Final(Byte *mac, size_t macSize)
{
Byte digest[SHA256_DIGEST_SIZE];
Final(digest);
for (size_t i = 0; i < macSize; i++)
mac[i] = digest[i];
}
*/
}}

View File

@@ -9,6 +9,7 @@
namespace NCrypto {
namespace NSha256 {
const unsigned kBlockSize = SHA256_BLOCK_SIZE;
const unsigned kDigestSize = SHA256_DIGEST_SIZE;
class CHmac
@@ -19,7 +20,6 @@ public:
void SetKey(const Byte *key, size_t keySize);
void Update(const Byte *data, size_t dataSize) { Sha256_Update(&_sha, data, dataSize); }
void Final(Byte *mac);
// void Final(Byte *mac, size_t macSize);
};
}}

View File

@@ -10,91 +10,179 @@ namespace NCrypto {
static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit;
CAesCbcCoder::CAesCbcCoder(bool encodeMode, unsigned keySize):
CAesCoder::CAesCoder(bool encodeMode, unsigned keySize, bool ctrMode):
_keySize(keySize),
_keyIsSet(false),
_encodeMode(encodeMode)
_encodeMode(encodeMode),
_ctrMode(ctrMode),
_aes(AES_NUM_IVMRK_WORDS * 4 + AES_BLOCK_SIZE * 2)
{
_offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32);
// _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32);
memset(_iv, 0, AES_BLOCK_SIZE);
/*
// we can use the following code to test 32-bit overflow case for AES-CTR
for (unsigned i = 0; i < 16; i++) _iv[i] = (Byte)(i + 1);
_iv[0] = 0xFE; _iv[1] = _iv[2] = _iv[3] = 0xFF;
*/
SetFunctions(0);
}
STDMETHODIMP CAesCbcCoder::Init()
STDMETHODIMP CAesCoder::Init()
{
AesCbc_Init(_aes + _offset, _iv);
return _keyIsSet ? S_OK : E_FAIL;
AesCbc_Init(Aes(), _iv);
return _keyIsSet ? S_OK : E_NOTIMPL; // E_FAIL
}
STDMETHODIMP_(UInt32) CAesCbcCoder::Filter(Byte *data, UInt32 size)
STDMETHODIMP_(UInt32) CAesCoder::Filter(Byte *data, UInt32 size)
{
if (!_keyIsSet)
return 0;
if (size == 0)
return 0;
if (size < AES_BLOCK_SIZE)
{
#ifndef _SFX
if (_ctrMode)
{
// use that code only for last block !!!
Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS);
memset(ctr, 0, AES_BLOCK_SIZE);
memcpy(ctr, data, size);
_codeFunc(Aes(), ctr, 1);
memcpy(data, ctr, size);
return size;
}
#endif
return AES_BLOCK_SIZE;
}
size >>= 4;
_codeFunc(_aes + _offset, data, size);
_codeFunc(Aes(), data, size);
return size << 4;
}
STDMETHODIMP CAesCbcCoder::SetKey(const Byte *data, UInt32 size)
STDMETHODIMP CAesCoder::SetKey(const Byte *data, UInt32 size)
{
if ((size & 0x7) != 0 || size < 16 || size > 32)
return E_INVALIDARG;
if (_keySize != 0 && size != _keySize)
return E_INVALIDARG;
AES_SET_KEY_FUNC setKeyFunc = _encodeMode ? Aes_SetKey_Enc : Aes_SetKey_Dec;
setKeyFunc(_aes + _offset + 4, data, size);
AES_SET_KEY_FUNC setKeyFunc = (_ctrMode | _encodeMode) ? Aes_SetKey_Enc : Aes_SetKey_Dec;
setKeyFunc(Aes() + 4, data, size);
_keyIsSet = true;
return S_OK;
}
STDMETHODIMP CAesCbcCoder::SetInitVector(const Byte *data, UInt32 size)
STDMETHODIMP CAesCoder::SetInitVector(const Byte *data, UInt32 size)
{
if (size != AES_BLOCK_SIZE)
return E_INVALIDARG;
memcpy(_iv, data, size);
CAesCbcCoder::Init(); // don't call virtual function here !!!
CAesCoder::Init(); // don't call virtual function here !!!
return S_OK;
}
EXTERN_C_BEGIN
#ifndef _SFX
void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
#ifdef MY_CPU_X86_OR_AMD64
#define USE_HW_AES
#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE)
#if defined(__clang__)
#if (__clang_major__ >= 8) // fix that check
#define USE_HW_AES
#endif
#elif defined(__GNUC__)
#if (__GNUC__ >= 6) // fix that check
#define USE_HW_AES
#endif
#elif defined(_MSC_VER)
#if _MSC_VER >= 1910
#define USE_HW_AES
#endif
#endif
#endif
void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
#endif
EXTERN_C_END
bool CAesCbcCoder::SetFunctions(UInt32 algo)
bool CAesCoder::SetFunctions(UInt32
#ifndef _SFX
algo
#endif
)
{
_codeFunc = _encodeMode ?
g_AesCbc_Encode :
g_AesCbc_Decode;
_codeFunc = g_AesCbc_Decode;
#ifdef _SFX
return true;
#else
if (_ctrMode)
_codeFunc = g_AesCtr_Code;
else if (_encodeMode)
_codeFunc = g_AesCbc_Encode;
if (algo < 1)
return true;
if (algo == 1)
{
_codeFunc = _encodeMode ?
AesCbc_Encode:
AesCbc_Decode;
}
if (algo == 2)
{
#ifdef MY_CPU_X86_OR_AMD64
if (g_AesCbc_Encode != AesCbc_Encode_Intel)
_codeFunc = AesCbc_Decode;
#ifndef _SFX
if (_ctrMode)
_codeFunc = AesCtr_Code;
else if (_encodeMode)
_codeFunc = AesCbc_Encode;
#endif
return false;
return true;
}
return true;
#ifdef USE_HW_AES
// if (CPU_IsSupported_AES())
{
if (algo == 2)
if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW)
{
_codeFunc = AesCbc_Decode_HW;
#ifndef _SFX
if (_ctrMode)
_codeFunc = AesCtr_Code_HW;
else if (_encodeMode)
_codeFunc = AesCbc_Encode_HW;
#endif
return true;
}
#if defined(MY_CPU_X86_OR_AMD64)
if (algo == 3)
if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256)
{
_codeFunc = AesCbc_Decode_HW_256;
#ifndef _SFX
if (_ctrMode)
_codeFunc = AesCtr_Code_HW_256;
else if (_encodeMode)
_codeFunc = AesCbc_Encode_HW;
#endif
return true;
}
#endif
}
#endif
return false;
#endif
}
STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
#ifndef _SFX
STDMETHODIMP CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
UInt32 algo = 0;
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
@@ -102,11 +190,16 @@ STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPV
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
if (!SetFunctions(prop.ulVal))
if (prop.ulVal > 3)
return E_NOTIMPL;
algo = prop.ulVal;
}
}
if (!SetFunctions(algo))
return E_NOTIMPL;
return S_OK;
}
#endif
}

View File

@@ -5,51 +5,73 @@
#include "../../../C/Aes.h"
#include "../../Common/MyBuffer2.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
namespace NCrypto {
class CAesCbcCoder:
class CAesCoder:
public ICompressFilter,
public ICryptoProperties,
#ifndef _SFX
public ICompressSetCoderProperties,
#endif
public CMyUnknownImp
{
AES_CODE_FUNC _codeFunc;
unsigned _offset;
// unsigned _offset;
unsigned _keySize;
bool _keyIsSet;
bool _encodeMode;
UInt32 _aes[AES_NUM_IVMRK_WORDS + 3];
bool _ctrMode;
// UInt32 _aes[AES_NUM_IVMRK_WORDS + 3];
CAlignedBuffer _aes;
Byte _iv[AES_BLOCK_SIZE];
// UInt32 *Aes() { return _aes + _offset; }
UInt32 *Aes() { return (UInt32 *)(void *)(Byte *)_aes; }
bool SetFunctions(UInt32 algo);
public:
CAesCbcCoder(bool encodeMode, unsigned keySize);
CAesCoder(bool encodeMode, unsigned keySize, bool ctrMode);
virtual ~CAesCbcCoder() {}; // we need virtual destructor for derived classes
virtual ~CAesCoder() {}; // we need virtual destructor for derived classes
MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
MY_QUERYINTERFACE_BEGIN2(ICompressFilter)
MY_QUERYINTERFACE_ENTRY(ICryptoProperties)
#ifndef _SFX
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_ICompressFilter(;)
void SetKeySize(unsigned size) { _keySize = size; }
STDMETHOD(SetKey)(const Byte *data, UInt32 size);
STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
#ifndef _SFX
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
#endif
};
struct CAesCbcEncoder: public CAesCbcCoder
#ifndef _SFX
struct CAesCbcEncoder: public CAesCoder
{
CAesCbcEncoder(unsigned keySize = 0): CAesCbcCoder(true, keySize) {}
CAesCbcEncoder(unsigned keySize = 0): CAesCoder(true, keySize, false) {}
};
#endif
struct CAesCbcDecoder: public CAesCbcCoder
struct CAesCbcDecoder: public CAesCoder
{
CAesCbcDecoder(unsigned keySize = 0): CAesCbcCoder(false, keySize) {}
CAesCbcDecoder(unsigned keySize = 0): CAesCoder(false, keySize, false) {}
};
}

View File

@@ -8,9 +8,23 @@
namespace NCrypto {
REGISTER_FILTER_E(AES256CBC,
CAesCbcDecoder(32),
CAesCbcEncoder(32),
0x6F00181, "AES256CBC")
#ifndef _SFX
#define REGISTER_AES_2(name, nameString, keySize, isCtr) \
REGISTER_FILTER_E(name, \
CAesCoder(false, keySize, isCtr), \
CAesCoder(true , keySize, isCtr), \
0x6F00100 | ((keySize - 16) * 8) | (isCtr ? 4 : 1), \
nameString) \
#define REGISTER_AES(name, nameString, isCtr) \
/* REGISTER_AES_2(AES128 ## name, "AES128" nameString, 16, isCtr) */ \
/* REGISTER_AES_2(AES192 ## name, "AES192" nameString, 24, isCtr) */ \
REGISTER_AES_2(AES256 ## name, "AES256" nameString, 32, isCtr) \
REGISTER_AES(CBC, "CBC", false)
// REGISTER_AES(CTR, "CTR", true)
#endif
}

View File

@@ -5,6 +5,7 @@
#include "../../../C/CpuArch.h"
#include "HmacSha1.h"
#include "Pbkdf2HmacSha1.h"
namespace NCrypto {
namespace NSha1 {
@@ -14,81 +15,29 @@ void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize,
UInt32 numIterations,
Byte *key, size_t keySize)
{
MY_ALIGN (16)
CHmac baseCtx;
baseCtx.SetKey(pwd, pwdSize);
for (UInt32 i = 1; keySize != 0; i++)
{
CHmac ctx = baseCtx;
MY_ALIGN (16)
CHmac ctx;
ctx = baseCtx;
ctx.Update(salt, saltSize);
Byte u[kDigestSize];
MY_ALIGN (16)
UInt32 u[kNumDigestWords];
SetBe32(u, i);
ctx.Update(u, 4);
ctx.Final(u, kDigestSize);
ctx.Update((const Byte *)u, 4);
ctx.Final((Byte *)u);
const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize;
unsigned s;
for (s = 0; s < curSize; s++)
key[s] = u[s];
for (UInt32 j = numIterations; j > 1; j--)
{
ctx = baseCtx;
ctx.Update(u, kDigestSize);
ctx.Final(u, kDigestSize);
for (s = 0; s < curSize; s++)
key[s] ^= u[s];
}
key += curSize;
keySize -= curSize;
}
}
void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize,
const UInt32 *salt, size_t saltSize,
UInt32 numIterations,
UInt32 *key, size_t keySize)
{
CHmac32 baseCtx;
baseCtx.SetKey(pwd, pwdSize);
for (UInt32 i = 1; keySize != 0; i++)
{
CHmac32 ctx = baseCtx;
ctx.Update(salt, saltSize);
UInt32 u[kNumDigestWords];
u[0] = i;
ctx.Update(u, 1);
ctx.Final(u, kNumDigestWords);
// Speed-optimized code start
ctx = baseCtx;
ctx.GetLoopXorDigest(u, numIterations - 1);
// Speed-optimized code end
const unsigned curSize = (keySize < kNumDigestWords) ? (unsigned)keySize : kNumDigestWords;
unsigned s;
for (s = 0; s < curSize; s++)
key[s] = u[s];
/*
// Default code start
for (UInt32 j = numIterations; j > 1; j--)
{
ctx = baseCtx;
ctx.Update(u, kNumDigestWords);
ctx.Final(u, kNumDigestWords);
for (s = 0; s < curSize; s++)
key[s] ^= u[s];
}
// Default code end
*/
ctx.GetLoopXorDigest1((void *)u, numIterations - 1);
const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize;;
memcpy(key, (const Byte *)u, curSize);
key += curSize;
keySize -= curSize;
}

View File

@@ -14,9 +14,6 @@ namespace NSha1 {
void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
UInt32 numIterations, Byte *key, size_t keySize);
void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
UInt32 numIterations, UInt32 *key, size_t keySize);
}}
#endif

View File

@@ -19,7 +19,7 @@
#ifdef USE_STATIC_RtlGenRandom
#include <ntsecapi.h>
// #include <NTSecAPI.h>
EXTERN_C_BEGIN
#ifndef RtlGenRandom
@@ -59,6 +59,7 @@ EXTERN_C_END
void CRandomGenerator::Init()
{
MY_ALIGN (16)
CSha256 hash;
Sha256_Init(&hash);
@@ -68,6 +69,7 @@ void CRandomGenerator::Init()
#ifndef UNDER_CE
const unsigned kNumIterations_Small = 100;
const unsigned kBufSize = 32;
MY_ALIGN (16)
Byte buf[kBufSize];
#endif
@@ -98,7 +100,7 @@ void CRandomGenerator::Init()
if (hModule)
{
// SystemFunction036() is real name of RtlGenRandom() function
Func_RtlGenRandom my_RtlGenRandom = (Func_RtlGenRandom)GetProcAddress(hModule, "SystemFunction036");
Func_RtlGenRandom my_RtlGenRandom = (Func_RtlGenRandom)(void *)GetProcAddress(hModule, "SystemFunction036");
if (my_RtlGenRandom)
{
if (my_RtlGenRandom(buf, kBufSize))
@@ -126,11 +128,11 @@ void CRandomGenerator::Init()
{
do
{
int n = read(f, buf, numBytes);
ssize_t n = read(f, buf, numBytes);
if (n <= 0)
break;
Sha256_Update(&hash, buf, n);
numBytes -= n;
Sha256_Update(&hash, buf, (size_t)n);
numBytes -= (unsigned)n;
}
while (numBytes);
close(f);
@@ -211,6 +213,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size)
Init();
while (size != 0)
{
MY_ALIGN (16)
CSha256 hash;
Sha256_Init(&hash);
@@ -221,6 +224,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size)
UInt32 salt = 0xF672ABD1;
HASH_UPD(salt);
Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
MY_ALIGN (16)
Byte buff[SHA256_DIGEST_SIZE];
Sha256_Final(&hash, buff);
for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--)

View File

@@ -54,7 +54,7 @@ void CData::SetPassword(const Byte *data, unsigned size)
Keys[3] = 0xA4E7F123L;
Byte psw[128];
memset(psw, 0, sizeof(psw));
MY_memset_0_ARRAY(psw);
if (size != 0)
{
if (size >= sizeof(psw))

View File

@@ -28,6 +28,13 @@ class CData
void UpdateKeys(const Byte *data);
void CryptBlock(Byte *buf, bool encrypt);
public:
~CData() { Wipe(); }
void Wipe()
{
MY_memset_0_ARRAY(SubstTable);
MY_memset_0_ARRAY(Keys);
}
void EncryptBlock(Byte *buf) { CryptBlock(buf, true); }
void DecryptBlock(Byte *buf) { CryptBlock(buf, false); }
void SetPassword(const Byte *password, unsigned passwordLen);

View File

@@ -9,6 +9,7 @@
#endif
#include "Rar5Aes.h"
#include "HmacSha256.h"
namespace NCrypto {
namespace NRar5 {
@@ -122,6 +123,7 @@ void CDecoder::SetPassword(const Byte *data, size_t size)
if (size != _password.Size() || memcmp(data, _password, size) != 0)
{
_needCalc = true;
_password.Wipe();
_password.CopyFrom(data, size);
}
}
@@ -132,28 +134,31 @@ STDMETHODIMP CDecoder::Init()
CalcKey_and_CheckPassword();
RINOK(SetKey(_key, kAesKeySize));
RINOK(SetInitVector(_iv, AES_BLOCK_SIZE));
return CAesCbcCoder::Init();
return CAesCoder::Init();
}
UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const
{
MY_ALIGN (16)
NSha256::CHmac ctx;
ctx.SetKey(_hashKey, NSha256::kDigestSize);
Byte v[4];
SetUi32(v, crc);
ctx.Update(v, 4);
Byte h[NSha256::kDigestSize];
ctx.Final(h);
UInt32 v;
SetUi32(&v, crc);
ctx.Update((const Byte *)&v, 4);
MY_ALIGN (16)
UInt32 h[SHA256_NUM_DIGEST_WORDS];
ctx.Final((Byte *)h);
crc = 0;
for (unsigned i = 0; i < NSha256::kDigestSize; i++)
crc ^= (UInt32)h[i] << ((i & 3) * 8);
for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++)
crc ^= (UInt32)GetUi32(h + i);
return crc;
};
void CDecoder::Hmac_Convert_32Bytes(Byte *data) const
{
MY_ALIGN (16)
NSha256::CHmac ctx;
ctx.SetKey(_hashKey, NSha256::kDigestSize);
ctx.Update(data, NSha256::kDigestSize);
@@ -190,13 +195,16 @@ bool CDecoder::CalcKey_and_CheckPassword()
{
// Pbkdf HMAC-SHA-256
MY_ALIGN (16)
NSha256::CHmac baseCtx;
baseCtx.SetKey(_password, _password.Size());
NSha256::CHmac ctx = baseCtx;
ctx.Update(_salt, sizeof(_salt));
MY_ALIGN (16)
Byte u[NSha256::kDigestSize];
MY_ALIGN (16)
Byte key[NSha256::kDigestSize];
u[0] = 0;

View File

@@ -3,11 +3,10 @@
#ifndef __CRYPTO_RAR5_AES_H
#define __CRYPTO_RAR5_AES_H
#include "../../../C/Aes.h"
#include "../../../C/Sha256.h"
#include "../../Common/MyBuffer.h"
#include "HmacSha256.h"
#include "MyAes.h"
namespace NCrypto {
@@ -50,6 +49,17 @@ struct CKey
}
CKey();
void Wipe()
{
_password.Wipe();
MY_memset_0_ARRAY(_salt);
MY_memset_0_ARRAY(_key);
MY_memset_0_ARRAY(_check_Calced);
MY_memset_0_ARRAY(_hashKey);
}
~CKey() { Wipe(); }
};

View File

@@ -2,6 +2,9 @@
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../../C/RotateDefs.h"
#include "RarAes.h"
#include "Sha1Cls.h"
@@ -71,6 +74,7 @@ void CDecoder::SetPassword(const Byte *data, unsigned size)
}
if (!_needCalc && !same)
_needCalc = true;
_password.Wipe();
_password.CopyFrom(data, (size_t)size);
}
@@ -79,9 +83,44 @@ STDMETHODIMP CDecoder::Init()
CalcKey();
RINOK(SetKey(_key, kAesKeySize));
RINOK(SetInitVector(_iv, AES_BLOCK_SIZE));
return CAesCbcCoder::Init();
return CAesCoder::Init();
}
// if (password_size_in_bytes + SaltSize > 64),
// the original rar code updates password_with_salt buffer
// with some generated data from SHA1 code.
// #define RAR_SHA1_REDUCE
#ifdef RAR_SHA1_REDUCE
#define kNumW 16
#define WW(i) W[(i)&15]
#else
#define kNumW 80
#define WW(i) W[i]
#endif
static void UpdatePswDataSha1(Byte *data)
{
UInt32 W[kNumW];
size_t i;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
W[i] = GetBe32(data + i * 4);
for (i = 16; i < 80; i++)
{
WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1);
}
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
{
SetUi32(data + i * 4, W[kNumW - SHA1_NUM_BLOCK_WORDS + i]);
}
}
void CDecoder::CalcKey()
{
if (!_needCalc)
@@ -102,20 +141,42 @@ void CDecoder::CalcKey()
rawSize += kSaltSize;
}
MY_ALIGN (16)
NSha1::CContext sha;
sha.Init();
MY_ALIGN (16)
Byte digest[NSha1::kDigestSize];
// rar reverts hash for sha.
const UInt32 kNumRounds = ((UInt32)1 << 18);
UInt32 pos = 0;
UInt32 i;
for (i = 0; i < kNumRounds; i++)
{
sha.UpdateRar(buf, rawSize /* , _rar350Mode */);
sha.Update(buf, rawSize);
// if (_rar350Mode)
{
const UInt32 kBlockSize = 64;
const UInt32 endPos = (pos + (UInt32)rawSize) & ~(kBlockSize - 1);
if (endPos > pos + kBlockSize)
{
UInt32 curPos = pos & ~(kBlockSize - 1);
curPos += kBlockSize;
do
{
UpdatePswDataSha1(buf + (curPos - pos));
curPos += kBlockSize;
}
while (curPos != endPos);
}
}
pos += (UInt32)rawSize;
Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
sha.UpdateRar(pswNum, 3 /* , _rar350Mode */);
sha.Update(pswNum, 3);
pos += 3;
if (i % (kNumRounds / 16) == 0)
{
MY_ALIGN (16)
NSha1::CContext shaTemp = sha;
shaTemp.Final(digest);
_iv[i / (kNumRounds / 16)] = (Byte)digest[4 * 4 + 3];

View File

@@ -44,6 +44,15 @@ public:
HRESULT SetDecoderProperties2(const Byte *data, UInt32 size);
CDecoder();
~CDecoder() { Wipe(); }
void Wipe()
{
_password.Wipe();
MY_memset_0_ARRAY(_salt);
MY_memset_0_ARRAY(_key);
MY_memset_0_ARRAY(_iv);
}
// void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; }
};

View File

@@ -1,7 +1,7 @@
// Crypto/Sha1.h
// Crypto/Sha1Cls.h
#ifndef __CRYPTO_SHA1_H
#define __CRYPTO_SHA1_H
#ifndef __CRYPTO_SHA1_CLS_H
#define __CRYPTO_SHA1_CLS_H
#include "../../../C/Sha1.h"
@@ -14,35 +14,21 @@ const unsigned kNumDigestWords = SHA1_NUM_DIGEST_WORDS;
const unsigned kBlockSize = SHA1_BLOCK_SIZE;
const unsigned kDigestSize = SHA1_DIGEST_SIZE;
class CContextBase
class CContext
{
protected:
CSha1 _s;
public:
void Init() throw() { Sha1_Init(&_s); }
void GetBlockDigest(const UInt32 *blockData, UInt32 *destDigest) throw() { Sha1_GetBlockDigest(&_s, blockData, destDigest); }
};
class CContext: public CContextBase
{
public:
void Update(const Byte *data, size_t size) throw() { Sha1_Update(&_s, data, size); }
void UpdateRar(Byte *data, size_t size /* , bool rar350Mode */) throw() { Sha1_Update_Rar(&_s, data, size /* , rar350Mode ? 1 : 0 */); }
void Final(Byte *digest) throw() { Sha1_Final(&_s, digest); }
};
class CContext32: public CContextBase
{
public:
void Update(const UInt32 *data, size_t size) throw() { Sha1_32_Update(&_s, data, size); }
void Final(UInt32 *digest) throw() { Sha1_32_Final(&_s, digest); }
/* PrepareBlock can be used only when size <= 13. size in Words
_buffer must be empty (_count & 0xF) == 0) */
void PrepareBlock(UInt32 *block, unsigned size) const throw()
void PrepareBlock(Byte *block, unsigned size) const throw()
{
Sha1_32_PrepareBlock(&_s, block, size);
Sha1_PrepareBlock(&_s, block, size);
}
void GetBlockDigest(const Byte *blockData, Byte *destDigest) const throw()
{
Sha1_GetBlockDigest(&_s, blockData, destDigest);
}
};

View File

@@ -16,9 +16,6 @@ Note: you must include MyAes.cpp to project to initialize AES tables
#include "RandGen.h"
#include "WzAes.h"
// define it if you don't want to use speed-optimized version of NSha1::Pbkdf2Hmac
// #define _NO_WZAES_OPTIMIZATIONS
namespace NCrypto {
namespace NWzAes {
@@ -30,6 +27,7 @@ STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
{
if (size > kPasswordSizeMax)
return E_INVALIDARG;
_key.Password.Wipe();
_key.Password.CopyFrom(data, (size_t)size);
return S_OK;
}
@@ -40,52 +38,25 @@ void CBaseCoder::Init2()
Byte dk[dkSizeMax32 * 4];
const unsigned keySize = _key.GetKeySize();
const unsigned dkSize = 2 * keySize + kPwdVerifSize;
const unsigned dkSize = 2 * keySize + ((kPwdVerifSize + 3) & ~(unsigned)3);
// for (unsigned ii = 0; ii < 1000; ii++)
{
#ifdef _NO_WZAES_OPTIMIZATIONS
NSha1::Pbkdf2Hmac(
_key.Password, _key.Password.Size(),
_key.Salt, _key.GetSaltSize(),
kNumKeyGenIterations,
dk, dkSize);
#else
UInt32 dk32[dkSizeMax32];
const unsigned dkSize32 = (dkSize + 3) / 4;
UInt32 salt[kSaltSizeMax / 4];
unsigned numSaltWords = _key.GetNumSaltWords();
for (unsigned i = 0; i < numSaltWords; i++)
{
const Byte *src = _key.Salt + i * 4;
salt[i] = GetBe32(src);
}
NSha1::Pbkdf2Hmac32(
_key.Password, _key.Password.Size(),
salt, numSaltWords,
kNumKeyGenIterations,
dk32, dkSize32);
/*
for (unsigned j = 0; j < dkSize; j++)
dk[j] = (Byte)(dk32[j / 4] >> (24 - 8 * (j & 3)));
*/
for (unsigned j = 0; j < dkSize32; j++)
SetBe32(dk + j * 4, dk32[j]);
#endif
}
_hmac.SetKey(dk + keySize, keySize);
Hmac()->SetKey(dk + keySize, keySize);
memcpy(_key.PwdVerifComputed, dk + 2 * keySize, kPwdVerifSize);
Aes_SetKey_Enc(_aes.aes + _aes.offset + 8, dk, keySize);
AesCtr2_Init(&_aes);
// Aes_SetKey_Enc(_aes.Aes() + 8, dk, keySize);
// AesCtr2_Init(&_aes);
_aesCoderSpec->SetKeySize(keySize);
if (_aesCoderSpec->SetKey(dk, keySize) != S_OK) throw 2;
if (_aesCoderSpec->Init() != S_OK) throw 3;
}
STDMETHODIMP CBaseCoder::Init()
@@ -104,8 +75,9 @@ HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream)
{
Byte mac[kMacSize];
_hmac.Final(mac, kMacSize);
MY_ALIGN (16)
UInt32 mac[NSha1::kNumDigestWords];
Hmac()->Final((Byte *)mac);
return WriteStream(outStream, mac, kMacSize);
}
@@ -150,34 +122,41 @@ bool CDecoder::Init_and_CheckPassword()
HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK)
{
isOK = false;
MY_ALIGN (16)
Byte mac1[kMacSize];
RINOK(ReadStream_FAIL(inStream, mac1, kMacSize));
Byte mac2[kMacSize];
_hmac.Final(mac2, kMacSize);
isOK = CompareArrays(mac1, mac2, kMacSize);
MY_ALIGN (16)
UInt32 mac2[NSha1::kNumDigestWords];
Hmac()->Final((Byte *)mac2);
isOK = CompareArrays(mac1, (const Byte *)mac2, kMacSize);
return S_OK;
}
CAesCtr2::CAesCtr2()
/*
CAesCtr2::CAesCtr2():
aes((4 + AES_NUM_IVMRK_WORDS) * 4)
{
offset = ((0 - (unsigned)(ptrdiff_t)aes) & 0xF) / sizeof(UInt32);
// offset = ((0 - (unsigned)(ptrdiff_t)aes) & 0xF) / sizeof(UInt32);
// first 16 bytes are buffer for last block data.
// so the ivAES is aligned for (Align + 16).
}
void AesCtr2_Init(CAesCtr2 *p)
{
UInt32 *ctr = p->aes + p->offset + 4;
UInt32 *ctr = p->Aes() + 4;
unsigned i;
for (i = 0; i < 4; i++)
ctr[i] = 0;
p->pos = AES_BLOCK_SIZE;
}
/* (size != 16 * N) is allowed only for last call */
// (size != 16 * N) is allowed only for last call
void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size)
{
unsigned pos = p->pos;
UInt32 *buf32 = p->aes + p->offset;
UInt32 *buf32 = p->Aes();
if (size == 0)
return;
@@ -188,6 +167,8 @@ void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size)
*data++ ^= buf[pos++];
while (--size != 0 && pos != AES_BLOCK_SIZE);
}
// (size == 0 || pos == AES_BLOCK_SIZE)
if (size >= 16)
{
@@ -196,8 +177,10 @@ void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size)
size2 <<= 4;
data += size2;
size -= size2;
pos = AES_BLOCK_SIZE;
// (pos == AES_BLOCK_SIZE)
}
// (size < 16)
if (size != 0)
{
@@ -215,20 +198,26 @@ void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size)
p->pos = pos;
}
*/
/* (size != 16 * N) is allowed only for last Filter() call */
STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
{
AesCtr2_Code(&_aes, data, size);
_hmac.Update(data, size);
// AesCtr2_Code(&_aes, data, size);
size = _aesCoder->Filter(data, size);
Hmac()->Update(data, size);
return size;
}
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
{
_hmac.Update(data, size);
AesCtr2_Code(&_aes, data, size);
if (size >= 16)
size &= ~(UInt32)15;
Hmac()->Update(data, size);
// AesCtr2_Code(&_aes, data, size);
size = _aesCoder->Filter(data, size);
return size;
}

View File

@@ -12,15 +12,12 @@ specified in "A Password Based File Encryption Utility":
#ifndef __CRYPTO_WZ_AES_H
#define __CRYPTO_WZ_AES_H
#include "../../../C/Aes.h"
#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../IPassword.h"
#include "HmacSha1.h"
#include "MyAes.h"
namespace NCrypto {
namespace NWzAes {
@@ -64,18 +61,33 @@ struct CKeyInfo
unsigned GetNumSaltWords() const { return (KeySizeMode + 1); }
CKeyInfo(): KeySizeMode(kKeySizeMode_AES256) {}
void Wipe()
{
Password.Wipe();
MY_memset_0_ARRAY(Salt);
MY_memset_0_ARRAY(PwdVerifComputed);
}
~CKeyInfo() { Wipe(); }
};
/*
struct CAesCtr2
{
unsigned pos;
unsigned offset;
UInt32 aes[4 + AES_NUM_IVMRK_WORDS + 3];
CAlignedBuffer aes;
UInt32 *Aes() { return (UInt32 *)(Byte *)aes; }
// unsigned offset;
// UInt32 aes[4 + AES_NUM_IVMRK_WORDS + 3];
// UInt32 *Aes() { return aes + offset; }
CAesCtr2();
};
void AesCtr2_Init(CAesCtr2 *p);
void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size);
*/
class CBaseCoder:
public ICompressFilter,
@@ -84,8 +96,21 @@ class CBaseCoder:
{
protected:
CKeyInfo _key;
NSha1::CHmac _hmac;
CAesCtr2 _aes;
// NSha1::CHmac _hmac;
// NSha1::CHmac *Hmac() { return &_hmac; }
CAlignedBuffer _hmacBuf;
NSha1::CHmac *Hmac() { return (NSha1::CHmac *)(void *)(Byte *)_hmacBuf; }
// CAesCtr2 _aes;
CAesCoder *_aesCoderSpec;
CMyComPtr<ICompressFilter> _aesCoder;
CBaseCoder():
_hmacBuf(sizeof(NSha1::CHmac))
{
_aesCoderSpec = new CAesCoder(true, 32, true);
_aesCoder = _aesCoderSpec;
}
void Init2();
public:

View File

@@ -51,7 +51,12 @@ public:
STDMETHOD(Init)();
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
virtual ~CCipher() {}
virtual ~CCipher()
{
Key0 = KeyMem0 =
Key1 = KeyMem1 =
Key2 = KeyMem2 = 0;
}
};
class CEncoder: public CCipher

View File

@@ -26,10 +26,12 @@ static const UInt16 kAES128 = 0x660E;
static void DeriveKey2(const Byte *digest, Byte c, Byte *dest)
{
MY_ALIGN (16)
Byte buf[64];
memset(buf, c, 64);
for (unsigned i = 0; i < NSha1::kDigestSize; i++)
buf[i] ^= digest[i];
MY_ALIGN (16)
NSha1::CContext sha;
sha.Init();
sha.Update(buf, 64);
@@ -38,8 +40,10 @@ static void DeriveKey2(const Byte *digest, Byte c, Byte *dest)
static void DeriveKey(NSha1::CContext &sha, Byte *key)
{
MY_ALIGN (16)
Byte digest[NSha1::kDigestSize];
sha.Final(digest);
MY_ALIGN (16)
Byte temp[NSha1::kDigestSize * 2];
DeriveKey2(digest, 0x36, temp);
DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize);
@@ -48,6 +52,7 @@ static void DeriveKey(NSha1::CContext &sha, Byte *key)
void CKeyInfo::SetPassword(const Byte *data, UInt32 size)
{
MY_ALIGN (16)
NSha1::CContext sha;
sha.Init();
sha.Update(data, size);
@@ -103,21 +108,21 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (_remSize < 16)
return E_NOTIMPL;
Byte *p = _bufAligned;
UInt16 format = GetUi16(p);
const unsigned format = GetUi16(p);
if (format != 3)
return E_NOTIMPL;
UInt16 algId = GetUi16(p + 2);
unsigned 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);
const unsigned bitLen = GetUi16(p + 4);
const unsigned flags = GetUi16(p + 6);
if (algId * 64 + 128 != bitLen)
return E_NOTIMPL;
_key.KeySize = 16 + algId * 8;
bool cert = ((flags & 2) != 0);
const bool cert = ((flags & 2) != 0);
if ((flags & 0x4000) != 0)
{
@@ -198,7 +203,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
UInt32 validSize = GetUi16(p2);
p2 += 2;
const size_t validOffset = p2 - p;
const size_t validOffset = (size_t)(p2 - p);
if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
return E_NOTIMPL;
@@ -214,7 +219,9 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
return S_OK; // passwOK = false;
}
MY_ALIGN (16)
Byte fileKey[32];
MY_ALIGN (16)
NSha1::CContext sha;
sha.Init();
sha.Update(_iv, _ivSize);

View File

@@ -27,6 +27,12 @@ struct CKeyInfo
UInt32 KeySize;
void SetPassword(const Byte *data, UInt32 size);
~CKeyInfo() { Wipe(); }
void Wipe()
{
MY_memset_0_ARRAY(MasterKey);
}
};
class CBaseCoder:
@@ -58,6 +64,12 @@ public:
// Change it, if is not AES
return kAesPadAllign - (packSize32 & (kAesPadAllign - 1));
}
~CDecoder() { Wipe(); }
void Wipe()
{
MY_memset_0_ARRAY(_iv);
}
};
}}