1*f6dc9357SAndroid Build Coastguard Worker // Crypto/MyAes.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "MyAes.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker namespace NCrypto {
10*f6dc9357SAndroid Build Coastguard Worker
CAesTabInitNCrypto::CAesTabInit11*f6dc9357SAndroid Build Coastguard Worker static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit;
12*f6dc9357SAndroid Build Coastguard Worker
CAesCoder(unsigned keySize)13*f6dc9357SAndroid Build Coastguard Worker CAesCoder::CAesCoder(
14*f6dc9357SAndroid Build Coastguard Worker // bool encodeMode,
15*f6dc9357SAndroid Build Coastguard Worker unsigned keySize
16*f6dc9357SAndroid Build Coastguard Worker // , bool ctrMode
17*f6dc9357SAndroid Build Coastguard Worker ):
18*f6dc9357SAndroid Build Coastguard Worker _keyIsSet(false),
19*f6dc9357SAndroid Build Coastguard Worker // _encodeMode(encodeMode),
20*f6dc9357SAndroid Build Coastguard Worker // _ctrMode(ctrMode),
21*f6dc9357SAndroid Build Coastguard Worker _keySize(keySize),
22*f6dc9357SAndroid Build Coastguard Worker // _ctrPos(0), // _ctrPos =0 will be set in Init()
23*f6dc9357SAndroid Build Coastguard Worker _aes(AES_NUM_IVMRK_WORDS * 4 + AES_BLOCK_SIZE * 2)
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker // _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32);
26*f6dc9357SAndroid Build Coastguard Worker memset(_iv, 0, AES_BLOCK_SIZE);
27*f6dc9357SAndroid Build Coastguard Worker /*
28*f6dc9357SAndroid Build Coastguard Worker // we can use the following code to test 32-bit overflow case for AES-CTR
29*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 16; i++) _iv[i] = (Byte)(i + 1);
30*f6dc9357SAndroid Build Coastguard Worker _iv[0] = 0xFE; _iv[1] = _iv[2] = _iv[3] = 0xFF;
31*f6dc9357SAndroid Build Coastguard Worker */
32*f6dc9357SAndroid Build Coastguard Worker }
33*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CAesCoder::Init ())34*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAesCoder::Init())
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker _ctrPos = 0;
37*f6dc9357SAndroid Build Coastguard Worker AesCbc_Init(Aes(), _iv);
38*f6dc9357SAndroid Build Coastguard Worker return _keyIsSet ? S_OK : E_NOTIMPL; // E_FAIL
39*f6dc9357SAndroid Build Coastguard Worker }
40*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF2(UInt32,CAesCoder::Filter (Byte * data,UInt32 size))41*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt32, CAesCoder::Filter(Byte *data, UInt32 size))
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker if (!_keyIsSet)
44*f6dc9357SAndroid Build Coastguard Worker return 0;
45*f6dc9357SAndroid Build Coastguard Worker if (size < AES_BLOCK_SIZE)
46*f6dc9357SAndroid Build Coastguard Worker {
47*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
48*f6dc9357SAndroid Build Coastguard Worker return 0;
49*f6dc9357SAndroid Build Coastguard Worker return AES_BLOCK_SIZE;
50*f6dc9357SAndroid Build Coastguard Worker }
51*f6dc9357SAndroid Build Coastguard Worker size >>= 4;
52*f6dc9357SAndroid Build Coastguard Worker // (data) must be aligned for 16-bytes here
53*f6dc9357SAndroid Build Coastguard Worker _codeFunc(Aes(), data, size);
54*f6dc9357SAndroid Build Coastguard Worker return size << 4;
55*f6dc9357SAndroid Build Coastguard Worker }
56*f6dc9357SAndroid Build Coastguard Worker
57*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CAesCoder::SetKey (const Byte * data,UInt32 size))58*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAesCoder::SetKey(const Byte *data, UInt32 size))
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker if ((size & 0x7) != 0 || size < 16 || size > 32)
61*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
62*f6dc9357SAndroid Build Coastguard Worker if (_keySize != 0 && size != _keySize)
63*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
64*f6dc9357SAndroid Build Coastguard Worker _setKeyFunc(Aes() + 4, data, size);
65*f6dc9357SAndroid Build Coastguard Worker _keyIsSet = true;
66*f6dc9357SAndroid Build Coastguard Worker return S_OK;
67*f6dc9357SAndroid Build Coastguard Worker }
68*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CAesCoder::SetInitVector (const Byte * data,UInt32 size))69*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAesCoder::SetInitVector(const Byte *data, UInt32 size))
70*f6dc9357SAndroid Build Coastguard Worker {
71*f6dc9357SAndroid Build Coastguard Worker if (size != AES_BLOCK_SIZE)
72*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
73*f6dc9357SAndroid Build Coastguard Worker memcpy(_iv, data, size);
74*f6dc9357SAndroid Build Coastguard Worker /* we allow SetInitVector() call before SetKey() call.
75*f6dc9357SAndroid Build Coastguard Worker so we ignore possible error in Init() here */
76*f6dc9357SAndroid Build Coastguard Worker CAesCoder::Init(); // don't call virtual function here !!!
77*f6dc9357SAndroid Build Coastguard Worker return S_OK;
78*f6dc9357SAndroid Build Coastguard Worker }
79*f6dc9357SAndroid Build Coastguard Worker
80*f6dc9357SAndroid Build Coastguard Worker
81*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
82*f6dc9357SAndroid Build Coastguard Worker
83*f6dc9357SAndroid Build Coastguard Worker /*
84*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAesCtrCoder::Init())
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker _ctrPos = 0;
87*f6dc9357SAndroid Build Coastguard Worker return CAesCoder::Init();
88*f6dc9357SAndroid Build Coastguard Worker }
89*f6dc9357SAndroid Build Coastguard Worker */
90*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF2(UInt32,CAesCtrCoder::Filter (Byte * data,UInt32 size))91*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt32, CAesCtrCoder::Filter(Byte *data, UInt32 size))
92*f6dc9357SAndroid Build Coastguard Worker {
93*f6dc9357SAndroid Build Coastguard Worker if (!_keyIsSet)
94*f6dc9357SAndroid Build Coastguard Worker return 0;
95*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
96*f6dc9357SAndroid Build Coastguard Worker return 0;
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker if (_ctrPos != 0)
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker /* Optimized caller will not call here */
101*f6dc9357SAndroid Build Coastguard Worker const Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS);
102*f6dc9357SAndroid Build Coastguard Worker unsigned num = 0;
103*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = _ctrPos; i != AES_BLOCK_SIZE; i++)
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker if (num == size)
106*f6dc9357SAndroid Build Coastguard Worker {
107*f6dc9357SAndroid Build Coastguard Worker _ctrPos = i;
108*f6dc9357SAndroid Build Coastguard Worker return num;
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker data[num++] ^= ctr[i];
111*f6dc9357SAndroid Build Coastguard Worker }
112*f6dc9357SAndroid Build Coastguard Worker _ctrPos = 0;
113*f6dc9357SAndroid Build Coastguard Worker /* if (num < size) {
114*f6dc9357SAndroid Build Coastguard Worker we can filter more data with _codeFunc().
115*f6dc9357SAndroid Build Coastguard Worker But it's supposed that the caller can work correctly,
116*f6dc9357SAndroid Build Coastguard Worker even if we do only partial filtering here.
117*f6dc9357SAndroid Build Coastguard Worker So we filter data only for current 16-byte block. }
118*f6dc9357SAndroid Build Coastguard Worker */
119*f6dc9357SAndroid Build Coastguard Worker /*
120*f6dc9357SAndroid Build Coastguard Worker size -= num;
121*f6dc9357SAndroid Build Coastguard Worker size >>= 4;
122*f6dc9357SAndroid Build Coastguard Worker // (data) must be aligned for 16-bytes here
123*f6dc9357SAndroid Build Coastguard Worker _codeFunc(Aes(), data + num, size);
124*f6dc9357SAndroid Build Coastguard Worker return num + (size << 4);
125*f6dc9357SAndroid Build Coastguard Worker */
126*f6dc9357SAndroid Build Coastguard Worker return num;
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker
129*f6dc9357SAndroid Build Coastguard Worker if (size < AES_BLOCK_SIZE)
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker /* The good optimized caller can call here only in last Filter() call.
132*f6dc9357SAndroid Build Coastguard Worker But we support also non-optimized callers,
133*f6dc9357SAndroid Build Coastguard Worker where another Filter() calls are allowed after this call.
134*f6dc9357SAndroid Build Coastguard Worker */
135*f6dc9357SAndroid Build Coastguard Worker Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS);
136*f6dc9357SAndroid Build Coastguard Worker memset(ctr, 0, AES_BLOCK_SIZE);
137*f6dc9357SAndroid Build Coastguard Worker memcpy(ctr, data, size);
138*f6dc9357SAndroid Build Coastguard Worker _codeFunc(Aes(), ctr, 1);
139*f6dc9357SAndroid Build Coastguard Worker memcpy(data, ctr, size);
140*f6dc9357SAndroid Build Coastguard Worker _ctrPos = size;
141*f6dc9357SAndroid Build Coastguard Worker return size;
142*f6dc9357SAndroid Build Coastguard Worker }
143*f6dc9357SAndroid Build Coastguard Worker
144*f6dc9357SAndroid Build Coastguard Worker size >>= 4;
145*f6dc9357SAndroid Build Coastguard Worker // (data) must be aligned for 16-bytes here
146*f6dc9357SAndroid Build Coastguard Worker _codeFunc(Aes(), data, size);
147*f6dc9357SAndroid Build Coastguard Worker return size << 4;
148*f6dc9357SAndroid Build Coastguard Worker }
149*f6dc9357SAndroid Build Coastguard Worker
150*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
151*f6dc9357SAndroid Build Coastguard Worker
152*f6dc9357SAndroid Build Coastguard Worker
153*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_EXTRACT_ONLY
154*f6dc9357SAndroid Build Coastguard Worker
155*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_X86_OR_AMD64
156*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_AES
157*f6dc9357SAndroid Build Coastguard Worker #elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE)
158*f6dc9357SAndroid Build Coastguard Worker
159*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FEATURE_AES) \
160*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_FEATURE_CRYPTO)
161*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_AES
162*f6dc9357SAndroid Build Coastguard Worker #else
163*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64) \
164*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \
165*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_MSC_VER_ORIGINAL)
166*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FP) && \
167*f6dc9357SAndroid Build Coastguard Worker ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \
168*f6dc9357SAndroid Build Coastguard Worker || defined(__GNUC__) && (__GNUC__ >= 6) \
169*f6dc9357SAndroid Build Coastguard Worker ) \
170*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910)
171*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64) \
172*f6dc9357SAndroid Build Coastguard Worker || !defined(Z7_CLANG_VERSION) \
173*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_NEON) && \
174*f6dc9357SAndroid Build Coastguard Worker (Z7_CLANG_VERSION < 170000 || \
175*f6dc9357SAndroid Build Coastguard Worker Z7_CLANG_VERSION > 170001)
176*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_AES
177*f6dc9357SAndroid Build Coastguard Worker #endif
178*f6dc9357SAndroid Build Coastguard Worker #endif
179*f6dc9357SAndroid Build Coastguard Worker #endif
180*f6dc9357SAndroid Build Coastguard Worker #endif
181*f6dc9357SAndroid Build Coastguard Worker #endif
182*f6dc9357SAndroid Build Coastguard Worker
183*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_HW_AES
184*f6dc9357SAndroid Build Coastguard Worker // #pragma message("=== MyAES.c USE_HW_AES === ")
185*f6dc9357SAndroid Build Coastguard Worker
186*f6dc9357SAndroid Build Coastguard Worker #define SET_AES_FUNC_2(f2) \
187*f6dc9357SAndroid Build Coastguard Worker if (algo == 2) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW) \
188*f6dc9357SAndroid Build Coastguard Worker { f = f2; }
189*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_X86_OR_AMD64
190*f6dc9357SAndroid Build Coastguard Worker #define SET_AES_FUNC_23(f2, f3) \
191*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNC_2(f2) \
192*f6dc9357SAndroid Build Coastguard Worker if (algo == 3) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256) \
193*f6dc9357SAndroid Build Coastguard Worker { f = f3; }
194*f6dc9357SAndroid Build Coastguard Worker #else // MY_CPU_X86_OR_AMD64
195*f6dc9357SAndroid Build Coastguard Worker #define SET_AES_FUNC_23(f2, f3) \
196*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNC_2(f2)
197*f6dc9357SAndroid Build Coastguard Worker #endif // MY_CPU_X86_OR_AMD64
198*f6dc9357SAndroid Build Coastguard Worker #else // USE_HW_AES
199*f6dc9357SAndroid Build Coastguard Worker #define SET_AES_FUNC_23(f2, f3)
200*f6dc9357SAndroid Build Coastguard Worker #endif // USE_HW_AES
201*f6dc9357SAndroid Build Coastguard Worker
202*f6dc9357SAndroid Build Coastguard Worker #define SET_AES_FUNCS(c, f0, f1, f2, f3) \
203*f6dc9357SAndroid Build Coastguard Worker bool c::SetFunctions(UInt32 algo) { \
204*f6dc9357SAndroid Build Coastguard Worker _codeFunc = f0; if (algo < 1) return true; \
205*f6dc9357SAndroid Build Coastguard Worker AES_CODE_FUNC f = NULL; \
206*f6dc9357SAndroid Build Coastguard Worker if (algo == 1) { f = f1; } \
207*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNC_23(f2, f3) \
208*f6dc9357SAndroid Build Coastguard Worker if (f) { _codeFunc = f; return true; } \
209*f6dc9357SAndroid Build Coastguard Worker return false; }
210*f6dc9357SAndroid Build Coastguard Worker
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker
213*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
SET_AES_FUNCS(CAesCtrCoder,g_AesCtr_Code,AesCtr_Code,AesCtr_Code_HW,AesCtr_Code_HW_256)214*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNCS(
215*f6dc9357SAndroid Build Coastguard Worker CAesCtrCoder,
216*f6dc9357SAndroid Build Coastguard Worker g_AesCtr_Code,
217*f6dc9357SAndroid Build Coastguard Worker AesCtr_Code,
218*f6dc9357SAndroid Build Coastguard Worker AesCtr_Code_HW,
219*f6dc9357SAndroid Build Coastguard Worker AesCtr_Code_HW_256)
220*f6dc9357SAndroid Build Coastguard Worker #endif
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNCS(
223*f6dc9357SAndroid Build Coastguard Worker CAesCbcEncoder,
224*f6dc9357SAndroid Build Coastguard Worker g_AesCbc_Encode,
225*f6dc9357SAndroid Build Coastguard Worker AesCbc_Encode,
226*f6dc9357SAndroid Build Coastguard Worker AesCbc_Encode_HW,
227*f6dc9357SAndroid Build Coastguard Worker AesCbc_Encode_HW)
228*f6dc9357SAndroid Build Coastguard Worker
229*f6dc9357SAndroid Build Coastguard Worker SET_AES_FUNCS(
230*f6dc9357SAndroid Build Coastguard Worker CAesCbcDecoder,
231*f6dc9357SAndroid Build Coastguard Worker g_AesCbc_Decode,
232*f6dc9357SAndroid Build Coastguard Worker AesCbc_Decode,
233*f6dc9357SAndroid Build Coastguard Worker AesCbc_Decode_HW,
234*f6dc9357SAndroid Build Coastguard Worker AesCbc_Decode_HW_256)
235*f6dc9357SAndroid Build Coastguard Worker
236*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps))
237*f6dc9357SAndroid Build Coastguard Worker {
238*f6dc9357SAndroid Build Coastguard Worker UInt32 algo = 0;
239*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numProps; i++)
240*f6dc9357SAndroid Build Coastguard Worker {
241*f6dc9357SAndroid Build Coastguard Worker if (propIDs[i] == NCoderPropID::kDefaultProp)
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker const PROPVARIANT &prop = coderProps[i];
244*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_UI4)
245*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
246*f6dc9357SAndroid Build Coastguard Worker if (prop.ulVal > 3)
247*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
248*f6dc9357SAndroid Build Coastguard Worker algo = prop.ulVal;
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker }
251*f6dc9357SAndroid Build Coastguard Worker if (!SetFunctions(algo))
252*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
253*f6dc9357SAndroid Build Coastguard Worker return S_OK;
254*f6dc9357SAndroid Build Coastguard Worker }
255*f6dc9357SAndroid Build Coastguard Worker
256*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_EXTRACT_ONLY
257*f6dc9357SAndroid Build Coastguard Worker
258*f6dc9357SAndroid Build Coastguard Worker }
259