/* Aes.c -- AES encryption / decryption
2017-01-24 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Aes.h"
#include "CpuArch.h"
static UInt32 T[256 * 4 ];
static const Byte Sbox[256 ] = {
0 x63, 0 x7c, 0 x77, 0 x7b, 0 xf2, 0 x6b, 0 x6f, 0 xc5, 0 x30, 0 x01, 0 x67, 0 x2b, 0 xfe, 0 xd7, 0 xab, 0 x76,
0 xca, 0 x82, 0 xc9, 0 x7d, 0 xfa, 0 x59, 0 x47, 0 xf0, 0 xad, 0 xd4, 0 xa2, 0 xaf, 0 x9c, 0 xa4, 0 x72, 0 xc0,
0 xb7, 0 xfd, 0 x93, 0 x26, 0 x36, 0 x3f, 0 xf7, 0 xcc, 0 x34, 0 xa5, 0 xe5, 0 xf1, 0 x71, 0 xd8, 0 x31, 0 x15,
0 x04, 0 xc7, 0 x23, 0 xc3, 0 x18, 0 x96, 0 x05, 0 x9a, 0 x07, 0 x12, 0 x80, 0 xe2, 0 xeb, 0 x27, 0 xb2, 0 x75,
0 x09, 0 x83, 0 x2c, 0 x1a, 0 x1b, 0 x6e, 0 x5a, 0 xa0, 0 x52, 0 x3b, 0 xd6, 0 xb3, 0 x29, 0 xe3, 0 x2f, 0 x84,
0 x53, 0 xd1, 0 x00, 0 xed, 0 x20, 0 xfc, 0 xb1, 0 x5b, 0 x6a, 0 xcb, 0 xbe, 0 x39, 0 x4a, 0 x4c, 0 x58, 0 xcf,
0 xd0, 0 xef, 0 xaa, 0 xfb, 0 x43, 0 x4d, 0 x33, 0 x85, 0 x45, 0 xf9, 0 x02, 0 x7f, 0 x50, 0 x3c, 0 x9f, 0 xa8,
0 x51, 0 xa3, 0 x40, 0 x8f, 0 x92, 0 x9d, 0 x38, 0 xf5, 0 xbc, 0 xb6, 0 xda, 0 x21, 0 x10, 0 xff, 0 xf3, 0 xd2,
0 xcd, 0 x0c, 0 x13, 0 xec, 0 x5f, 0 x97, 0 x44, 0 x17, 0 xc4, 0 xa7, 0 x7e, 0 x3d, 0 x64, 0 x5d, 0 x19, 0 x73,
0 x60, 0 x81, 0 x4f, 0 xdc, 0 x22, 0 x2a, 0 x90, 0 x88, 0 x46, 0 xee, 0 xb8, 0 x14, 0 xde, 0 x5e, 0 x0b, 0 xdb,
0 xe0, 0 x32, 0 x3a, 0 x0a, 0 x49, 0 x06, 0 x24, 0 x5c, 0 xc2, 0 xd3, 0 xac, 0 x62, 0 x91, 0 x95, 0 xe4, 0 x79,
0 xe7, 0 xc8, 0 x37, 0 x6d, 0 x8d, 0 xd5, 0 x4e, 0 xa9, 0 x6c, 0 x56, 0 xf4, 0 xea, 0 x65, 0 x7a, 0 xae, 0 x08,
0 xba, 0 x78, 0 x25, 0 x2e, 0 x1c, 0 xa6, 0 xb4, 0 xc6, 0 xe8, 0 xdd, 0 x74, 0 x1f, 0 x4b, 0 xbd, 0 x8b, 0 x8a,
0 x70, 0 x3e, 0 xb5, 0 x66, 0 x48, 0 x03, 0 xf6, 0 x0e, 0 x61, 0 x35, 0 x57, 0 xb9, 0 x86, 0 xc1, 0 x1d, 0 x9e,
0 xe1, 0 xf8, 0 x98, 0 x11, 0 x69, 0 xd9, 0 x8e, 0 x94, 0 x9b, 0 x1e, 0 x87, 0 xe9, 0 xce, 0 x55, 0 x28, 0 xdf,
0 x8c, 0 xa1, 0 x89, 0 x0d, 0 xbf, 0 xe6, 0 x42, 0 x68, 0 x41, 0 x99, 0 x2d, 0 x0f, 0 xb0, 0 x54, 0 xbb, 0 x16};
void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
AES_CODE_FUNC g_AesCbc_Encode;
AES_CODE_FUNC g_AesCbc_Decode;
AES_CODE_FUNC g_AesCtr_Code;
static UInt32 D[256 * 4 ];
static Byte InvS[256 ];
static const Byte Rcon[11 ] = { 0 x00, 0 x01, 0 x02, 0 x04, 0 x08, 0 x10, 0 x20, 0 x40, 0 x80, 0 x1b, 0 x36 };
#define xtime(x) ((((x) << 1 ) ^ (((x) & 0 x80) != 0 ? 0 x1B : 0 )) & 0 xFF)
#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8 ) | ((UInt32)(a2) << 16 ) | ((UInt32)(a3) << 24 ))
#define gb0(x) ( (x) & 0 xFF)
#define gb1(x) (((x) >> ( 8 )) & 0 xFF)
#define gb2(x) (((x) >> (16 )) & 0 xFF)
#define gb3(x) (((x) >> (24 )))
#define gb(n, x) gb ## n(x)
#define TT(x) (T + (x << 8 ))
#define DD(x) (D + (x << 8 ))
void AesGenTables(void )
{
unsigned i;
for (i = 0 ; i < 256 ; i++)
InvS[Sbox[i]] = (Byte)i;
for (i = 0 ; i < 256 ; i++)
{
{
UInt32 a1 = Sbox[i];
UInt32 a2 = xtime(a1);
UInt32 a3 = a2 ^ a1;
TT(0 )[i] = Ui32(a2, a1, a1, a3);
TT(1 )[i] = Ui32(a3, a2, a1, a1);
TT(2 )[i] = Ui32(a1, a3, a2, a1);
TT(3 )[i] = Ui32(a1, a1, a3, a2);
}
{
UInt32 a1 = InvS[i];
UInt32 a2 = xtime(a1);
UInt32 a4 = xtime(a2);
UInt32 a8 = xtime(a4);
UInt32 a9 = a8 ^ a1;
UInt32 aB = a8 ^ a2 ^ a1;
UInt32 aD = a8 ^ a4 ^ a1;
UInt32 aE = a8 ^ a4 ^ a2;
DD(0 )[i] = Ui32(aE, a9, aD, aB);
DD(1 )[i] = Ui32(aB, aE, a9, aD);
DD(2 )[i] = Ui32(aD, aB, aE, a9);
DD(3 )[i] = Ui32(a9, aD, aB, aE);
}
}
g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code;
#ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported())
{
g_AesCbc_Encode = AesCbc_Encode_Intel;
g_AesCbc_Decode = AesCbc_Decode_Intel;
g_AesCtr_Code = AesCtr_Code_Intel;
}
#endif
}
#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3 ])]
#define HT4(m, i, s, p) m[i] = \
HT(i, 0 , s) ^ \
HT(i, 1 , s) ^ \
HT(i, 2 , s) ^ \
HT(i, 3 , s) ^ w[p + i]
#define HT16(m, s, p) \
HT4(m, 0 , s, p); \
HT4(m, 1 , s, p); \
HT4(m, 2 , s, p); \
HT4(m, 3 , s, p); \
#define FT(i, x) Sbox[gb(x, m[(i + x) & 3 ])]
#define FT4(i) dest[i] = Ui32(FT(i, 0 ), FT(i, 1 ), FT(i, 2 ), FT(i, 3 )) ^ w[i];
#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3 ])]
#define HD4(m, i, s, p) m[i] = \
HD(i, 0 , s) ^ \
HD(i, 1 , s) ^ \
HD(i, 2 , s) ^ \
HD(i, 3 , s) ^ w[p + i];
#define HD16(m, s, p) \
HD4(m, 0 , s, p); \
HD4(m, 1 , s, p); \
HD4(m, 2 , s, p); \
HD4(m, 3 , s, p); \
#define FD(i, x) InvS[gb(x, m[(i - x) & 3 ])]
#define FD4(i) dest[i] = Ui32(FD(i, 0 ), FD(i, 1 ), FD(i, 2 ), FD(i, 3 )) ^ w[i];
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
{
unsigned i, wSize;
wSize = keySize + 28 ;
keySize /= 4 ;
w[0 ] = ((UInt32)keySize / 2 ) + 3 ;
w += 4 ;
for (i = 0 ; i < keySize; i++, key += 4 )
w[i] = GetUi32(key);
for (; i < wSize; i++)
{
UInt32 t = w[(size_t)i - 1 ];
unsigned rem = i % keySize;
if (rem == 0 )
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
else if (keySize > 6 && rem == 4 )
t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
w[i] = w[i - keySize] ^ t;
}
}
void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
{
unsigned i, num;
Aes_SetKey_Enc(w, key, keySize);
num = keySize + 20 ;
w += 8 ;
for (i = 0 ; i < num; i++)
{
UInt32 r = w[i];
w[i] =
DD(0 )[Sbox[gb0(r)]] ^
DD(1 )[Sbox[gb1(r)]] ^
DD(2 )[Sbox[gb2(r)]] ^
DD(3 )[Sbox[gb3(r)]];
}
}
/* Aes_Encode and Aes_Decode functions work with little-endian words.
src and dest are pointers to 4 UInt32 words.
src and dest can point to same block */
static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{
UInt32 s[4 ];
UInt32 m[4 ];
UInt32 numRounds2 = w[0 ];
w += 4 ;
s[0 ] = src[0 ] ^ w[0 ];
s[1 ] = src[1 ] ^ w[1 ];
s[2 ] = src[2 ] ^ w[2 ];
s[3 ] = src[3 ] ^ w[3 ];
w += 4 ;
for (;;)
{
HT16(m, s, 0 );
if (--numRounds2 == 0 )
break ;
HT16(s, m, 4 );
w += 8 ;
}
w += 4 ;
FT4(0 ); FT4(1 ); FT4(2 ); FT4(3 );
}
static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{
UInt32 s[4 ];
UInt32 m[4 ];
UInt32 numRounds2 = w[0 ];
w += 4 + numRounds2 * 8 ;
s[0 ] = src[0 ] ^ w[0 ];
s[1 ] = src[1 ] ^ w[1 ];
s[2 ] = src[2 ] ^ w[2 ];
s[3 ] = src[3 ] ^ w[3 ];
for (;;)
{
w -= 8 ;
HD16(m, s, 4 );
if (--numRounds2 == 0 )
break ;
HD16(s, m, 0 );
}
FD4(0 ); FD4(1 ); FD4(2 ); FD4(3 );
}
void AesCbc_Init(UInt32 *p, const Byte *iv)
{
unsigned i;
for (i = 0 ; i < 4 ; i++)
p[i] = GetUi32(iv + i * 4 );
}
void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
{
for (; numBlocks != 0 ; numBlocks--, data += AES_BLOCK_SIZE)
{
p[0 ] ^= GetUi32(data);
p[1 ] ^= GetUi32(data + 4 );
p[2 ] ^= GetUi32(data + 8 );
p[3 ] ^= GetUi32(data + 12 );
Aes_Encode(p + 4 , p, p);
SetUi32(data, p[0 ]);
SetUi32(data + 4 , p[1 ]);
SetUi32(data + 8 , p[2 ]);
SetUi32(data + 12 , p[3 ]);
}
}
void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
{
UInt32 in[4 ], out[4 ];
for (; numBlocks != 0 ; numBlocks--, data += AES_BLOCK_SIZE)
{
in[0 ] = GetUi32(data);
in[1 ] = GetUi32(data + 4 );
in[2 ] = GetUi32(data + 8 );
in[3 ] = GetUi32(data + 12 );
Aes_Decode(p + 4 , out, in);
SetUi32(data, p[0 ] ^ out[0 ]);
SetUi32(data + 4 , p[1 ] ^ out[1 ]);
SetUi32(data + 8 , p[2 ] ^ out[2 ]);
SetUi32(data + 12 , p[3 ] ^ out[3 ]);
p[0 ] = in[0 ];
p[1 ] = in[1 ];
p[2 ] = in[2 ];
p[3 ] = in[3 ];
}
}
void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
{
for (; numBlocks != 0 ; numBlocks--)
{
UInt32 temp[4 ];
unsigned i;
if (++p[0 ] == 0 )
p[1 ]++;
Aes_Encode(p + 4 , temp, p);
for (i = 0 ; i < 4 ; i++, data += 4 )
{
UInt32 t = temp[i];
#ifdef MY_CPU_LE_UNALIGN
*((UInt32 *)data) ^= t;
#else
data[0 ] ^= (t & 0 xFF);
data[1 ] ^= ((t >> 8 ) & 0 xFF);
data[2 ] ^= ((t >> 16 ) & 0 xFF);
data[3 ] ^= ((t >> 24 ));
#endif
}
}
}
Messung V0.5 in Prozent C=91 H=92 G=91
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-06)
¤
*© Formatika GbR, Deutschland