1 // Crypto/MyAes.cpp 2 3 #include "StdAfx.h" 4 5 #include "../../../C/CpuArch.h" 6 7 #include "MyAes.h" 8 9 namespace NCrypto { 10 11 static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; 12 13 CAesCbcCoder::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 23 STDMETHODIMP CAesCbcCoder::Init() 24 { 25 AesCbc_Init(_aes + _offset, _iv); 26 return _keyIsSet ? S_OK : E_FAIL; 27 } 28 29 STDMETHODIMP_(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 42 STDMETHODIMP 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 54 STDMETHODIMP 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 63 EXTERN_C_BEGIN 64 65 void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); 66 void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); 67 void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); 68 69 void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 70 void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 71 void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); 72 73 EXTERN_C_END 74 75 bool 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 96 STDMETHODIMP 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