Home | History | Annotate | Download | only in Crypto
      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