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]>


Reply via email to