diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-06-02 02:01:23 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-07-08 07:30:17 +0100 |
commit | 5b41deb3108c48143d6697cd2dcde3f0b9a57c80 (patch) | |
tree | d408d36c44a2a234abbbcae66532711f2318bd54 | |
parent | 04e1f30eedfe581c0c3b6bc6b6f5f76c65dc2c71 (diff) |
crypto: Add aesdec_IMC
Add a primitive for InvMixColumns.
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | crypto/aes.c | 59 | ||||
-rw-r--r-- | host/include/generic/host/crypto/aes-round.h | 2 | ||||
-rw-r--r-- | include/crypto/aes-round.h | 18 |
3 files changed, 79 insertions, 0 deletions
diff --git a/crypto/aes.c b/crypto/aes.c index ec300cda0c..6c05d731f4 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -1323,6 +1323,65 @@ void aesenc_SB_SR_AK_genrev(AESState *r, const AESState *s, const AESState *k) } /* + * Perform InvMixColumns. + */ +static inline void +aesdec_IMC_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_imc is encoded for big-endian. */ + t = (AES_imc[st->b[swap_b ^ 0x0]][0] ^ + AES_imc[st->b[swap_b ^ 0x1]][1] ^ + AES_imc[st->b[swap_b ^ 0x2]][2] ^ + AES_imc[st->b[swap_b ^ 0x3]][3]); + if (!be) { + t = bswap32(t); + } + r->w[swap_w ^ 0] = t; + + t = (AES_imc[st->b[swap_b ^ 0x4]][0] ^ + AES_imc[st->b[swap_b ^ 0x5]][1] ^ + AES_imc[st->b[swap_b ^ 0x6]][2] ^ + AES_imc[st->b[swap_b ^ 0x7]][3]); + if (!be) { + t = bswap32(t); + } + r->w[swap_w ^ 1] = t; + + t = (AES_imc[st->b[swap_b ^ 0x8]][0] ^ + AES_imc[st->b[swap_b ^ 0x9]][1] ^ + AES_imc[st->b[swap_b ^ 0xA]][2] ^ + AES_imc[st->b[swap_b ^ 0xB]][3]); + if (!be) { + t = bswap32(t); + } + r->w[swap_w ^ 2] = t; + + t = (AES_imc[st->b[swap_b ^ 0xC]][0] ^ + AES_imc[st->b[swap_b ^ 0xD]][1] ^ + AES_imc[st->b[swap_b ^ 0xE]][2] ^ + AES_imc[st->b[swap_b ^ 0xF]][3]); + if (!be) { + t = bswap32(t); + } + r->w[swap_w ^ 3] = t; +} + +void aesdec_IMC_gen(AESState *r, const AESState *st) +{ + aesdec_IMC_swap(r, st, false); +} + +void aesdec_IMC_genrev(AESState *r, const AESState *st) +{ + aesdec_IMC_swap(r, st, true); +} + +/* * Perform InvSubBytes + InvShiftRows + 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 1b82afc629..335ec3f11e 100644 --- a/host/include/generic/host/crypto/aes-round.h +++ b/host/include/generic/host/crypto/aes-round.h @@ -15,6 +15,8 @@ void aesenc_SB_SR_AK_accel(AESState *, const AESState *, const AESState *, bool) QEMU_ERROR("unsupported accel"); +void aesdec_IMC_accel(AESState *, const AESState *, bool) + QEMU_ERROR("unsupported accel"); void aesdec_ISB_ISR_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 7d2be40a67..7be2cc0d8e 100644 --- a/include/crypto/aes-round.h +++ b/include/crypto/aes-round.h @@ -60,6 +60,24 @@ static inline void aesenc_SB_SR_AK(AESState *r, const AESState *st, } /* + * Perform InvMixColumns. + */ + +void aesdec_IMC_gen(AESState *ret, const AESState *st); +void aesdec_IMC_genrev(AESState *ret, const AESState *st); + +static inline void aesdec_IMC(AESState *r, const AESState *st, bool be) +{ + if (HAVE_AES_ACCEL) { + aesdec_IMC_accel(r, st, be); + } else if (HOST_BIG_ENDIAN == be) { + aesdec_IMC_gen(r, st); + } else { + aesdec_IMC_genrev(r, st); + } +} + +/* * Perform InvSubBytes + InvShiftRows + AddRoundKey. */ |