diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-06-02 01:49:21 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-07-08 07:30:17 +0100 |
commit | 04e1f30eedfe581c0c3b6bc6b6f5f76c65dc2c71 (patch) | |
tree | 1bd22fc5421d62f3f1a09348a3621546598c9435 | |
parent | 192fa84986a6e060f353ed491fe635ccd960876e (diff) |
crypto: Add aesenc_MC
Add a primitive for MixColumns.
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | crypto/aes.c | 61 | ||||
-rw-r--r-- | host/include/generic/host/crypto/aes-round.h | 2 | ||||
-rw-r--r-- | include/crypto/aes-round.h | 18 |
3 files changed, 81 insertions, 0 deletions
diff --git a/crypto/aes.c b/crypto/aes.c index 90274c3706..ec300cda0c 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -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" @@ -1217,6 +1219,65 @@ static const u32 rcon[] = { }; /* + * 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. */ static inline void diff --git a/host/include/generic/host/crypto/aes-round.h b/host/include/generic/host/crypto/aes-round.h index c9b9d732f0..1b82afc629 100644 --- a/host/include/generic/host/crypto/aes-round.h +++ b/host/include/generic/host/crypto/aes-round.h @@ -9,6 +9,8 @@ #define HAVE_AES_ACCEL false #define ATTR_AES_ACCEL +void aesenc_MC_accel(AESState *, const AESState *, bool) + QEMU_ERROR("unsupported accel"); void aesenc_SB_SR_AK_accel(AESState *, const AESState *, const AESState *, bool) QEMU_ERROR("unsupported accel"); diff --git a/include/crypto/aes-round.h b/include/crypto/aes-round.h index dcf098b97b..7d2be40a67 100644 --- a/include/crypto/aes-round.h +++ b/include/crypto/aes-round.h @@ -21,6 +21,24 @@ typedef union { #include "host/crypto/aes-round.h" /* + * Perform MixColumns. + */ + +void aesenc_MC_gen(AESState *ret, const AESState *st); +void aesenc_MC_genrev(AESState *ret, const AESState *st); + +static inline void aesenc_MC(AESState *r, const AESState *st, bool be) +{ + if (HAVE_AES_ACCEL) { + aesenc_MC_accel(r, st, be); + } else if (HOST_BIG_ENDIAN == be) { + aesenc_MC_gen(r, st); + } else { + aesenc_MC_genrev(r, st); + } +} + +/* * Perform SubBytes + ShiftRows + AddRoundKey. */ |