diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp | 163 |
1 files changed, 128 insertions, 35 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp index 52eaab7ae2c..5cb7f46359b 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp +++ b/3rdparty/lzma/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 + } |