On 21/10/26 08:46, Stian Halseth wrote:
Implement the AES key expansion instructions according to
OSA (Oracle SPARC Architecture) 2011 sections 7.3 and 7.4
and set the AES bit in the CFR.
4-operand form (7.3):
- AES_KEXPAND1
3-operand form (7.4):
- AES_KEXPAND0
- AES_KEXPAND2
Like the AES round instructions, they are gated behind the
crypto CPU feature and disabled for sparc32.
~ "The AES feature is now complete and exposed in the Compatibility
Feature Register".
Signed-off-by: Stian Halseth <[email protected]>
---
target/sparc/crypto_helper.c | 58 ++++++++++++++++++++++++++++++++++++
target/sparc/helper.h | 3 ++
target/sparc/insns.decode | 7 +++++
target/sparc/translate.c | 30 ++++++++++++++++++-
4 files changed, 97 insertions(+), 1 deletion(-)
/*
* SPARC four-operand AES round (Section 7.3).
@@ -87,3 +88,60 @@ uint64_t helper_aes_dround23_l(uint64_t key, uint64_t s2,
uint64_t s3)
{
return aes_round(key, s2, s3, 1, true, true);
}
+
+/* Combine the transformed word with the two words in rs1. */
+static uint64_t aes_kexpand(uint64_t rs1, uint32_t t)
+{
+ uint32_t hi = (rs1 >> 32) ^ t;
+ uint32_t lo = (uint32_t)rs1 ^ hi;
+
+ return ((uint64_t)hi << 32) | lo;
Alternatively:
return deposit64(lo, 32, 32, hi);
+}
+
+/* Apply the AES S-box to each byte, preserving byte positions. */
+static uint32_t aes_subword(uint32_t x)
+{
+ return ((uint32_t)AES_sbox[x >> 24] << 24) |
+ ((uint32_t)AES_sbox[(x >> 16) & 0xff] << 16) |
+ ((uint32_t)AES_sbox[(x >> 8) & 0xff] << 8) |
+ (uint32_t)AES_sbox[x & 0xff];
+}
We could move that method to include/crypto/aes.h and re-use
it in RISCV's vaeskf1_vi / vaeskf2_vi helpers.
+
+/*
+ * AES Cryptographic Operations 4-operand (Section 7.3)
+ * AES key expansion with RotWord, SubWord, and RCON.
+ */
+uint64_t helper_aes_kexpand1(uint64_t rs1, uint64_t rs2, uint32_t imm)
+{
+ static const uint8_t rcon[10] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x80, 0x1b, 0x36,
This table is also used by RISCV aes64ks1i, vaeskf1_vi, and vaeskf2_vi,
so we could add a common const uint8_t AES_rcon[10] in include/crypto/aes.h:
-- >8 --
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -29,6 +29,7 @@ void AES_decrypt(const unsigned char *in, unsigned
char *out,
extern const uint8_t AES_sbox[256];
extern const uint8_t AES_isbox[256];
+extern const uint8_t AES_rcon[10];
---
and in crypto/aes.c:
@@ -944,6 +944,11 @@
};
+const uint8_t AES_rcon[10] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x80, 0x1b, 0x36,
+};
+
+ };
+ uint32_t t = rol32((uint32_t)rs2, 8);
+
+ t = aes_subword(t);
+
+ if (imm < ARRAY_SIZE(rcon)) {
+ t ^= (uint32_t)rcon[imm] << 24;
+ }
+
+ return aes_kexpand(rs1, t);
+}
+
+/*
+ * AES Cryptographic Operations 3-operand (Section 7.4)
+ * AES key expansion with SubWord, without RotWord or RCON.
+ */
+uint64_t helper_aes_kexpand0(uint64_t rs1, uint64_t rs2)
+{
+ return aes_kexpand(rs1, aes_subword(rs2));
+}
+
+/*
+ * AES Cryptographic Operations 3-operand (Section 7.4)
+ * AES key expansion without SubWord, RotWord, or RCON.
+ */
+uint64_t helper_aes_kexpand2(uint64_t rs1, uint64_t rs2)
+{
+ return aes_kexpand(rs1, (uint32_t)rs2);
+}
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>