"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/rijndael.cpp" (4 May 2022, 16116 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "rijndael.cpp" see the
Fossies "Dox" file reference documentation.
1 /**************************************************************************
2 * This code is based on Szymon Stefanek public domain AES implementation *
3 **************************************************************************/
4 #include "rar.hpp"
5
6 #ifdef USE_SSE
7 #include <wmmintrin.h>
8 #endif
9
10 static byte S[256]=
11 {
12 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
13 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
14 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
15 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
16 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
17 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
18 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
19 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
20 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
21 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
22 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
23 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
24 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
25 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
26 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
27 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
28 };
29
30 static byte S5[256];
31
32 // Round constants. 10 items are used by AES-128, 8 by AES-192, 7 by AES-256.
33 static byte rcon[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};
34
35 static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
36 static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
37 static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
38
39 inline void Xor128(void *dest,const void *arg1,const void *arg2)
40 {
41 #ifdef ALLOW_MISALIGNED
42 ((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
43 ((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
44 ((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
45 ((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
46 #else
47 for (int I=0;I<16;I++)
48 ((byte*)dest)[I]=((byte*)arg1)[I]^((byte*)arg2)[I];
49 #endif
50 }
51
52
53 inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
54 const byte *arg3,const byte *arg4)
55 {
56 #ifdef ALLOW_MISALIGNED
57 (*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
58 #else
59 for (int I=0;I<4;I++)
60 dest[I]=arg1[I]^arg2[I]^arg3[I]^arg4[I];
61 #endif
62 }
63
64
65 inline void Copy128(byte *dest,const byte *src)
66 {
67 #ifdef ALLOW_MISALIGNED
68 ((uint32*)dest)[0]=((uint32*)src)[0];
69 ((uint32*)dest)[1]=((uint32*)src)[1];
70 ((uint32*)dest)[2]=((uint32*)src)[2];
71 ((uint32*)dest)[3]=((uint32*)src)[3];
72 #else
73 for (int I=0;I<16;I++)
74 dest[I]=src[I];
75 #endif
76 }
77
78
79 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80 // API
81 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82
83 Rijndael::Rijndael()
84 {
85 if (S5[0]==0)
86 GenerateTables();
87 CBCMode = true; // Always true for RAR.
88 }
89
90
91 void Rijndael::Init(bool Encrypt,const byte *key,uint keyLen,const byte * initVector)
92 {
93 #ifdef USE_SSE
94 // Check SSE here instead of constructor, so if object is a part of some
95 // structure memset'ed before use, this variable is not lost.
96 int CPUInfo[4];
97 __cpuid(CPUInfo, 0x80000000); // Get the maximum supported cpuid function.
98 if ((CPUInfo[0] & 0x7fffffff)>=1)
99 {
100 __cpuid(CPUInfo, 1);
101 AES_NI=(CPUInfo[2] & 0x2000000)!=0;
102 }
103 else
104 AES_NI=false;
105 #endif
106
107 // Other developers asked us to initialize it to suppress "may be used
108 // uninitialized" warning in code below in some compilers.
109 uint uKeyLenInBytes=0;
110
111 switch(keyLen)
112 {
113 case 128:
114 uKeyLenInBytes = 16;
115 m_uRounds = 10;
116 break;
117 case 192:
118 uKeyLenInBytes = 24;
119 m_uRounds = 12;
120 break;
121 case 256:
122 uKeyLenInBytes = 32;
123 m_uRounds = 14;
124 break;
125 }
126
127 byte keyMatrix[_MAX_KEY_COLUMNS][4];
128
129 for(uint i = 0; i < uKeyLenInBytes; i++)
130 keyMatrix[i >> 2][i & 3] = key[i];
131
132 if (initVector==NULL)
133 memset(m_initVector, 0, sizeof(m_initVector));
134 else
135 for(int i = 0; i < MAX_IV_SIZE; i++)
136 m_initVector[i] = initVector[i];
137
138 keySched(keyMatrix);
139
140 if(!Encrypt)
141 keyEncToDec();
142 }
143
144 void Rijndael::blockEncrypt(const byte *input,size_t inputLen,byte *outBuffer)
145 {
146 if (inputLen <= 0)
147 return;
148
149 size_t numBlocks = inputLen/16;
150 #ifdef USE_SSE
151 if (AES_NI)
152 {
153 blockEncryptSSE(input,numBlocks,outBuffer);
154 return;
155 }
156 #endif
157
158 byte *prevBlock = m_initVector;
159 for(size_t i = numBlocks;i > 0;i--)
160 {
161 byte block[16];
162 if (CBCMode)
163 Xor128(block,prevBlock,input);
164 else
165 Copy128(block,input);
166
167 byte temp[4][4];
168
169 Xor128(temp,block,m_expandedKey[0]);
170 Xor128(outBuffer, T1[temp[0][0]],T2[temp[1][1]],T3[temp[2][2]],T4[temp[3][3]]);
171 Xor128(outBuffer+4, T1[temp[1][0]],T2[temp[2][1]],T3[temp[3][2]],T4[temp[0][3]]);
172 Xor128(outBuffer+8, T1[temp[2][0]],T2[temp[3][1]],T3[temp[0][2]],T4[temp[1][3]]);
173 Xor128(outBuffer+12,T1[temp[3][0]],T2[temp[0][1]],T3[temp[1][2]],T4[temp[2][3]]);
174
175 for(int r = 1; r < m_uRounds-1; r++)
176 {
177 Xor128(temp,outBuffer,m_expandedKey[r]);
178 Xor128(outBuffer, T1[temp[0][0]],T2[temp[1][1]],T3[temp[2][2]],T4[temp[3][3]]);
179 Xor128(outBuffer+4, T1[temp[1][0]],T2[temp[2][1]],T3[temp[3][2]],T4[temp[0][3]]);
180 Xor128(outBuffer+8, T1[temp[2][0]],T2[temp[3][1]],T3[temp[0][2]],T4[temp[1][3]]);
181 Xor128(outBuffer+12,T1[temp[3][0]],T2[temp[0][1]],T3[temp[1][2]],T4[temp[2][3]]);
182 }
183 Xor128(temp,outBuffer,m_expandedKey[m_uRounds-1]);
184 outBuffer[ 0] = T1[temp[0][0]][1];
185 outBuffer[ 1] = T1[temp[1][1]][1];
186 outBuffer[ 2] = T1[temp[2][2]][1];
187 outBuffer[ 3] = T1[temp[3][3]][1];
188 outBuffer[ 4] = T1[temp[1][0]][1];
189 outBuffer[ 5] = T1[temp[2][1]][1];
190 outBuffer[ 6] = T1[temp[3][2]][1];
191 outBuffer[ 7] = T1[temp[0][3]][1];
192 outBuffer[ 8] = T1[temp[2][0]][1];
193 outBuffer[ 9] = T1[temp[3][1]][1];
194 outBuffer[10] = T1[temp[0][2]][1];
195 outBuffer[11] = T1[temp[1][3]][1];
196 outBuffer[12] = T1[temp[3][0]][1];
197 outBuffer[13] = T1[temp[0][1]][1];
198 outBuffer[14] = T1[temp[1][2]][1];
199 outBuffer[15] = T1[temp[2][3]][1];
200 Xor128(outBuffer,outBuffer,m_expandedKey[m_uRounds]);
201 prevBlock=outBuffer;
202
203 outBuffer += 16;
204 input += 16;
205 }
206 Copy128(m_initVector,prevBlock);
207 }
208
209
210 #ifdef USE_SSE
211 void Rijndael::blockEncryptSSE(const byte *input,size_t numBlocks,byte *outBuffer)
212 {
213 __m128i v = _mm_loadu_si128((__m128i*)m_initVector);
214 __m128i *src=(__m128i*)input;
215 __m128i *dest=(__m128i*)outBuffer;
216 __m128i *rkey=(__m128i*)m_expandedKey;
217 while (numBlocks > 0)
218 {
219 __m128i d = _mm_loadu_si128(src++);
220 if (CBCMode)
221 v = _mm_xor_si128(v, d);
222 else
223 v = d;
224 __m128i r0 = _mm_loadu_si128(rkey);
225 v = _mm_xor_si128(v, r0);
226
227 for (int i=1; i<m_uRounds; i++)
228 {
229 __m128i ri = _mm_loadu_si128(rkey + i);
230 v = _mm_aesenc_si128(v, ri);
231 }
232
233 __m128i rl = _mm_loadu_si128(rkey + m_uRounds);
234 v = _mm_aesenclast_si128(v, rl);
235 _mm_storeu_si128(dest++,v);
236 numBlocks--;
237 }
238 _mm_storeu_si128((__m128i*)m_initVector,v);
239 }
240 #endif
241
242
243 void Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
244 {
245 if (inputLen <= 0)
246 return;
247
248 size_t numBlocks=inputLen/16;
249 #ifdef USE_SSE
250 if (AES_NI)
251 {
252 blockDecryptSSE(input,numBlocks,outBuffer);
253 return;
254 }
255 #endif
256
257 byte block[16], iv[4][4];
258 memcpy(iv,m_initVector,16);
259
260 for (size_t i = numBlocks; i > 0; i--)
261 {
262 byte temp[4][4];
263
264 Xor128(temp,input,m_expandedKey[m_uRounds]);
265
266 Xor128(block, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
267 Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
268 Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
269 Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
270
271 for(int r = m_uRounds-1; r > 1; r--)
272 {
273 Xor128(temp,block,m_expandedKey[r]);
274 Xor128(block, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
275 Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
276 Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
277 Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
278 }
279
280 Xor128(temp,block,m_expandedKey[1]);
281 block[ 0] = S5[temp[0][0]];
282 block[ 1] = S5[temp[3][1]];
283 block[ 2] = S5[temp[2][2]];
284 block[ 3] = S5[temp[1][3]];
285 block[ 4] = S5[temp[1][0]];
286 block[ 5] = S5[temp[0][1]];
287 block[ 6] = S5[temp[3][2]];
288 block[ 7] = S5[temp[2][3]];
289 block[ 8] = S5[temp[2][0]];
290 block[ 9] = S5[temp[1][1]];
291 block[10] = S5[temp[0][2]];
292 block[11] = S5[temp[3][3]];
293 block[12] = S5[temp[3][0]];
294 block[13] = S5[temp[2][1]];
295 block[14] = S5[temp[1][2]];
296 block[15] = S5[temp[0][3]];
297 Xor128(block,block,m_expandedKey[0]);
298
299 if (CBCMode)
300 Xor128(block,block,iv);
301
302 Copy128((byte*)iv,input);
303 Copy128(outBuffer,block);
304
305 input += 16;
306 outBuffer += 16;
307 }
308
309 memcpy(m_initVector,iv,16);
310 }
311
312
313 #ifdef USE_SSE
314 void Rijndael::blockDecryptSSE(const byte *input, size_t numBlocks, byte *outBuffer)
315 {
316 __m128i initVector = _mm_loadu_si128((__m128i*)m_initVector);
317 __m128i *src=(__m128i*)input;
318 __m128i *dest=(__m128i*)outBuffer;
319 __m128i *rkey=(__m128i*)m_expandedKey;
320 while (numBlocks > 0)
321 {
322 __m128i rl = _mm_loadu_si128(rkey + m_uRounds);
323 __m128i d = _mm_loadu_si128(src++);
324 __m128i v = _mm_xor_si128(rl, d);
325
326 for (int i=m_uRounds-1; i>0; i--)
327 {
328 __m128i ri = _mm_loadu_si128(rkey + i);
329 v = _mm_aesdec_si128(v, ri);
330 }
331
332 __m128i r0 = _mm_loadu_si128(rkey);
333 v = _mm_aesdeclast_si128(v, r0);
334
335 if (CBCMode)
336 v = _mm_xor_si128(v, initVector);
337 initVector = d;
338 _mm_storeu_si128(dest++,v);
339 numBlocks--;
340 }
341 _mm_storeu_si128((__m128i*)m_initVector,initVector);
342 }
343 #endif
344
345
346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
347 // ALGORITHM
348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
349
350
351 void Rijndael::keySched(byte key[_MAX_KEY_COLUMNS][4])
352 {
353 int j,rconpointer = 0;
354
355 // Calculate the necessary round keys
356 // The number of calculations depends on keyBits and blockBits
357 int uKeyColumns = m_uRounds - 6;
358
359 byte tempKey[_MAX_KEY_COLUMNS][4];
360
361 // Copy the input key to the temporary key matrix
362
363 memcpy(tempKey,key,sizeof(tempKey));
364
365 int r = 0;
366 int t = 0;
367
368 // copy values into round key array
369 for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
370 {
371 for(;(j < uKeyColumns) && (t < 4); j++, t++)
372 for (int k=0;k<4;k++)
373 m_expandedKey[r][t][k]=tempKey[j][k];
374
375 if(t == 4)
376 {
377 r++;
378 t = 0;
379 }
380 }
381
382 while(r <= m_uRounds)
383 {
384 tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
385 tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
386 tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
387 tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
388 tempKey[0][0] ^= rcon[rconpointer++];
389
390 if (uKeyColumns != 8)
391 for(j = 1; j < uKeyColumns; j++)
392 for (int k=0;k<4;k++)
393 tempKey[j][k] ^= tempKey[j-1][k];
394 else
395 {
396 for(j = 1; j < uKeyColumns/2; j++)
397 for (int k=0;k<4;k++)
398 tempKey[j][k] ^= tempKey[j-1][k];
399
400 tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
401 tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
402 tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
403 tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
404 for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
405 for (int k=0;k<4;k++)
406 tempKey[j][k] ^= tempKey[j-1][k];
407 }
408 for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
409 {
410 for(; (j < uKeyColumns) && (t < 4); j++, t++)
411 for (int k=0;k<4;k++)
412 m_expandedKey[r][t][k] = tempKey[j][k];
413 if(t == 4)
414 {
415 r++;
416 t = 0;
417 }
418 }
419 }
420 }
421
422 void Rijndael::keyEncToDec()
423 {
424 for(int r = 1; r < m_uRounds; r++)
425 {
426 byte n_expandedKey[4][4];
427 for (int i = 0; i < 4; i++)
428 for (int j = 0; j < 4; j++)
429 {
430 byte *w=m_expandedKey[r][j];
431 n_expandedKey[j][i]=U1[w[0]][i]^U2[w[1]][i]^U3[w[2]][i]^U4[w[3]][i];
432 }
433 memcpy(m_expandedKey[r],n_expandedKey,sizeof(m_expandedKey[0]));
434 }
435 }
436
437
438 static byte gmul(byte a, byte b) // Galois field "peasant's algorithm" multiplication.
439 {
440 const byte poly=0x1b; // Lower byte of AES 0x11b irreducible polynomial.
441 byte result = 0;
442 while (b>0)
443 {
444 if ((b & 1) != 0)
445 result ^= a;
446 a = (a & 0x80) ? (a<<1)^poly : a<<1;
447 b >>= 1;
448 }
449 return result;
450 }
451
452
453 // 2021-09-24: changed to slower and simpler code without interim tables.
454 // It is still fast enough for our purpose.
455 void Rijndael::GenerateTables()
456 {
457 for (int I=0;I<256;I++)
458 S5[S[I]]=I;
459
460 for (int I=0;I<256;I++)
461 {
462 byte s=S[I];
463 T1[I][1]=T1[I][2]=T2[I][2]=T2[I][3]=T3[I][0]=T3[I][3]=T4[I][0]=T4[I][1]=s;
464 T1[I][0]=T2[I][1]=T3[I][2]=T4[I][3]=gmul(s,2);
465 T1[I][3]=T2[I][0]=T3[I][1]=T4[I][2]=gmul(s,3);
466
467 byte b=S5[I];
468 U1[b][3]=U2[b][0]=U3[b][1]=U4[b][2]=T5[I][3]=T6[I][0]=T7[I][1]=T8[I][2]=gmul(b,0xb);
469 U1[b][1]=U2[b][2]=U3[b][3]=U4[b][0]=T5[I][1]=T6[I][2]=T7[I][3]=T8[I][0]=gmul(b,0x9);
470 U1[b][2]=U2[b][3]=U3[b][0]=U4[b][1]=T5[I][2]=T6[I][3]=T7[I][0]=T8[I][1]=gmul(b,0xd);
471 U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[I][0]=T6[I][1]=T7[I][2]=T8[I][3]=gmul(b,0xe);
472 }
473 }
474
475
476 #if 0
477 static void TestRijndael();
478 struct TestRij {TestRij() {TestRijndael();exit(0);}} GlobalTestRij;
479
480 // Test CBC encryption according to NIST 800-38A.
481 void TestRijndael()
482 {
483 byte IV[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
484 byte PT[64]={
485 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
486 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
487 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,
488 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10,
489 };
490
491 byte Key128[16]={0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c};
492 byte Chk128[16]={0x3f,0xf1,0xca,0xa1,0x68,0x1f,0xac,0x09,0x12,0x0e,0xca,0x30,0x75,0x86,0xe1,0xa7};
493 byte Key192[24]={0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52,0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5,0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b};
494 byte Chk192[16]={0x08,0xb0,0xe2,0x79,0x88,0x59,0x88,0x81,0xd9,0x20,0xa9,0xe6,0x4f,0x56,0x15,0xcd};
495 byte Key256[32]={0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};
496 byte Chk256[16]={0xb2,0xeb,0x05,0xe2,0xc3,0x9b,0xe9,0xfc,0xda,0x6c,0x19,0x07,0x8c,0x6a,0x9d,0x1b};
497 byte *Key[3]={Key128,Key192,Key256};
498 byte *Chk[3]={Chk128,Chk192,Chk256};
499
500 Rijndael rij; // Declare outside of loop to test re-initialization.
501 for (uint L=0;L<3;L++)
502 {
503 byte Out[16];
504 wchar Str[sizeof(Out)*2+1];
505
506 uint KeyLength=128+L*64;
507 rij.Init(true,Key[L],KeyLength,IV);
508 for (uint I=0;I<sizeof(PT);I+=16)
509 rij.blockEncrypt(PT+I,16,Out);
510 BinToHex(Chk[L],16,NULL,Str,ASIZE(Str));
511 mprintf(L"\nAES-%d expected: %s",KeyLength,Str);
512 BinToHex(Out,sizeof(Out),NULL,Str,ASIZE(Str));
513 mprintf(L"\nAES-%d result: %s",KeyLength,Str);
514 if (memcmp(Out,Chk[L],16)==0)
515 mprintf(L" OK");
516 else
517 {
518 mprintf(L" FAILED");
519 getchar();
520 }
521 }
522 }
523 #endif