diff --git a/README.md b/README.md index 83604740a..70c486e9d 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ Supported RISC-V ISA features - Zvbb extension for vector basic bit-manipulation, v1.0 - Zvbc extension for vector carryless multiplication, v1.0 - Zvkb extension for vector cryptography bit-manipulation, v1.0 +- Zvkg extension for vector GCM/GMAC, v1.0 - Zvknha and Zvknhb extensions for vector cryptography NIST Suite: Vector SHA-2 Secure Hash, v1.0 - Machine, Supervisor, and User modes - Smcntrpmf extension for cycle and instret privilege mode filtering, v1.0 diff --git a/config/default.json b/config/default.json index cfcf80d5d..2f04bb281 100644 --- a/config/default.json +++ b/config/default.json @@ -174,6 +174,9 @@ "Zvbc" : { "supported" : true }, + "Zvkg" : { + "supported" : true + }, "Zvknha" : { "supported" : true }, diff --git a/model/CMakeLists.txt b/model/CMakeLists.txt index d594ae044..1f90eab81 100644 --- a/model/CMakeLists.txt +++ b/model/CMakeLists.txt @@ -88,6 +88,7 @@ foreach (xlen IN ITEMS 32 64) "riscv_insts_zicboz.sail" "riscv_insts_zvbb.sail" "riscv_insts_zvbc.sail" + "riscv_insts_zvkg.sail" "riscv_insts_zvknhab.sail" # Zimop and Zcmop should be at the end so they can be overridden by earlier extensions "riscv_insts_zimop.sail" diff --git a/model/arithmetic.sail b/model/arithmetic.sail index 78a5478fa..7238f858c 100644 --- a/model/arithmetic.sail +++ b/model/arithmetic.sail @@ -6,6 +6,15 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /*=======================================================================================*/ +/* Reverse bits in each byte */ +val brev8 : forall 'm, 'm >= 0 & mod('m, 8) == 0. (bits('m)) -> bits('m) +function brev8(input) = { + var output : bits('m) = zeros(); + foreach (i from 0 to ('m - 8) by 8) + output[i+7..i] = reverse_bits(input[i+7..i]); + output +} + /* Carry-less multiply. */ val carryless_mul : forall 'n, 'n > 0. (bits('n), bits('n)) -> bits(2 * 'n) function carryless_mul(a, b) = { diff --git a/model/riscv_extensions.sail b/model/riscv_extensions.sail index f0c83a51b..64a811f9d 100644 --- a/model/riscv_extensions.sail +++ b/model/riscv_extensions.sail @@ -179,6 +179,9 @@ function clause hartSupports(Ext_Zvkb) = config extensions.Zvkb.supported // Vector Carryless Multiplication enum clause extension = Ext_Zvbc function clause hartSupports(Ext_Zvbc) = config extensions.Zvbc.supported +// Vector GCM/GMAC +enum clause extension = Ext_Zvkg +function clause hartSupports(Ext_Zvkg) = config extensions.Zvkg.supported // NIST Suite: Vector SHA-2 Secure Hash enum clause extension = Ext_Zvknha function clause hartSupports(Ext_Zvknha) = config extensions.Zvknha.supported diff --git a/model/riscv_insts_zvkg.sail b/model/riscv_insts_zvkg.sail new file mode 100644 index 000000000..0b37653c7 --- /dev/null +++ b/model/riscv_insts_zvkg.sail @@ -0,0 +1,101 @@ +/*=======================================================================================*/ +/* This Sail RISC-V architecture model, comprising all files and */ +/* directories except where otherwise noted is subject the BSD */ +/* two-clause license in the LICENSE file. */ +/* */ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*=======================================================================================*/ + +function clause currentlyEnabled(Ext_Zvkg) = hartSupports(Ext_Zvkg) & currentlyEnabled(Ext_V) + +union clause ast = VGHSH_VV : (vregidx, vregidx, vregidx) + +mapping clause encdec = VGHSH_VV(vs2, vs1, vd) + <-> 0b1011001 @ encdec_vreg(vs2) @ encdec_vreg(vs1) @ 0b010 @ encdec_vreg(vd) @ 0b1110111 + when currentlyEnabled(Ext_Zvkg) & get_sew() == 32 & zvk_check_encdec(128, 4) + +function clause execute (VGHSH_VV(vs2, vs1, vd)) = { + let SEW = get_sew(); + let LMUL_pow = get_lmul_pow(); + let num_elem = get_num_elem(LMUL_pow, SEW); + + assert(SEW == 32); + + let vs2_val = read_vreg(num_elem, SEW, LMUL_pow, vs2); + let vs1_val = read_vreg(num_elem, SEW, LMUL_pow, vs1); + let vd_val = read_vreg(num_elem, SEW, LMUL_pow, vd); + + let eg_len = (unsigned(vl) / 4); + let eg_start = (unsigned(vstart) / 4); + + foreach (i from eg_start to (eg_len - 1)) { + assert(i * 4 + 3 < num_elem); + + let Y : bits(128) = get_velem_quad(vd_val, i); + let X : bits(128) = get_velem_quad(vs1_val, i); + var H : bits(128) = brev8(get_velem_quad(vs2_val, i)); + + var Z : bits(128) = zeros(); + let S : bits(128) = brev8(Y ^ X); + + foreach (b from 0 to 127) { + if S[b] == bitone then Z = Z ^ H; + + let reduce = H[127] == bitone; + H = H << 1; + if reduce then H = H[127..8] @ (H[7..0] ^ 0x87); + }; + + write_velem_quad(vd, SEW, brev8(Z), i); + }; + + set_vstart(zeros()); + RETIRE_SUCCESS +} + +mapping clause assembly = VGHSH_VV(vs2, vs1, vd) + <-> "vghsh.vv" ^ spc() ^ vreg_name(vd) ^ sep() ^ vreg_name(vs2) ^ sep() ^ vreg_name(vs1) + +union clause ast = VGMUL_VV : (vregidx, vregidx) + +mapping clause encdec = VGMUL_VV(vs2, vd) + <-> 0b1010001 @ encdec_vreg(vs2) @ 0b10001 @ 0b010 @ encdec_vreg(vd) @ 0b1110111 + when currentlyEnabled(Ext_Zvkg) & get_sew() == 32 & zvk_check_encdec(128, 4) + +function clause execute (VGMUL_VV(vs2, vd)) = { + let SEW = get_sew(); + let LMUL_pow = get_lmul_pow(); + let num_elem = get_num_elem(LMUL_pow, SEW); + + assert(SEW == 32); + + let vs2_val = read_vreg(num_elem, SEW, LMUL_pow, vs2); + let vd_val = read_vreg(num_elem, SEW, LMUL_pow, vd); + + let eg_len = (unsigned(vl) / 4); + let eg_start = (unsigned(vstart) / 4); + + foreach (i from eg_start to (eg_len - 1)) { + assert(i * 4 + 3 < num_elem); + + let Y : bits(128) = brev8(get_velem_quad(vd_val, i)); + var H : bits(128) = brev8(get_velem_quad(vs2_val, i)); + var Z : bits(128) = zeros(); + + foreach (b from 0 to 127) { + if Y[b] == bitone then Z = Z ^ H; + + let reduce = H[127] == bitone; + H = H << 1; + if reduce then H = H[127..8] @ (H[7..0] ^ 0x87); + }; + + write_velem_quad(vd, SEW, brev8(Z), i); + }; + + set_vstart(zeros()); + RETIRE_SUCCESS +} + +mapping clause assembly = VGMUL_VV(vs2, vd) + <-> "vgmul.vv" ^ spc() ^ vreg_name(vd) ^ sep() ^ vreg_name(vs2)