|
|
|
@ -28,6 +28,8 @@ |
|
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
*/ |
|
|
|
#include "qemu/osdep.h" |
|
|
|
#include "qemu/bswap.h" |
|
|
|
#include "qemu/bitops.h" |
|
|
|
#include "crypto/aes.h" |
|
|
|
#include "crypto/aes-round.h" |
|
|
|
|
|
|
|
@ -1216,6 +1218,65 @@ static const u32 rcon[] = { |
|
|
|
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ |
|
|
|
}; |
|
|
|
|
|
|
|
/*
|
|
|
|
* Perform MixColumns. |
|
|
|
*/ |
|
|
|
static inline void |
|
|
|
aesenc_MC_swap(AESState *r, const AESState *st, bool swap) |
|
|
|
{ |
|
|
|
int swap_b = swap * 0xf; |
|
|
|
int swap_w = swap * 0x3; |
|
|
|
bool be = HOST_BIG_ENDIAN ^ swap; |
|
|
|
uint32_t t; |
|
|
|
|
|
|
|
/* Note that AES_mc_rot is encoded for little-endian. */ |
|
|
|
t = ( AES_mc_rot[st->b[swap_b ^ 0x0]] ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x1]], 8) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x2]], 16) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x3]], 24)); |
|
|
|
if (be) { |
|
|
|
t = bswap32(t); |
|
|
|
} |
|
|
|
r->w[swap_w ^ 0] = t; |
|
|
|
|
|
|
|
t = ( AES_mc_rot[st->b[swap_b ^ 0x4]] ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x5]], 8) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x6]], 16) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x7]], 24)); |
|
|
|
if (be) { |
|
|
|
t = bswap32(t); |
|
|
|
} |
|
|
|
r->w[swap_w ^ 1] = t; |
|
|
|
|
|
|
|
t = ( AES_mc_rot[st->b[swap_b ^ 0x8]] ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0x9]], 8) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0xA]], 16) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0xB]], 24)); |
|
|
|
if (be) { |
|
|
|
t = bswap32(t); |
|
|
|
} |
|
|
|
r->w[swap_w ^ 2] = t; |
|
|
|
|
|
|
|
t = ( AES_mc_rot[st->b[swap_b ^ 0xC]] ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0xD]], 8) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0xE]], 16) ^ |
|
|
|
rol32(AES_mc_rot[st->b[swap_b ^ 0xF]], 24)); |
|
|
|
if (be) { |
|
|
|
t = bswap32(t); |
|
|
|
} |
|
|
|
r->w[swap_w ^ 3] = t; |
|
|
|
} |
|
|
|
|
|
|
|
void aesenc_MC_gen(AESState *r, const AESState *st) |
|
|
|
{ |
|
|
|
aesenc_MC_swap(r, st, false); |
|
|
|
} |
|
|
|
|
|
|
|
void aesenc_MC_genrev(AESState *r, const AESState *st) |
|
|
|
{ |
|
|
|
aesenc_MC_swap(r, st, true); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Perform SubBytes + ShiftRows + AddRoundKey. |
|
|
|
*/ |
|
|
|
|