Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Crypto/MyAes.cpp')
-rw-r--r--CPP/7zip/Crypto/MyAes.cpp163
1 files changed, 128 insertions, 35 deletions
diff --git a/CPP/7zip/Crypto/MyAes.cpp b/CPP/7zip/Crypto/MyAes.cpp
index 52eaab7a..5cb7f463 100644
--- a/CPP/7zip/Crypto/MyAes.cpp
+++ b/CPP/7zip/Crypto/MyAes.cpp
@@ -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;
+ _codeFunc = AesCbc_Decode;
+
+ #ifndef _SFX
+ if (_ctrMode)
+ _codeFunc = AesCtr_Code;
+ else if (_encodeMode)
+ _codeFunc = AesCbc_Encode;
+ #endif
+ return true;
}
- if (algo == 2)
+
+ #ifdef USE_HW_AES
+ // if (CPU_IsSupported_AES())
{
- #ifdef MY_CPU_X86_OR_AMD64
- if (g_AesCbc_Encode != AesCbc_Encode_Intel)
+ 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
- return false;
}
- return true;
+ #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
+
}