new file mode 100644
@@ -0,0 +1,139 @@
+/*
+ * RISC-V Crypto Emulation Helpers for QEMU.
+ *
+ * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com
+ * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "crypto/aes.h"
+#include "crypto/sm4.h"
+
+#define AES_XTIME(a) \
+ ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
+
+#define AES_GFMUL(a, b) (( \
+ (((b) & 0x1) ? (a) : 0) ^ \
+ (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
+ (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
+ (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
+
+#define BY(X, I) ((X >> (8 * I)) & 0xFF)
+
+#define AES_SHIFROWS_LO(RS1, RS2) ( \
+ (((RS1 >> 24) & 0xFF) << 56) | (((RS2 >> 48) & 0xFF) << 48) | \
+ (((RS2 >> 8) & 0xFF) << 40) | (((RS1 >> 32) & 0xFF) << 32) | \
+ (((RS2 >> 56) & 0xFF) << 24) | (((RS2 >> 16) & 0xFF) << 16) | \
+ (((RS1 >> 40) & 0xFF) << 8) | (((RS1 >> 0) & 0xFF) << 0))
+
+#define AES_INVSHIFROWS_LO(RS1, RS2) ( \
+ (((RS2 >> 24) & 0xFF) << 56) | (((RS2 >> 48) & 0xFF) << 48) | \
+ (((RS1 >> 8) & 0xFF) << 40) | (((RS1 >> 32) & 0xFF) << 32) | \
+ (((RS1 >> 56) & 0xFF) << 24) | (((RS2 >> 16) & 0xFF) << 16) | \
+ (((RS2 >> 40) & 0xFF) << 8) | (((RS1 >> 0) & 0xFF) << 0))
+
+#define AES_MIXBYTE(COL, B0, B1, B2, B3) ( \
+ BY(COL, B3) ^ BY(COL, B2) ^ AES_GFMUL(BY(COL, B1), 3) ^ \
+ AES_GFMUL(BY(COL, B0), 2))
+
+#define AES_MIXCOLUMN(COL) ( \
+ AES_MIXBYTE(COL, 3, 0, 1, 2) << 24 | \
+ AES_MIXBYTE(COL, 2, 3, 0, 1) << 16 | \
+ AES_MIXBYTE(COL, 1, 2, 3, 0) << 8 | AES_MIXBYTE(COL, 0, 1, 2, 3) << 0)
+
+#define AES_INVMIXBYTE(COL, B0, B1, B2, B3) ( \
+ AES_GFMUL(BY(COL, B3), 0x9) ^ AES_GFMUL(BY(COL, B2), 0xd) ^ \
+ AES_GFMUL(BY(COL, B1), 0xb) ^ AES_GFMUL(BY(COL, B0), 0xe))
+
+#define AES_INVMIXCOLUMN(COL) ( \
+ AES_INVMIXBYTE(COL, 3, 0, 1, 2) << 24 | \
+ AES_INVMIXBYTE(COL, 2, 3, 0, 1) << 16 | \
+ AES_INVMIXBYTE(COL, 1, 2, 3, 0) << 8 | \
+ AES_INVMIXBYTE(COL, 0, 1, 2, 3) << 0)
+
+static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
+{
+ uint32_t u;
+
+ if (fwd) {
+ u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
+ (AES_GFMUL(x, 2) << 0);
+ } else {
+ u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
+ (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
+ }
+ return u;
+}
+
+#define sext_xlen(x) (target_ulong)(int32_t)(x)
+
+static inline target_ulong aes32_operation(target_ulong bs, target_ulong rs1,
+ target_ulong rs2, bool enc,
+ bool mix)
+{
+ uint8_t shamt = bs << 3;
+ uint8_t si = rs2 >> shamt;
+ uint8_t so;
+ uint32_t mixed;
+ target_ulong res;
+
+ if (enc) {
+ so = AES_sbox[si];
+ if (mix) {
+ mixed = aes_mixcolumn_byte(so, true);
+ } else {
+ mixed = so;
+ }
+ } else {
+ so = AES_isbox[si];
+ if (mix) {
+ mixed = aes_mixcolumn_byte(so, false);
+ } else {
+ mixed = so;
+ }
+ }
+ mixed = (mixed << shamt) | (mixed >> (32 - shamt));
+ res = rs1 ^ mixed;
+
+ return sext_xlen(res);
+}
+
+target_ulong HELPER(aes32esmi)(target_ulong rs1, target_ulong rs2,
+ target_ulong bs)
+{
+ return aes32_operation(bs, rs1, rs2, true, true);
+}
+
+target_ulong HELPER(aes32esi)(target_ulong rs1, target_ulong rs2,
+ target_ulong bs)
+{
+ return aes32_operation(bs, rs1, rs2, true, false);
+}
+
+target_ulong HELPER(aes32dsmi)(target_ulong rs1, target_ulong rs2,
+ target_ulong bs)
+{
+ return aes32_operation(bs, rs1, rs2, false, true);
+}
+
+target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2,
+ target_ulong bs)
+{
+ return aes32_operation(bs, rs1, rs2, false, false);
+}
+#undef sext_xlen
@@ -1115,3 +1115,9 @@ DEF_HELPER_5(divu_i128, tl, env, tl, tl, tl, tl)
DEF_HELPER_5(divs_i128, tl, env, tl, tl, tl, tl)
DEF_HELPER_5(remu_i128, tl, env, tl, tl, tl, tl)
DEF_HELPER_5(rems_i128, tl, env, tl, tl, tl, tl)
+
+/* Crypto functions */
+DEF_HELPER_3(aes32esmi, tl, tl, tl, tl)
+DEF_HELPER_3(aes32esi, tl, tl, tl, tl)
+DEF_HELPER_3(aes32dsmi, tl, tl, tl, tl)
+DEF_HELPER_3(aes32dsi, tl, tl, tl, tl)
@@ -17,6 +17,7 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
# Fields:
+%bs 30:2
%rs3 27:5
%rs2 20:5
%rs1 15:5
@@ -91,6 +92,7 @@
# Formats 64:
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
+@k_aes .. ..... ..... ..... ... ..... ....... %bs %rs2 %rs1 %rd
# Formats 128:
@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
@@ -827,3 +829,10 @@ fcvt_l_h 1100010 00010 ..... ... ..... 1010011 @r2_rm
fcvt_lu_h 1100010 00011 ..... ... ..... 1010011 @r2_rm
fcvt_h_l 1101010 00010 ..... ... ..... 1010011 @r2_rm
fcvt_h_lu 1101010 00011 ..... ... ..... 1010011 @r2_rm
+
+# *** RV32 Zknd Standard Extension ***
+aes32dsmi .. 10111 ..... ..... 000 ..... 0110011 @k_aes
+aes32dsi .. 10101 ..... ..... 000 ..... 0110011 @k_aes
+# *** RV32 Zkne Standard Extension ***
+aes32esmi .. 10011 ..... ..... 000 ..... 0110011 @k_aes
+aes32esi .. 10001 ..... ..... 000 ..... 0110011 @k_aes
new file mode 100644
@@ -0,0 +1,94 @@
+/*
+ * RISC-V translation routines for the Zk[nd,ne,nh,sed,sh] Standard Extension.
+ *
+ * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com
+ * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZKND(ctx) do { \
+ if (!RISCV_CPU(ctx->cs)->cfg.ext_zknd) { \
+ return false; \
+ } \
+} while (0)
+
+#define REQUIRE_ZKNE(ctx) do { \
+ if (!RISCV_CPU(ctx->cs)->cfg.ext_zkne) { \
+ return false; \
+ } \
+} while (0)
+
+static bool trans_aes32esmi(DisasContext *ctx, arg_aes32esmi *a)
+{
+ REQUIRE_ZKNE(ctx);
+
+ TCGv bs = tcg_const_tl(a->bs);
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ gen_helper_aes32esmi(dest, src1, src2, bs);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ tcg_temp_free(bs);
+ return true;
+}
+
+static bool trans_aes32esi(DisasContext *ctx, arg_aes32esi *a)
+{
+ REQUIRE_ZKNE(ctx);
+
+ TCGv bs = tcg_const_tl(a->bs);
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ gen_helper_aes32esi(dest, src1, src2, bs);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ tcg_temp_free(bs);
+ return true;
+}
+
+static bool trans_aes32dsmi(DisasContext *ctx, arg_aes32dsmi *a)
+{
+ REQUIRE_ZKND(ctx);
+
+ TCGv bs = tcg_const_tl(a->bs);
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ gen_helper_aes32dsmi(dest, src1, src2, bs);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ tcg_temp_free(bs);
+ return true;
+}
+
+static bool trans_aes32dsi(DisasContext *ctx, arg_aes32dsi *a)
+{
+ REQUIRE_ZKND(ctx);
+
+ TCGv bs = tcg_const_tl(a->bs);
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ gen_helper_aes32dsi(dest, src1, src2, bs);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ tcg_temp_free(bs);
+ return true;
+}
@@ -18,7 +18,8 @@ riscv_ss.add(files(
'vector_helper.c',
'bitmanip_helper.c',
'translate.c',
- 'm128_helper.c'
+ 'm128_helper.c',
+ 'crypto_helper.c'
))
riscv_softmmu_ss = ss.source_set()
@@ -844,6 +844,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_rvv.c.inc"
#include "insn_trans/trans_rvb.c.inc"
#include "insn_trans/trans_rvzfh.c.inc"
+#include "insn_trans/trans_rvk.c.inc"
#include "insn_trans/trans_privileged.c.inc"
/* Include the auto-generated decoder for 16 bit insn */