1// Crypto/MyAes.cpp 2 3#include "StdAfx.h" 4 5#include "../../../C/CpuArch.h" 6 7#include "MyAes.h" 8 9namespace NCrypto { 10 11static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; 12 13CAesCbcCoder::CAesCbcCoder(bool encodeMode, unsigned keySize): 14 _keySize(keySize), 15 _keyIsSet(false), 16 _encodeMode(encodeMode) 17{ 18 _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); 19 memset(_iv, 0, AES_BLOCK_SIZE); 20 SetFunctions(0); 21} 22 23STDMETHODIMP CAesCbcCoder::Init() 24{ 25 AesCbc_Init(_aes + _offset, _iv); 26 return _keyIsSet ? S_OK : E_FAIL; 27} 28 29STDMETHODIMP_(UInt32) CAesCbcCoder::Filter(Byte *data, UInt32 size) 30{ 31 if (!_keyIsSet) 32 return 0; 33 if (size == 0) 34 return 0; 35 if (size < AES_BLOCK_SIZE) 36 return AES_BLOCK_SIZE; 37 size >>= 4; 38 _codeFunc(_aes + _offset, data, size); 39 return size << 4; 40} 41 42STDMETHODIMP CAesCbcCoder::SetKey(const Byte *data, UInt32 size) 43{ 44 if ((size & 0x7) != 0 || size < 16 || size > 32) 45 return E_INVALIDARG; 46 if (_keySize != 0 && size != _keySize) 47 return E_INVALIDARG; 48 AES_SET_KEY_FUNC setKeyFunc = _encodeMode ? Aes_SetKey_Enc : Aes_SetKey_Dec; 49 setKeyFunc(_aes + _offset + 4, data, size); 50 _keyIsSet = true; 51 return S_OK; 52} 53 54STDMETHODIMP CAesCbcCoder::SetInitVector(const Byte *data, UInt32 size) 55{ 56 if (size != AES_BLOCK_SIZE) 57 return E_INVALIDARG; 58 memcpy(_iv, data, size); 59 CAesCbcCoder::Init(); // don't call virtual function here !!! 60 return S_OK; 61} 62 63EXTERN_C_BEGIN 64 65void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); 66void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); 67void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); 68 69void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 70void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 71void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 72 73EXTERN_C_END 74 75bool CAesCbcCoder::SetFunctions(UInt32 algo) 76{ 77 _codeFunc = _encodeMode ? 78 g_AesCbc_Encode : 79 g_AesCbc_Decode; 80 if (algo == 1) 81 { 82 _codeFunc = _encodeMode ? 83 AesCbc_Encode: 84 AesCbc_Decode; 85 } 86 if (algo == 2) 87 { 88 #ifdef MY_CPU_X86_OR_AMD64 89 if (g_AesCbc_Encode != AesCbc_Encode_Intel) 90 #endif 91 return false; 92 } 93 return true; 94} 95 96STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) 97{ 98 for (UInt32 i = 0; i < numProps; i++) 99 { 100 const PROPVARIANT &prop = coderProps[i]; 101 if (propIDs[i] == NCoderPropID::kDefaultProp) 102 { 103 if (prop.vt != VT_UI4) 104 return E_INVALIDARG; 105 if (!SetFunctions(prop.ulVal)) 106 return E_NOTIMPL; 107 } 108 } 109 return S_OK; 110} 111 112} 113