1*8882eb68SXin Tian/*************************************************************************************** 2*8882eb68SXin Tian* Copyright (c) 2024-2025 Institute of Information Engineering, Chinese Academy of Sciences 3*8882eb68SXin Tian* 4*8882eb68SXin Tian* XiangShan is licensed under Mulan PSL v2. 5*8882eb68SXin Tian* You can use this software according to the terms and conditions of the Mulan PSL v2. 6*8882eb68SXin Tian* You may obtain a copy of Mulan PSL v2 at: 7*8882eb68SXin Tian* http://license.coscl.org.cn/MulanPSL2 8*8882eb68SXin Tian* 9*8882eb68SXin Tian* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10*8882eb68SXin Tian* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11*8882eb68SXin Tian* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12*8882eb68SXin Tian* 13*8882eb68SXin Tian* See the Mulan PSL v2 for more details. 14*8882eb68SXin Tian***************************************************************************************/ 15*8882eb68SXin Tian 16*8882eb68SXin Tianpackage device 17*8882eb68SXin Tian 18*8882eb68SXin Tianimport chisel3._ 19*8882eb68SXin Tianimport chisel3.util._ 20*8882eb68SXin Tianimport chisel3.util.HasBlackBoxResource 21*8882eb68SXin Tianimport org.chipsalliance.cde.config.Parameters 22*8882eb68SXin Tianimport freechips.rocketchip.amba.axi4._ 23*8882eb68SXin Tianimport freechips.rocketchip.diplomacy._ 24*8882eb68SXin Tianimport freechips.rocketchip.util._ 25*8882eb68SXin Tianimport freechips.rocketchip.amba.apb._ 26*8882eb68SXin Tianimport freechips.rocketchip.tilelink.AXI4TLState 27*8882eb68SXin Tian 28*8882eb68SXin Tianclass IrrevocableQueue[T <: Data](gen: T, entries: Int, flow: Boolean = false) extends Module { 29*8882eb68SXin Tian val io = IO(new Bundle { 30*8882eb68SXin Tian val enq = Flipped(Irrevocable(gen)) 31*8882eb68SXin Tian val deq = Irrevocable(gen) 32*8882eb68SXin Tian }) 33*8882eb68SXin Tian val queue = Module(new Queue(gen, entries = entries, flow = flow)) 34*8882eb68SXin Tian 35*8882eb68SXin Tian queue.io.enq.valid := io.enq.valid 36*8882eb68SXin Tian queue.io.enq.bits := io.enq.bits 37*8882eb68SXin Tian io.enq.ready := queue.io.enq.ready 38*8882eb68SXin Tian 39*8882eb68SXin Tian io.deq.valid := queue.io.deq.valid 40*8882eb68SXin Tian io.deq.bits := queue.io.deq.bits 41*8882eb68SXin Tian queue.io.deq.ready := io.deq.ready 42*8882eb68SXin Tian} 43*8882eb68SXin Tian 44*8882eb68SXin Tianclass IrrevocableArbiter[T <: Data](gen: T, n: Int) extends Module { 45*8882eb68SXin Tian val io = IO(new Bundle { 46*8882eb68SXin Tian val in = Flipped(Vec(n, Irrevocable(gen))) 47*8882eb68SXin Tian val out = Irrevocable(gen) 48*8882eb68SXin Tian }) 49*8882eb68SXin Tian 50*8882eb68SXin Tian val decoupledIn = io.in.map { irrevocable => 51*8882eb68SXin Tian val decoupled = Wire(Decoupled(gen)) 52*8882eb68SXin Tian decoupled.valid := irrevocable.valid 53*8882eb68SXin Tian decoupled.bits := irrevocable.bits 54*8882eb68SXin Tian irrevocable.ready := decoupled.ready 55*8882eb68SXin Tian decoupled 56*8882eb68SXin Tian } 57*8882eb68SXin Tian 58*8882eb68SXin Tian val arbiter = Module(new Arbiter(gen, n)) 59*8882eb68SXin Tian arbiter.io.in <> decoupledIn 60*8882eb68SXin Tian 61*8882eb68SXin Tian io.out.valid := arbiter.io.out.valid 62*8882eb68SXin Tian io.out.bits := arbiter.io.out.bits 63*8882eb68SXin Tian arbiter.io.out.ready := io.out.ready 64*8882eb68SXin Tian} 65*8882eb68SXin Tian 66*8882eb68SXin Tian// CKI (Cipher Key Input) is a constant input used in the SM4 encryption algorithm. 67*8882eb68SXin Tian// It is part of the key expansion process and participates in generating subkeys. 68*8882eb68SXin Tian// During each round of the key expansion, the CKI value is mixed with other constants and 69*8882eb68SXin Tian// the initial key to enhance the security of the encryption algorithm. 70*8882eb68SXin Tianclass GetCKI extends Module { 71*8882eb68SXin Tian val io = IO(new Bundle { 72*8882eb68SXin Tian val countRoundIn = Input(UInt(5.W)) 73*8882eb68SXin Tian val ckiOut = Output(UInt(32.W)) 74*8882eb68SXin Tian }) 75*8882eb68SXin Tian val ckiOutReg= RegInit(0.U(32.W)) 76*8882eb68SXin Tian // 32 32-bit CKI constant values 77*8882eb68SXin Tian val ckiValuesVec = VecInit(Seq( 78*8882eb68SXin Tian "h00070e15".U, "h1c232a31".U, "h383f464d".U, "h545b6269".U, 79*8882eb68SXin Tian "h70777e85".U, "h8c939aa1".U, "ha8afb6bd".U, "hc4cbd2d9".U, 80*8882eb68SXin Tian "he0e7eef5".U, "hfc030a11".U, "h181f262d".U, "h343b4249".U, 81*8882eb68SXin Tian "h50575e65".U, "h6c737a81".U, "h888f969d".U, "ha4abb2b9".U, 82*8882eb68SXin Tian "hc0c7ced5".U, "hdce3eaf1".U, "hf8ff060d".U, "h141b2229".U, 83*8882eb68SXin Tian "h30373e45".U, "h4c535a61".U, "h686f767d".U, "h848b9299".U, 84*8882eb68SXin Tian "ha0a7aeb5".U, "hbcc3cad1".U, "hd8dfe6ed".U, "hf4fb0209".U, 85*8882eb68SXin Tian "h10171e25".U, "h2c333a41".U, "h484f565d".U, "h646b7279".U 86*8882eb68SXin Tian )) 87*8882eb68SXin Tian when(io.countRoundIn < 32.U) { 88*8882eb68SXin Tian ckiOutReg := ckiValuesVec(io.countRoundIn) 89*8882eb68SXin Tian }.otherwise { 90*8882eb68SXin Tian ckiOutReg := 0.U 91*8882eb68SXin Tian } 92*8882eb68SXin Tian io.ckiOut := ckiOutReg 93*8882eb68SXin Tian} 94*8882eb68SXin Tian 95*8882eb68SXin Tian 96*8882eb68SXin Tian// S-box is used in SM4 for nonlinear transformations during encryption processes. 97*8882eb68SXin Tian// SM4 uses a fixed 256 byte S-box for byte replacement. 98*8882eb68SXin Tian// This replacement process is achieved by replacing the input 8-bit data 99*8882eb68SXin Tian// with the corresponding values in the S-box lookup table. 100*8882eb68SXin Tianclass SboxReplace extends Module { 101*8882eb68SXin Tian val io = IO(new Bundle { 102*8882eb68SXin Tian val dataIn = Input(UInt(8.W)) 103*8882eb68SXin Tian val resultOut = Output(UInt(8.W)) 104*8882eb68SXin Tian }) 105*8882eb68SXin Tian // A 256 element S-box lookup table, where each element is an 8-bit hexadecimal constant 106*8882eb68SXin Tian val sbox = VecInit(Seq( 107*8882eb68SXin Tian 0xd6.U, 0x90.U, 0xe9.U, 0xfe.U, 0xcc.U, 0xe1.U, 0x3d.U, 0xb7.U, 0x16.U, 0xb6.U, 0x14.U, 0xc2.U, 0x28.U, 0xfb.U, 0x2c.U, 0x05.U, 108*8882eb68SXin Tian 0x2b.U, 0x67.U, 0x9a.U, 0x76.U, 0x2a.U, 0xbe.U, 0x04.U, 0xc3.U, 0xaa.U, 0x44.U, 0x13.U, 0x26.U, 0x49.U, 0x86.U, 0x06.U, 0x99.U, 109*8882eb68SXin Tian 0x9c.U, 0x42.U, 0x50.U, 0xf4.U, 0x91.U, 0xef.U, 0x98.U, 0x7a.U, 0x33.U, 0x54.U, 0x0b.U, 0x43.U, 0xed.U, 0xcf.U, 0xac.U, 0x62.U, 110*8882eb68SXin Tian 0xe4.U, 0xb3.U, 0x1c.U, 0xa9.U, 0xc9.U, 0x08.U, 0xe8.U, 0x95.U, 0x80.U, 0xdf.U, 0x94.U, 0xfa.U, 0x75.U, 0x8f.U, 0x3f.U, 0xa6.U, 111*8882eb68SXin Tian 0x47.U, 0x07.U, 0xa7.U, 0xfc.U, 0xf3.U, 0x73.U, 0x17.U, 0xba.U, 0x83.U, 0x59.U, 0x3c.U, 0x19.U, 0xe6.U, 0x85.U, 0x4f.U, 0xa8.U, 112*8882eb68SXin Tian 0x68.U, 0x6b.U, 0x81.U, 0xb2.U, 0x71.U, 0x64.U, 0xda.U, 0x8b.U, 0xf8.U, 0xeb.U, 0x0f.U, 0x4b.U, 0x70.U, 0x56.U, 0x9d.U, 0x35.U, 113*8882eb68SXin Tian 0x1e.U, 0x24.U, 0x0e.U, 0x5e.U, 0x63.U, 0x58.U, 0xd1.U, 0xa2.U, 0x25.U, 0x22.U, 0x7c.U, 0x3b.U, 0x01.U, 0x21.U, 0x78.U, 0x87.U, 114*8882eb68SXin Tian 0xd4.U, 0x00.U, 0x46.U, 0x57.U, 0x9f.U, 0xd3.U, 0x27.U, 0x52.U, 0x4c.U, 0x36.U, 0x02.U, 0xe7.U, 0xa0.U, 0xc4.U, 0xc8.U, 0x9e.U, 115*8882eb68SXin Tian 0xea.U, 0xbf.U, 0x8a.U, 0xd2.U, 0x40.U, 0xc7.U, 0x38.U, 0xb5.U, 0xa3.U, 0xf7.U, 0xf2.U, 0xce.U, 0xf9.U, 0x61.U, 0x15.U, 0xa1.U, 116*8882eb68SXin Tian 0xe0.U, 0xae.U, 0x5d.U, 0xa4.U, 0x9b.U, 0x34.U, 0x1a.U, 0x55.U, 0xad.U, 0x93.U, 0x32.U, 0x30.U, 0xf5.U, 0x8c.U, 0xb1.U, 0xe3.U, 117*8882eb68SXin Tian 0x1d.U, 0xf6.U, 0xe2.U, 0x2e.U, 0x82.U, 0x66.U, 0xca.U, 0x60.U, 0xc0.U, 0x29.U, 0x23.U, 0xab.U, 0x0d.U, 0x53.U, 0x4e.U, 0x6f.U, 118*8882eb68SXin Tian 0xd5.U, 0xdb.U, 0x37.U, 0x45.U, 0xde.U, 0xfd.U, 0x8e.U, 0x2f.U, 0x03.U, 0xff.U, 0x6a.U, 0x72.U, 0x6d.U, 0x6c.U, 0x5b.U, 0x51.U, 119*8882eb68SXin Tian 0x8d.U, 0x1b.U, 0xaf.U, 0x92.U, 0xbb.U, 0xdd.U, 0xbc.U, 0x7f.U, 0x11.U, 0xd9.U, 0x5c.U, 0x41.U, 0x1f.U, 0x10.U, 0x5a.U, 0xd8.U, 120*8882eb68SXin Tian 0x0a.U, 0xc1.U, 0x31.U, 0x88.U, 0xa5.U, 0xcd.U, 0x7b.U, 0xbd.U, 0x2d.U, 0x74.U, 0xd0.U, 0x12.U, 0xb8.U, 0xe5.U, 0xb4.U, 0xb0.U, 121*8882eb68SXin Tian 0x89.U, 0x69.U, 0x97.U, 0x4a.U, 0x0c.U, 0x96.U, 0x77.U, 0x7e.U, 0x65.U, 0xb9.U, 0xf1.U, 0x09.U, 0xc5.U, 0x6e.U, 0xc6.U, 0x84.U, 122*8882eb68SXin Tian 0x18.U, 0xf0.U, 0x7d.U, 0xec.U, 0x3a.U, 0xdc.U, 0x4d.U, 0x20.U, 0x79.U, 0xee.U, 0x5f.U, 0x3e.U, 0xd7.U, 0xcb.U, 0x39.U, 0x48.U 123*8882eb68SXin Tian )) 124*8882eb68SXin Tian 125*8882eb68SXin Tian io.resultOut := sbox(io.dataIn) 126*8882eb68SXin Tian} 127*8882eb68SXin Tian 128*8882eb68SXin Tian// Nonlinear Transformation in Data Encryption Process 129*8882eb68SXin Tianclass TransformForEncDec extends Module { 130*8882eb68SXin Tian val io = IO(new Bundle { 131*8882eb68SXin Tian val data_in = Input(UInt(32.W)) 132*8882eb68SXin Tian val result_out = Output(UInt(32.W)) 133*8882eb68SXin Tian }) 134*8882eb68SXin Tian 135*8882eb68SXin Tian val bytes_in = VecInit(Seq(io.data_in(7, 0), io.data_in(15, 8), io.data_in(23, 16), io.data_in(31, 24))) 136*8882eb68SXin Tian val bytes_replaced = Wire(Vec(4, UInt(8.W))) 137*8882eb68SXin Tian val word_replaced = Wire(UInt(32.W)) 138*8882eb68SXin Tian 139*8882eb68SXin Tian val sbox_replace_modules = VecInit(Seq.fill(4)(Module(new SboxReplace).io)) 140*8882eb68SXin Tian for (i <- 0 until 4) { 141*8882eb68SXin Tian sbox_replace_modules(i).dataIn := bytes_in(i) 142*8882eb68SXin Tian bytes_replaced(i) := sbox_replace_modules(i).resultOut 143*8882eb68SXin Tian } 144*8882eb68SXin Tian 145*8882eb68SXin Tian word_replaced := Cat(bytes_replaced.reverse) 146*8882eb68SXin Tian 147*8882eb68SXin Tian io.result_out := ((word_replaced ^ Cat(word_replaced(29, 0), word_replaced(31, 30))) ^ 148*8882eb68SXin Tian (Cat(word_replaced(21, 0), word_replaced(31, 22)) ^ Cat(word_replaced(13, 0), word_replaced(31, 14)))) ^ 149*8882eb68SXin Tian Cat(word_replaced(7, 0), word_replaced(31, 8)) 150*8882eb68SXin Tian} 151*8882eb68SXin Tian 152*8882eb68SXin Tian 153*8882eb68SXin Tian// Nonlinear Transformation in Key Expansion Process 154*8882eb68SXin Tianclass TransformForKeyExp extends Module { 155*8882eb68SXin Tian val io = IO(new Bundle { 156*8882eb68SXin Tian val data_in = Input(UInt(32.W)) 157*8882eb68SXin Tian val data_after_linear_key_out = Output(UInt(32.W)) 158*8882eb68SXin Tian }) 159*8882eb68SXin Tian val bytes_in = VecInit(Seq(io.data_in(7, 0), io.data_in(15, 8), io.data_in(23, 16), io.data_in(31, 24))) 160*8882eb68SXin Tian val bytes_replaced = Wire(Vec(4, UInt(8.W))) 161*8882eb68SXin Tian val word_replaced = Wire(UInt(32.W)) 162*8882eb68SXin Tian 163*8882eb68SXin Tian val sbox_replace_modules = VecInit(Seq.fill(4)(Module(new SboxReplace).io)) 164*8882eb68SXin Tian for (i <- 0 until 4) { 165*8882eb68SXin Tian sbox_replace_modules(i).dataIn := bytes_in(i) 166*8882eb68SXin Tian bytes_replaced(i) := sbox_replace_modules(i).resultOut 167*8882eb68SXin Tian } 168*8882eb68SXin Tian 169*8882eb68SXin Tian word_replaced := Cat(bytes_replaced.reverse) 170*8882eb68SXin Tian 171*8882eb68SXin Tian io.data_after_linear_key_out := (word_replaced ^ Cat(word_replaced(18, 0), word_replaced(31, 19))) ^ Cat(word_replaced(8, 0), word_replaced(31, 9)) 172*8882eb68SXin Tian} 173*8882eb68SXin Tian 174*8882eb68SXin Tian// The key expansion algorithm requires a total of 32 rounds of operations, including one round of operation 175*8882eb68SXin Tianclass OneRoundForKeyExp extends Module { 176*8882eb68SXin Tian val io = IO(new Bundle { 177*8882eb68SXin Tian val countRoundIn = Input(UInt(5.W)) 178*8882eb68SXin Tian val dataIn = Input(UInt(128.W)) 179*8882eb68SXin Tian val ckParameterIn = Input(UInt(32.W)) 180*8882eb68SXin Tian val resultOut = Output(UInt(128.W)) 181*8882eb68SXin Tian }) 182*8882eb68SXin Tian // In key expansion, the first step is to XOR each word of the original key with the system parameter to obtain four new words. 183*8882eb68SXin Tian // system parameter: FK0, FK1, FK2, FK3. 184*8882eb68SXin Tian val FK0 = "ha3b1bac6".U 185*8882eb68SXin Tian val FK1 = "h56aa3350".U 186*8882eb68SXin Tian val FK2 = "h677d9197".U 187*8882eb68SXin Tian val FK3 = "hb27022dc".U 188*8882eb68SXin Tian 189*8882eb68SXin Tian val word = VecInit(Seq(io.dataIn(127, 96), io.dataIn(95, 64), io.dataIn(63, 32), io.dataIn(31, 0))) 190*8882eb68SXin Tian 191*8882eb68SXin Tian val k0 = word(0) ^ FK0 192*8882eb68SXin Tian val k1 = word(1) ^ FK1 193*8882eb68SXin Tian val k2 = word(2) ^ FK2 194*8882eb68SXin Tian val k3 = word(3) ^ FK3 195*8882eb68SXin Tian 196*8882eb68SXin Tian 197*8882eb68SXin Tian val dataForXor = io.ckParameterIn 198*8882eb68SXin Tian val tmp0 = Mux(io.countRoundIn === 0.U, k1 ^ k2, word(1) ^ word(2)) 199*8882eb68SXin Tian val tmp1 = Mux(io.countRoundIn === 0.U, k3 ^ dataForXor, word(3) ^ dataForXor) 200*8882eb68SXin Tian val dataForTransform = tmp0 ^ tmp1 201*8882eb68SXin Tian 202*8882eb68SXin Tian val transformKey = Module(new TransformForKeyExp) 203*8882eb68SXin Tian transformKey.io.data_in := dataForTransform 204*8882eb68SXin Tian 205*8882eb68SXin Tian io.resultOut := Mux(io.countRoundIn === 0.U, 206*8882eb68SXin Tian Cat(k1, k2, k3, transformKey.io.data_after_linear_key_out ^ k0), 207*8882eb68SXin Tian Cat(word(1), word(2), word(3), transformKey.io.data_after_linear_key_out ^ word(0))) 208*8882eb68SXin Tian} 209*8882eb68SXin Tian 210*8882eb68SXin Tian// The SM4 encryption algorithm requires a total of 32 rounds of operations, including one round of operation 211*8882eb68SXin Tianclass OneRoundForEncDec extends Module { 212*8882eb68SXin Tian val io = IO(new Bundle { 213*8882eb68SXin Tian val data_in = Input(UInt(128.W)) 214*8882eb68SXin Tian val round_key_in = Input(UInt(32.W)) 215*8882eb68SXin Tian val result_out = Output(UInt(128.W)) 216*8882eb68SXin Tian }) 217*8882eb68SXin Tian 218*8882eb68SXin Tian val word = VecInit(Seq(io.data_in(127, 96), io.data_in(95, 64), io.data_in(63, 32), io.data_in(31, 0))) 219*8882eb68SXin Tian 220*8882eb68SXin Tian val tmp0 = word(1) ^ word(2) 221*8882eb68SXin Tian val tmp1 = word(3) ^ io.round_key_in 222*8882eb68SXin Tian val data_for_transform = tmp0 ^ tmp1 223*8882eb68SXin Tian 224*8882eb68SXin Tian val transform_encdec = Module(new TransformForEncDec) 225*8882eb68SXin Tian transform_encdec.io.data_in := data_for_transform 226*8882eb68SXin Tian 227*8882eb68SXin Tian io.result_out := Cat(word(1), word(2), word(3), transform_encdec.io.result_out ^ word(0)) 228*8882eb68SXin Tian} 229*8882eb68SXin Tian 230*8882eb68SXin Tian 231*8882eb68SXin Tian 232*8882eb68SXin Tianclass AXI4BundleWWithoutData(params: AXI4BundleParameters) extends Bundle { 233*8882eb68SXin Tian val strb = UInt((params.dataBits/8).W) 234*8882eb68SXin Tian val last = Bool() 235*8882eb68SXin Tian val user = BundleMap(params.requestFields.filter(_.key.isData)) 236*8882eb68SXin Tian} 237*8882eb68SXin Tian 238*8882eb68SXin Tianclass AXI4BundleRWithoutData(params: AXI4BundleParameters) extends Bundle { 239*8882eb68SXin Tian val id = UInt(params.idBits.W) 240*8882eb68SXin Tian val resp = UInt(params.respBits.W) 241*8882eb68SXin Tian val user = BundleMap(params.responseFields) 242*8882eb68SXin Tian val echo = BundleMap(params.echoFields) 243*8882eb68SXin Tian val last = Bool() 244*8882eb68SXin Tian} 245*8882eb68SXin Tian 246*8882eb68SXin Tian// OnePipeEncBase is an abstract class that defines the structure of a single-pipe encryption module. 247*8882eb68SXin Tian// The main purpose of this class is to standardize the input and output interfaces for encryption modules. 248*8882eb68SXin Tianabstract class OnePipeEncBase(implicit p: Parameters) extends MemEncryptModule { 249*8882eb68SXin Tian val io = IO(new Bundle { 250*8882eb68SXin Tian val onepipe_in = new Bundle { 251*8882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) 252*8882eb68SXin Tian val data_in = Input(UInt(128.W)) 253*8882eb68SXin Tian val tweak_in = Input(UInt(128.W)) 254*8882eb68SXin Tian val axi4_other = Input(new AXI4BundleWWithoutData(MemcedgeIn.bundle)) 255*8882eb68SXin Tian val round_key_in = Input(Vec(32/MemencPipes, UInt(32.W))) 256*8882eb68SXin Tian } 257*8882eb68SXin Tian val onepipe_out = new Bundle { 258*8882eb68SXin Tian val result_out = Output(UInt(128.W)) 259*8882eb68SXin Tian val axi4_other_out = Output(new AXI4BundleWWithoutData(MemcedgeIn.bundle)) 260*8882eb68SXin Tian val tweak_out = Output(UInt(128.W)) 261*8882eb68SXin Tian val keyid_out = Output(UInt(5.W)) 262*8882eb68SXin Tian } 263*8882eb68SXin Tian }) 264*8882eb68SXin Tian} 265*8882eb68SXin Tian 266*8882eb68SXin Tian// The OnePipeForEnc module needs to actually perform the encryption process for each 267*8882eb68SXin Tian// level of the pipeline in the encryption pipeline. 268*8882eb68SXin Tian// The flow level can be customized and configured. 269*8882eb68SXin Tianclass OnePipeForEnc(implicit p: Parameters) extends OnePipeEncBase { 270*8882eb68SXin Tian 271*8882eb68SXin Tian val OneRoundForEncDecs = Seq.fill(32/MemencPipes)(Module(new OneRoundForEncDec)) 272*8882eb68SXin Tian 273*8882eb68SXin Tian for (i <- 0 until 32/MemencPipes) { 274*8882eb68SXin Tian val mod = OneRoundForEncDecs(i) 275*8882eb68SXin Tian mod.io.round_key_in := io.onepipe_in.round_key_in(i) 276*8882eb68SXin Tian if (i == 0) mod.io.data_in := io.onepipe_in.data_in else mod.io.data_in := OneRoundForEncDecs(i - 1).io.result_out 277*8882eb68SXin Tian } 278*8882eb68SXin Tian 279*8882eb68SXin Tian io.onepipe_out.result_out := OneRoundForEncDecs.last.io.result_out 280*8882eb68SXin Tian io.onepipe_out.keyid_out := io.onepipe_in.keyid 281*8882eb68SXin Tian io.onepipe_out.axi4_other_out := io.onepipe_in.axi4_other 282*8882eb68SXin Tian io.onepipe_out.tweak_out := io.onepipe_in.tweak_in 283*8882eb68SXin Tian 284*8882eb68SXin Tian} 285*8882eb68SXin Tian// The encryption process of each stage in the encryption pipeline does not require 286*8882eb68SXin Tian// the OnePipeForEnc module to actually execute the encryption process. 287*8882eb68SXin Tian// Test usage 288*8882eb68SXin Tianclass OnePipeForEncNoEnc(implicit p: Parameters) extends OnePipeEncBase { 289*8882eb68SXin Tian io.onepipe_out.result_out := io.onepipe_in.data_in 290*8882eb68SXin Tian io.onepipe_out.keyid_out := io.onepipe_in.keyid 291*8882eb68SXin Tian io.onepipe_out.tweak_out := io.onepipe_in.tweak_in 292*8882eb68SXin Tian io.onepipe_out.axi4_other_out := io.onepipe_in.axi4_other 293*8882eb68SXin Tian} 294*8882eb68SXin Tian 295*8882eb68SXin Tianabstract class OnePipeDecBase(implicit p: Parameters) extends MemEncryptModule { 296*8882eb68SXin Tian val io = IO(new Bundle { 297*8882eb68SXin Tian val onepipe_in = new Bundle { 298*8882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) 299*8882eb68SXin Tian val data_in = Input(UInt(128.W)) 300*8882eb68SXin Tian val tweak_in = Input(UInt(128.W)) 301*8882eb68SXin Tian val axi4_other = Input(new AXI4BundleRWithoutData(MemcedgeOut.bundle)) 302*8882eb68SXin Tian val round_key_in = Input(Vec(32/MemencPipes, UInt(32.W))) 303*8882eb68SXin Tian } 304*8882eb68SXin Tian val onepipe_out = new Bundle { 305*8882eb68SXin Tian val result_out = Output(UInt(128.W)) 306*8882eb68SXin Tian val axi4_other_out = Output(new AXI4BundleRWithoutData(MemcedgeOut.bundle)) 307*8882eb68SXin Tian val tweak_out = Output(UInt(128.W)) 308*8882eb68SXin Tian val keyid_out = Output(UInt(5.W)) 309*8882eb68SXin Tian } 310*8882eb68SXin Tian }) 311*8882eb68SXin Tian} 312*8882eb68SXin Tianclass OnePipeForDec(implicit p: Parameters) extends OnePipeDecBase { 313*8882eb68SXin Tian 314*8882eb68SXin Tian val OneRoundForEncDecs = Seq.fill(32/MemencPipes)(Module(new OneRoundForEncDec)) 315*8882eb68SXin Tian 316*8882eb68SXin Tian for (i <- 0 until 32/MemencPipes) { 317*8882eb68SXin Tian val mod = OneRoundForEncDecs(i) 318*8882eb68SXin Tian mod.io.round_key_in := io.onepipe_in.round_key_in(i) 319*8882eb68SXin Tian if (i == 0) mod.io.data_in := io.onepipe_in.data_in else mod.io.data_in := OneRoundForEncDecs(i - 1).io.result_out 320*8882eb68SXin Tian } 321*8882eb68SXin Tian 322*8882eb68SXin Tian io.onepipe_out.result_out := OneRoundForEncDecs.last.io.result_out 323*8882eb68SXin Tian io.onepipe_out.keyid_out := io.onepipe_in.keyid 324*8882eb68SXin Tian io.onepipe_out.axi4_other_out := io.onepipe_in.axi4_other 325*8882eb68SXin Tian io.onepipe_out.tweak_out := io.onepipe_in.tweak_in 326*8882eb68SXin Tian 327*8882eb68SXin Tian} 328*8882eb68SXin Tianclass OnePipeForDecNoDec(implicit p: Parameters) extends OnePipeDecBase { 329*8882eb68SXin Tian io.onepipe_out.result_out := io.onepipe_in.data_in 330*8882eb68SXin Tian io.onepipe_out.keyid_out := io.onepipe_in.keyid 331*8882eb68SXin Tian io.onepipe_out.axi4_other_out := io.onepipe_in.axi4_other 332*8882eb68SXin Tian io.onepipe_out.tweak_out := io.onepipe_in.tweak_in 333*8882eb68SXin Tian} 334*8882eb68SXin Tian 335*8882eb68SXin Tian// Finite field operations after encrypting tweak (encryption adjustment value) in XTS confidential mode 336*8882eb68SXin Tian// Encryption adjustment value (tweak), This encryption adjustment utilizes finite fields and XOR operations to 337*8882eb68SXin Tian// ensure security by preventing the same ciphertext from being obtained even if the packet is identical each time. 338*8882eb68SXin Tian 339*8882eb68SXin Tian// Calculation process: 340*8882eb68SXin Tian// Move the logic one bit to the left. If the highest bit that is moved out is 1, XOR the lower 8 bits 0x87 three times, 341*8882eb68SXin Tian// generating four different sets of data for XOR before and after data encryption; 342*8882eb68SXin Tianclass GF128 extends Module{ 343*8882eb68SXin Tian val io = IO(new Bundle { 344*8882eb68SXin Tian val tweak_in = Input(UInt(128.W)) 345*8882eb68SXin Tian val tweak_out = Output(UInt(512.W)) 346*8882eb68SXin Tian }) 347*8882eb68SXin Tian 348*8882eb68SXin Tian val gf_128_fdbk = "h87".U(8.W) 349*8882eb68SXin Tian val tweak_1_isgf = io.tweak_in(127) 350*8882eb68SXin Tian val tweak_2_isgf = io.tweak_in(126) 351*8882eb68SXin Tian val tweak_3_isgf = io.tweak_in(125) 352*8882eb68SXin Tian val tweak_1_shifted = Wire(UInt(128.W)) 353*8882eb68SXin Tian val tweak_2_shifted = Wire(UInt(128.W)) 354*8882eb68SXin Tian val tweak_3_shifted = Wire(UInt(128.W)) 355*8882eb68SXin Tian val tweak_1_out = Wire(UInt(128.W)) 356*8882eb68SXin Tian val tweak_2_out = Wire(UInt(128.W)) 357*8882eb68SXin Tian val tweak_3_out = Wire(UInt(128.W)) 358*8882eb68SXin Tian 359*8882eb68SXin Tian tweak_1_shifted := io.tweak_in << 1 360*8882eb68SXin Tian tweak_2_shifted := tweak_1_out << 1 361*8882eb68SXin Tian tweak_3_shifted := tweak_2_out << 1 362*8882eb68SXin Tian 363*8882eb68SXin Tian tweak_1_out := Mux(tweak_1_isgf, tweak_1_shifted ^ gf_128_fdbk, tweak_1_shifted) 364*8882eb68SXin Tian tweak_2_out := Mux(tweak_2_isgf, tweak_2_shifted ^ gf_128_fdbk, tweak_2_shifted) 365*8882eb68SXin Tian tweak_3_out := Mux(tweak_3_isgf, tweak_3_shifted ^ gf_128_fdbk, tweak_3_shifted) 366*8882eb68SXin Tian 367*8882eb68SXin Tian io.tweak_out := Cat(tweak_3_out, tweak_2_out, tweak_1_out, io.tweak_in) 368*8882eb68SXin Tian} 369*8882eb68SXin Tian 370*8882eb68SXin Tian// Perform finite field operations on the initial tweak during the request sending process, 371*8882eb68SXin Tian// and output according to the requirements (aw. len) 372*8882eb68SXin Tianclass TweakGF128(implicit p: Parameters) extends MemEncryptModule{ 373*8882eb68SXin Tian val io = IO(new Bundle { 374*8882eb68SXin Tian val req = Flipped(DecoupledIO(new Bundle { 375*8882eb68SXin Tian val len = UInt(MemcedgeIn.bundle.lenBits.W) 376*8882eb68SXin Tian val addr = UInt(PAddrBits.W) 377*8882eb68SXin Tian val tweak_in = UInt(128.W) 378*8882eb68SXin Tian })) 379*8882eb68SXin Tian val resp = DecoupledIO(new Bundle { 380*8882eb68SXin Tian val tweak_out = UInt(256.W) 381*8882eb68SXin Tian val keyid_out = UInt(KeyIDBits.W) 382*8882eb68SXin Tian val addr_out = UInt(PAddrBits.W) 383*8882eb68SXin Tian }) 384*8882eb68SXin Tian }) 385*8882eb68SXin Tian val tweak_gf128 = Module(new GF128()) 386*8882eb68SXin Tian tweak_gf128.io.tweak_in := io.req.bits.tweak_in 387*8882eb68SXin Tian 388*8882eb68SXin Tian val reg_valid = RegInit(false.B) 389*8882eb68SXin Tian val reg_counter = RegInit(0.U(2.W)) 390*8882eb68SXin Tian val reg_len = RegInit(0.U(MemcedgeIn.bundle.lenBits.W)) 391*8882eb68SXin Tian val reg_addr = RegInit(0.U(PAddrBits.W)) 392*8882eb68SXin Tian val reg_tweak_result = RegInit(0.U(512.W)) 393*8882eb68SXin Tian 394*8882eb68SXin Tian io.req.ready := !reg_valid || (reg_valid && io.resp.ready && (reg_len === 0.U || reg_counter =/= 0.U)) 395*8882eb68SXin Tian 396*8882eb68SXin Tian when(io.req.fire) { 397*8882eb68SXin Tian reg_tweak_result := tweak_gf128.io.tweak_out 398*8882eb68SXin Tian reg_len := io.req.bits.len 399*8882eb68SXin Tian reg_addr := io.req.bits.addr 400*8882eb68SXin Tian reg_valid := true.B 401*8882eb68SXin Tian reg_counter := 0.U 402*8882eb68SXin Tian }.elsewhen(reg_valid && io.resp.ready) { 403*8882eb68SXin Tian when(reg_len === 0.U) { 404*8882eb68SXin Tian reg_valid := false.B 405*8882eb68SXin Tian reg_counter := 0.U 406*8882eb68SXin Tian }.otherwise { 407*8882eb68SXin Tian when(reg_counter === 0.U) { 408*8882eb68SXin Tian reg_counter := reg_counter + 1.U 409*8882eb68SXin Tian }.otherwise { 410*8882eb68SXin Tian reg_valid := false.B 411*8882eb68SXin Tian reg_counter := 0.U 412*8882eb68SXin Tian } 413*8882eb68SXin Tian } 414*8882eb68SXin Tian }.otherwise { 415*8882eb68SXin Tian reg_valid := reg_valid 416*8882eb68SXin Tian reg_counter := reg_counter 417*8882eb68SXin Tian } 418*8882eb68SXin Tian 419*8882eb68SXin Tian 420*8882eb68SXin Tian io.resp.bits.addr_out := reg_addr 421*8882eb68SXin Tian io.resp.bits.keyid_out := reg_addr(PAddrBits - 1, PAddrBits - KeyIDBits) 422*8882eb68SXin Tian io.resp.bits.tweak_out := Mux(reg_len === 0.U, Mux(reg_addr(5) === 0.U, reg_tweak_result(255, 0), reg_tweak_result(511, 256)), 423*8882eb68SXin Tian Mux(reg_counter === 0.U, reg_tweak_result(255, 0), reg_tweak_result(511, 256))) 424*8882eb68SXin Tian io.resp.valid := reg_valid 425*8882eb68SXin Tian} 426*8882eb68SXin Tian 427*8882eb68SXin Tian// The encryption process in each stage of the pipeline during the initial tweak encryption process 428*8882eb68SXin Tianclass OnePipeForTweakEnc(implicit p: Parameters) extends MemEncryptModule { 429*8882eb68SXin Tian val io = IO(new Bundle { 430*8882eb68SXin Tian val in = new Bundle { 431*8882eb68SXin Tian val data_in = Input(UInt(128.W)) 432*8882eb68SXin Tian val addr_in = Input(UInt(PAddrBits.W)) 433*8882eb68SXin Tian val len_in = Input(UInt(MemcedgeOut.bundle.lenBits.W)) 434*8882eb68SXin Tian val id_in = Input(UInt(MemcedgeOut.bundle.idBits.W)) 435*8882eb68SXin Tian val round_key_in = Input(Vec(32/MemencPipes, UInt(32.W))) 436*8882eb68SXin Tian } 437*8882eb68SXin Tian val out = new Bundle { 438*8882eb68SXin Tian val result_out = Output(UInt(128.W)) 439*8882eb68SXin Tian val addr_out = Output(UInt(PAddrBits.W)) 440*8882eb68SXin Tian val len_out = Output(UInt(MemcedgeOut.bundle.lenBits.W)) 441*8882eb68SXin Tian val id_out = Output(UInt(MemcedgeOut.bundle.idBits.W)) 442*8882eb68SXin Tian } 443*8882eb68SXin Tian }) 444*8882eb68SXin Tian 445*8882eb68SXin Tian val OneRoundForEncDecs = Seq.fill(32/MemencPipes)(Module(new OneRoundForEncDec)) 446*8882eb68SXin Tian for (i <- 0 until 32/MemencPipes) { 447*8882eb68SXin Tian val mod = OneRoundForEncDecs(i) 448*8882eb68SXin Tian mod.io.round_key_in := io.in.round_key_in(i) 449*8882eb68SXin Tian if (i == 0) mod.io.data_in := io.in.data_in else mod.io.data_in := OneRoundForEncDecs(i - 1).io.result_out 450*8882eb68SXin Tian } 451*8882eb68SXin Tian 452*8882eb68SXin Tian io.out.result_out := OneRoundForEncDecs.last.io.result_out 453*8882eb68SXin Tian io.out.addr_out := io.in.addr_in 454*8882eb68SXin Tian io.out.len_out := io.in.len_in 455*8882eb68SXin Tian io.out.id_out := io.in.id_in 456*8882eb68SXin Tian} 457*8882eb68SXin Tian 458*8882eb68SXin Tian// Initial TWEAK encryption module. 459*8882eb68SXin Tian// The pipeline configuration is determined by the MemencPipes parameter 460*8882eb68SXin Tianclass TweakEncrypt(opt: Boolean)(implicit p: Parameters) extends MemEncryptModule{ 461*8882eb68SXin Tian val edgeUse = if (opt) MemcedgeIn else MemcedgeOut 462*8882eb68SXin Tian val io = IO(new Bundle { 463*8882eb68SXin Tian val tweak_enc_req = Flipped(DecoupledIO(new Bundle { 464*8882eb68SXin Tian val tweak = UInt(128.W) 465*8882eb68SXin Tian val addr_in = UInt(PAddrBits.W) 466*8882eb68SXin Tian val len_in = UInt(edgeUse.bundle.lenBits.W) // 6 bit 467*8882eb68SXin Tian val id_in = UInt(edgeUse.bundle.idBits.W) 468*8882eb68SXin Tian val tweak_round_keys = Vec(32, UInt(32.W)) 469*8882eb68SXin Tian })) 470*8882eb68SXin Tian val tweak_enc_resp = DecoupledIO(new Bundle { 471*8882eb68SXin Tian val tweak_encrpty = UInt(128.W) 472*8882eb68SXin Tian val addr_out = UInt(PAddrBits.W) 473*8882eb68SXin Tian val len_out = UInt(edgeUse.bundle.lenBits.W) 474*8882eb68SXin Tian val id_out = UInt(edgeUse.bundle.idBits.W) 475*8882eb68SXin Tian }) 476*8882eb68SXin Tian }) 477*8882eb68SXin Tian 478*8882eb68SXin Tian val reg_tweak = Reg(Vec(MemencPipes, UInt(128.W))) 479*8882eb68SXin Tian val reg_addr = Reg(Vec(MemencPipes, UInt(PAddrBits.W))) 480*8882eb68SXin Tian val reg_len = Reg(Vec(MemencPipes, UInt(edgeUse.bundle.lenBits.W))) 481*8882eb68SXin Tian val reg_id = Reg(Vec(MemencPipes, UInt(edgeUse.bundle.idBits.W))) 482*8882eb68SXin Tian val reg_tweak_valid = RegInit(VecInit(Seq.fill(MemencPipes)(false.B))) 483*8882eb68SXin Tian // TWEAK encryption requires 32 rounds of encryption keys, grouped by pipeline level 484*8882eb68SXin Tian val wire_round_key = Wire(Vec(MemencPipes, UInt((32 * 32 / MemencPipes).W))) 485*8882eb68SXin Tian 486*8882eb68SXin Tian val keysPerPipe = 32 / MemencPipes 487*8882eb68SXin Tian for (i <- 0 until MemencPipes) { 488*8882eb68SXin Tian val keySegment = VecInit((0 until keysPerPipe).map(j => io.tweak_enc_req.bits.tweak_round_keys(i * keysPerPipe + j))) 489*8882eb68SXin Tian wire_round_key(i) := Cat(keySegment.asUInt) 490*8882eb68SXin Tian } 491*8882eb68SXin Tian 492*8882eb68SXin Tian val wire_ready_result = WireInit(VecInit(Seq.fill(MemencPipes)(false.B))) 493*8882eb68SXin Tian // The configuration method for each level of encryption module in tweak 494*8882eb68SXin Tian def configureModule(i: Int, dataIn: UInt, addrIn: UInt, lenIn: UInt, idIn: UInt, roundKeys: UInt): OnePipeForTweakEnc = { 495*8882eb68SXin Tian 496*8882eb68SXin Tian when(wire_ready_result(i) && (if (i == 0) io.tweak_enc_req.valid else reg_tweak_valid(i-1))) { 497*8882eb68SXin Tian reg_tweak_valid(i) := true.B 498*8882eb68SXin Tian }.elsewhen(reg_tweak_valid(i) && (if (i == MemencPipes - 1) io.tweak_enc_resp.ready else wire_ready_result(i+1))) { 499*8882eb68SXin Tian reg_tweak_valid(i) := false.B 500*8882eb68SXin Tian }.otherwise { 501*8882eb68SXin Tian reg_tweak_valid(i) := reg_tweak_valid(i) 502*8882eb68SXin Tian } 503*8882eb68SXin Tian wire_ready_result(i) := !reg_tweak_valid(i) || (reg_tweak_valid(i) && (if (i == MemencPipes - 1) io.tweak_enc_resp.ready else wire_ready_result(i+1))) 504*8882eb68SXin Tian 505*8882eb68SXin Tian val module = Module(new OnePipeForTweakEnc()) 506*8882eb68SXin Tian module.io.in.data_in := dataIn 507*8882eb68SXin Tian module.io.in.addr_in := addrIn 508*8882eb68SXin Tian module.io.in.len_in := lenIn 509*8882eb68SXin Tian module.io.in.id_in := idIn 510*8882eb68SXin Tian for (j <- 0 until 32/MemencPipes) { 511*8882eb68SXin Tian module.io.in.round_key_in(j) := roundKeys(j * 32 + 31, j * 32) 512*8882eb68SXin Tian } 513*8882eb68SXin Tian when(wire_ready_result(i) && (if (i == 0) io.tweak_enc_req.valid else reg_tweak_valid(i-1))) { 514*8882eb68SXin Tian reg_tweak(i) := module.io.out.result_out 515*8882eb68SXin Tian reg_addr(i) := module.io.out.addr_out 516*8882eb68SXin Tian reg_len(i) := module.io.out.len_out 517*8882eb68SXin Tian reg_id(i) := module.io.out.id_out 518*8882eb68SXin Tian } 519*8882eb68SXin Tian module 520*8882eb68SXin Tian } 521*8882eb68SXin Tian // Instantiate the tweak encryption module for each pipeline level 522*8882eb68SXin Tian val tweak_enc_modules = (0 until MemencPipes).map { i => 523*8882eb68SXin Tian if (i == 0) { 524*8882eb68SXin Tian configureModule(i, io.tweak_enc_req.bits.tweak, io.tweak_enc_req.bits.addr_in, io.tweak_enc_req.bits.len_in, io.tweak_enc_req.bits.id_in, wire_round_key(i)) 525*8882eb68SXin Tian } else { 526*8882eb68SXin Tian configureModule(i, reg_tweak(i-1), reg_addr(i-1), reg_len(i-1), reg_id(i-1), wire_round_key(i)) 527*8882eb68SXin Tian } 528*8882eb68SXin Tian } 529*8882eb68SXin Tian val result_out = Cat( 530*8882eb68SXin Tian reg_tweak.last(31, 0), 531*8882eb68SXin Tian reg_tweak.last(63, 32), 532*8882eb68SXin Tian reg_tweak.last(95, 64), 533*8882eb68SXin Tian reg_tweak.last(127, 96) 534*8882eb68SXin Tian ) 535*8882eb68SXin Tian io.tweak_enc_resp.bits.tweak_encrpty := result_out 536*8882eb68SXin Tian io.tweak_enc_resp.bits.addr_out := reg_addr.last 537*8882eb68SXin Tian io.tweak_enc_resp.bits.len_out := reg_len.last 538*8882eb68SXin Tian io.tweak_enc_resp.bits.id_out := reg_id.last 539*8882eb68SXin Tian io.tweak_enc_resp.valid := reg_tweak_valid.last 540*8882eb68SXin Tian io.tweak_enc_req.ready := wire_ready_result(0) 541*8882eb68SXin Tian 542*8882eb68SXin Tian} 543*8882eb68SXin Tian 544*8882eb68SXin Tian 545*8882eb68SXin Tian// tweak table entry in AR Channel 546*8882eb68SXin Tianclass TweakTableEntry(implicit val p: Parameters) extends Bundle with Memconsts { 547*8882eb68SXin Tian val v_flag = Bool() 548*8882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 549*8882eb68SXin Tian val len = UInt(MemcedgeOut.bundle.lenBits.W) 550*8882eb68SXin Tian val tweak_encrpty = UInt(128.W) 551*8882eb68SXin Tian val sel_counter = Bool() 552*8882eb68SXin Tian} 553*8882eb68SXin Tianclass TweakTableModeEntry extends Bundle { 554*8882eb68SXin Tian val dec_mode = Bool() 555*8882eb68SXin Tian} 556*8882eb68SXin Tian// tweak table in AR Channel 557*8882eb68SXin Tianclass TweakTable(implicit p: Parameters) extends MemEncryptModule { 558*8882eb68SXin Tian val io = IO(new Bundle { 559*8882eb68SXin Tian // Write to tweak table 560*8882eb68SXin Tian val write = Flipped(DecoupledIO(new Bundle { 561*8882eb68SXin Tian val id = UInt(MemcedgeOut.bundle.idBits.W) 562*8882eb68SXin Tian val len = UInt(MemcedgeOut.bundle.lenBits.W) 563*8882eb68SXin Tian val addr = UInt(PAddrBits.W) 564*8882eb68SXin Tian val tweak_encrpty = UInt(128.W) 565*8882eb68SXin Tian })) 566*8882eb68SXin Tian // Read from the tweak table with the ID of channel R in AXI4 as the index 567*8882eb68SXin Tian val req = Flipped(DecoupledIO(new Bundle { 568*8882eb68SXin Tian val read_id = UInt(MemcedgeOut.bundle.idBits.W) 569*8882eb68SXin Tian })) 570*8882eb68SXin Tian // Tweak table read response 571*8882eb68SXin Tian val resp = DecoupledIO(new Bundle { 572*8882eb68SXin Tian val read_tweak = UInt(128.W) 573*8882eb68SXin Tian val read_keyid = UInt(KeyIDBits.W) 574*8882eb68SXin Tian val read_sel_counter = Bool() 575*8882eb68SXin Tian }) 576*8882eb68SXin Tian val w_mode = Flipped(DecoupledIO(new Bundle { 577*8882eb68SXin Tian val id = UInt(MemcedgeOut.bundle.idBits.W) 578*8882eb68SXin Tian val dec_mode = Input(Bool()) 579*8882eb68SXin Tian })) 580*8882eb68SXin Tian val r_mode = new Bundle { 581*8882eb68SXin Tian val id = Input(UInt(MemcedgeOut.bundle.idBits.W)) 582*8882eb68SXin Tian val dec_mode = Output(Bool()) 583*8882eb68SXin Tian } 584*8882eb68SXin Tian }) 585*8882eb68SXin Tian 586*8882eb68SXin Tian val init_tweak_entry = Wire(new TweakTableEntry()) 587*8882eb68SXin Tian init_tweak_entry.v_flag := false.B 588*8882eb68SXin Tian init_tweak_entry.keyid := DontCare 589*8882eb68SXin Tian init_tweak_entry.len := DontCare 590*8882eb68SXin Tian init_tweak_entry.tweak_encrpty := DontCare 591*8882eb68SXin Tian init_tweak_entry.sel_counter := DontCare 592*8882eb68SXin Tian val init_mode_entry = Wire(new TweakTableModeEntry) 593*8882eb68SXin Tian init_mode_entry.dec_mode := false.B 594*8882eb68SXin Tian val tweak_table = RegInit(VecInit(Seq.fill((1 << (MemcedgeOut.bundle.idBits - 1)) + 1)(init_tweak_entry))) 595*8882eb68SXin Tian val tweak_mode_table = RegInit(VecInit(Seq.fill((1 << (MemcedgeOut.bundle.idBits - 1)) + 1)(init_mode_entry))) 596*8882eb68SXin Tian 597*8882eb68SXin Tian // write tweak table entry logic 598*8882eb68SXin Tian when(io.write.valid) { 599*8882eb68SXin Tian val write_entry = tweak_table(io.write.bits.id) 600*8882eb68SXin Tian write_entry.tweak_encrpty := io.write.bits.tweak_encrpty 601*8882eb68SXin Tian write_entry.keyid := io.write.bits.addr(PAddrBits-1, PAddrBits-KeyIDBits) 602*8882eb68SXin Tian write_entry.len := io.write.bits.len 603*8882eb68SXin Tian write_entry.v_flag := true.B 604*8882eb68SXin Tian 605*8882eb68SXin Tian when(io.write.bits.len === 1.U) { 606*8882eb68SXin Tian write_entry.sel_counter := false.B 607*8882eb68SXin Tian }.otherwise { 608*8882eb68SXin Tian write_entry.sel_counter := Mux(io.write.bits.addr(5) === 0.U, false.B, true.B) 609*8882eb68SXin Tian } 610*8882eb68SXin Tian } 611*8882eb68SXin Tian io.write.ready := true.B 612*8882eb68SXin Tian 613*8882eb68SXin Tian // write mode table entry logic 614*8882eb68SXin Tian when(io.w_mode.valid) { 615*8882eb68SXin Tian val write_mode_entry = tweak_mode_table(io.w_mode.bits.id) 616*8882eb68SXin Tian write_mode_entry.dec_mode := io.w_mode.bits.dec_mode 617*8882eb68SXin Tian } 618*8882eb68SXin Tian io.w_mode.ready := true.B 619*8882eb68SXin Tian 620*8882eb68SXin Tian // Tweak table read response logic 621*8882eb68SXin Tian val reg_read_valid = RegInit(false.B) 622*8882eb68SXin Tian val reg_tweak_encrpty = RegInit(0.U(128.W)) 623*8882eb68SXin Tian val reg_keyid = RegInit(0.U(KeyIDBits.W)) 624*8882eb68SXin Tian val reg_sel_counter = RegInit(false.B) 625*8882eb68SXin Tian 626*8882eb68SXin Tian val read_entry = tweak_table(io.req.bits.read_id) 627*8882eb68SXin Tian val read_mode_entry = tweak_mode_table(io.r_mode.id) 628*8882eb68SXin Tian io.r_mode.dec_mode := read_mode_entry.dec_mode 629*8882eb68SXin Tian 630*8882eb68SXin Tian io.req.ready := (!reg_read_valid || (reg_read_valid && io.resp.ready)) && read_entry.v_flag 631*8882eb68SXin Tian when(io.req.fire) { 632*8882eb68SXin Tian reg_read_valid := true.B 633*8882eb68SXin Tian reg_tweak_encrpty := read_entry.tweak_encrpty 634*8882eb68SXin Tian reg_keyid := read_entry.keyid 635*8882eb68SXin Tian reg_sel_counter := read_entry.sel_counter 636*8882eb68SXin Tian when(read_entry.len === 0.U) { 637*8882eb68SXin Tian read_entry.v_flag := false.B 638*8882eb68SXin Tian }.otherwise { 639*8882eb68SXin Tian when(!read_entry.sel_counter) { 640*8882eb68SXin Tian read_entry.sel_counter := true.B 641*8882eb68SXin Tian }.otherwise { 642*8882eb68SXin Tian read_entry.v_flag := false.B 643*8882eb68SXin Tian } 644*8882eb68SXin Tian } 645*8882eb68SXin Tian }.elsewhen(reg_read_valid && io.resp.ready) { 646*8882eb68SXin Tian reg_read_valid := false.B 647*8882eb68SXin Tian }.otherwise { 648*8882eb68SXin Tian reg_read_valid := reg_read_valid 649*8882eb68SXin Tian } 650*8882eb68SXin Tian 651*8882eb68SXin Tian io.resp.bits.read_tweak := reg_tweak_encrpty 652*8882eb68SXin Tian io.resp.bits.read_keyid := reg_keyid 653*8882eb68SXin Tian io.resp.bits.read_sel_counter := reg_sel_counter 654*8882eb68SXin Tian io.resp.valid := reg_read_valid 655*8882eb68SXin Tian 656*8882eb68SXin Tian} 657*8882eb68SXin Tian 658*8882eb68SXin Tian 659*8882eb68SXin Tian 660*8882eb68SXin Tian// AXI4Util 661*8882eb68SXin Tian// Bypass routing, Determine the encryption mode in the key expansion module. 662*8882eb68SXin Tian// write requests need to be encrypted ->io.out1; 663*8882eb68SXin Tian// Writing requests does not require encryption --->io.out0. 664*8882eb68SXin Tianclass WriteChanelRoute(implicit p: Parameters) extends MemEncryptModule 665*8882eb68SXin Tian{ 666*8882eb68SXin Tian val io = IO(new Bundle { 667*8882eb68SXin Tian val in = new Bundle { 668*8882eb68SXin Tian val aw = Flipped(Irrevocable(new AXI4BundleAW(MemcedgeIn.bundle))) 669*8882eb68SXin Tian val w = Flipped(Irrevocable(new AXI4BundleW(MemcedgeIn.bundle))) 670*8882eb68SXin Tian } 671*8882eb68SXin Tian // Unencrypt Chanel 672*8882eb68SXin Tian val out0 = new Bundle { 673*8882eb68SXin Tian val aw = Irrevocable(new AXI4BundleAW(MemcedgeIn.bundle)) 674*8882eb68SXin Tian val w = Irrevocable(new AXI4BundleW(MemcedgeIn.bundle)) 675*8882eb68SXin Tian } 676*8882eb68SXin Tian // Encrypt Chanel 677*8882eb68SXin Tian val out1 = new Bundle { 678*8882eb68SXin Tian val aw = Irrevocable(new AXI4BundleAW(MemcedgeIn.bundle)) 679*8882eb68SXin Tian val w = Irrevocable(new AXI4BundleW(MemcedgeIn.bundle)) 680*8882eb68SXin Tian } 681*8882eb68SXin Tian val enc_keyid = Output(UInt(KeyIDBits.W)) 682*8882eb68SXin Tian val enc_mode = Input(Bool()) 683*8882eb68SXin Tian val memenc_enable = Input(Bool()) 684*8882eb68SXin Tian }) 685*8882eb68SXin Tian io.enc_keyid := io.in.aw.bits.addr(PAddrBits-1, PAddrBits-KeyIDBits) 686*8882eb68SXin Tian 687*8882eb68SXin Tian val reg_idle = RegInit(true.B) 688*8882eb68SXin Tian val reg_enc_mode = RegInit(false.B) 689*8882eb68SXin Tian 690*8882eb68SXin Tian when(io.in.aw.fire) { 691*8882eb68SXin Tian reg_idle := false.B 692*8882eb68SXin Tian reg_enc_mode := io.enc_mode && io.memenc_enable 693*8882eb68SXin Tian } 694*8882eb68SXin Tian when(io.in.w.fire && io.in.w.bits.last) { 695*8882eb68SXin Tian reg_idle := true.B 696*8882eb68SXin Tian } 697*8882eb68SXin Tian 698*8882eb68SXin Tian val used_enc_mode = Mux(io.in.aw.fire, io.enc_mode && io.memenc_enable, reg_enc_mode) 699*8882eb68SXin Tian 700*8882eb68SXin Tian // Cut aw_queue.io.enq.ready from io.out*.awready 701*8882eb68SXin Tian val aw_queue = Module(new IrrevocableQueue(chiselTypeOf(io.in.aw.bits), 1, flow = true)) 702*8882eb68SXin Tian 703*8882eb68SXin Tian io.in.aw.ready := reg_idle && aw_queue.io.enq.ready 704*8882eb68SXin Tian aw_queue.io.enq.valid := io.in.aw.valid && reg_idle 705*8882eb68SXin Tian aw_queue.io.enq.bits := io.in.aw.bits 706*8882eb68SXin Tian 707*8882eb68SXin Tian val unencrypt_aw_queue = Module(new IrrevocableQueue(chiselTypeOf(io.in.aw.bits), MemencPipes+1, flow = true)) 708*8882eb68SXin Tian val unencrypt_w_queue = Module(new IrrevocableQueue(chiselTypeOf(io.in.w.bits), (MemencPipes+1)*2, flow = true)) 709*8882eb68SXin Tian 710*8882eb68SXin Tian aw_queue.io.deq.ready := Mux(used_enc_mode, io.out1.aw.ready, unencrypt_aw_queue.io.enq.ready) 711*8882eb68SXin Tian io.in.w.ready := (io.in.aw.fire || !reg_idle) && Mux(used_enc_mode, io.out1.w.ready, unencrypt_w_queue.io.enq.ready) 712*8882eb68SXin Tian 713*8882eb68SXin Tian unencrypt_aw_queue.io.enq.valid := !used_enc_mode && aw_queue.io.deq.valid 714*8882eb68SXin Tian unencrypt_w_queue.io.enq.valid := !used_enc_mode && io.in.w.valid && (io.in.aw.fire || !reg_idle) 715*8882eb68SXin Tian 716*8882eb68SXin Tian unencrypt_aw_queue.io.enq.bits := aw_queue.io.deq.bits 717*8882eb68SXin Tian unencrypt_w_queue.io.enq.bits := io.in.w.bits 718*8882eb68SXin Tian 719*8882eb68SXin Tian io.out0.aw.valid := unencrypt_aw_queue.io.deq.valid 720*8882eb68SXin Tian io.out0.w.valid := unencrypt_w_queue.io.deq.valid 721*8882eb68SXin Tian 722*8882eb68SXin Tian io.out0.aw.bits := unencrypt_aw_queue.io.deq.bits 723*8882eb68SXin Tian io.out0.w.bits := unencrypt_w_queue.io.deq.bits 724*8882eb68SXin Tian 725*8882eb68SXin Tian unencrypt_aw_queue.io.deq.ready := io.out0.aw.ready 726*8882eb68SXin Tian unencrypt_w_queue.io.deq.ready := io.out0.w.ready 727*8882eb68SXin Tian 728*8882eb68SXin Tian io.out1.aw.valid := used_enc_mode && aw_queue.io.deq.valid 729*8882eb68SXin Tian io.out1.w.valid := used_enc_mode && io.in.w.valid && (io.in.aw.fire || !reg_idle) 730*8882eb68SXin Tian 731*8882eb68SXin Tian io.out1.aw.bits := aw_queue.io.deq.bits 732*8882eb68SXin Tian io.out1.w.bits := io.in.w.bits 733*8882eb68SXin Tian} 734*8882eb68SXin Tian 735*8882eb68SXin Tianclass WriteChanelArbiter(implicit p: Parameters) extends MemEncryptModule 736*8882eb68SXin Tian{ 737*8882eb68SXin Tian val io = IO(new Bundle { 738*8882eb68SXin Tian // Unencrypt Chanel 739*8882eb68SXin Tian val in0 = new Bundle { 740*8882eb68SXin Tian val aw = Flipped(Irrevocable(new AXI4BundleAW(MemcedgeOut.bundle))) 741*8882eb68SXin Tian val w = Flipped(Irrevocable(new AXI4BundleW(MemcedgeOut.bundle))) 742*8882eb68SXin Tian } 743*8882eb68SXin Tian // Encrypt Chanel 744*8882eb68SXin Tian val in1 = new Bundle { 745*8882eb68SXin Tian val aw = Flipped(Irrevocable(new AXI4BundleAW(MemcedgeOut.bundle))) 746*8882eb68SXin Tian val w = Flipped(Irrevocable(new AXI4BundleW(MemcedgeOut.bundle))) 747*8882eb68SXin Tian } 748*8882eb68SXin Tian val out = new Bundle { 749*8882eb68SXin Tian val aw = Irrevocable(new AXI4BundleAW(MemcedgeOut.bundle)) 750*8882eb68SXin Tian val w = Irrevocable(new AXI4BundleW(MemcedgeOut.bundle)) 751*8882eb68SXin Tian } 752*8882eb68SXin Tian }) 753*8882eb68SXin Tian 754*8882eb68SXin Tian val validMask = RegInit(false.B) // 1:last send write req from Encrypt Chanel 755*8882eb68SXin Tian // 0:last send write req from Unencrypt Chanel 756*8882eb68SXin Tian val aw_choice = Wire(Bool()) // 1:Encrypt Chanel 0:Unencrypt Chanel 757*8882eb68SXin Tian val w_choice = RegInit(false.B) // 1:Encrypt Chanel 0:Unencrypt Chanel 758*8882eb68SXin Tian val reg_idle = RegInit(true.B) 759*8882eb68SXin Tian // Cut aw_queue.io.enq.ready from io.out*.awready 760*8882eb68SXin Tian val aw_queue = Module(new IrrevocableQueue(chiselTypeOf(io.in0.aw.bits), 1, flow = true)) 761*8882eb68SXin Tian 762*8882eb68SXin Tian when(io.in1.aw.fire) { 763*8882eb68SXin Tian validMask := true.B 764*8882eb68SXin Tian }.elsewhen(io.in0.aw.fire) { 765*8882eb68SXin Tian validMask := false.B 766*8882eb68SXin Tian }.otherwise { 767*8882eb68SXin Tian validMask := validMask 768*8882eb68SXin Tian } 769*8882eb68SXin Tian 770*8882eb68SXin Tian // --------------------------[Unencrypt pref] [Encrypt pref] 771*8882eb68SXin Tian aw_choice := Mux(validMask, !io.in0.aw.valid, io.in1.aw.valid) 772*8882eb68SXin Tian 773*8882eb68SXin Tian when(aw_queue.io.enq.fire) { 774*8882eb68SXin Tian reg_idle := false.B 775*8882eb68SXin Tian w_choice := aw_choice 776*8882eb68SXin Tian } 777*8882eb68SXin Tian when(io.out.w.fire && io.out.w.bits.last) { 778*8882eb68SXin Tian reg_idle := true.B 779*8882eb68SXin Tian } 780*8882eb68SXin Tian 781*8882eb68SXin Tian val used_w_choice = Mux(aw_queue.io.enq.fire, aw_choice, w_choice) 782*8882eb68SXin Tian 783*8882eb68SXin Tian io.in0.aw.ready := reg_idle && !aw_choice && aw_queue.io.enq.ready 784*8882eb68SXin Tian io.in1.aw.ready := reg_idle && aw_choice && aw_queue.io.enq.ready 785*8882eb68SXin Tian aw_queue.io.enq.valid := (io.in0.aw.valid || io.in1.aw.valid) && reg_idle 786*8882eb68SXin Tian aw_queue.io.enq.bits := Mux(aw_choice, io.in1.aw.bits, io.in0.aw.bits) 787*8882eb68SXin Tian 788*8882eb68SXin Tian // DecoupledIO connect IrrevocableIO 789*8882eb68SXin Tian io.out.aw.valid := aw_queue.io.deq.valid 790*8882eb68SXin Tian io.out.aw.bits := aw_queue.io.deq.bits 791*8882eb68SXin Tian aw_queue.io.deq.ready := io.out.aw.ready 792*8882eb68SXin Tian 793*8882eb68SXin Tian io.in0.w.ready := (aw_queue.io.enq.fire || !reg_idle) && !used_w_choice && io.out.w.ready 794*8882eb68SXin Tian io.in1.w.ready := (aw_queue.io.enq.fire || !reg_idle) && used_w_choice && io.out.w.ready 795*8882eb68SXin Tian 796*8882eb68SXin Tian io.out.w.valid := (aw_queue.io.enq.fire || !reg_idle) && Mux(used_w_choice, io.in1.w.valid, io.in0.w.valid) 797*8882eb68SXin Tian io.out.w.bits := Mux(used_w_choice, io.in1.w.bits, io.in0.w.bits) 798*8882eb68SXin Tian} 799*8882eb68SXin Tian 800*8882eb68SXin Tianclass RdataChanelRoute(implicit p: Parameters) extends MemEncryptModule 801*8882eb68SXin Tian{ 802*8882eb68SXin Tian val io = IO(new Bundle { 803*8882eb68SXin Tian val in_r = Flipped(Irrevocable(new AXI4BundleR(MemcedgeOut.bundle))) 804*8882eb68SXin Tian // Unencrypt Chanel 805*8882eb68SXin Tian val out_r0 = Irrevocable(new AXI4BundleR(MemcedgeOut.bundle)) 806*8882eb68SXin Tian // Encrypt Chanel 807*8882eb68SXin Tian val out_r1 = Irrevocable(new AXI4BundleR(MemcedgeOut.bundle)) 808*8882eb68SXin Tian val dec_rid = Output(UInt(MemcedgeOut.bundle.idBits.W)) 809*8882eb68SXin Tian val dec_mode = Input(Bool()) 810*8882eb68SXin Tian }) 811*8882eb68SXin Tian io.dec_rid := io.in_r.bits.id 812*8882eb68SXin Tian 813*8882eb68SXin Tian val r_sel = io.dec_mode 814*8882eb68SXin Tian 815*8882eb68SXin Tian io.out_r0.bits <> io.in_r.bits 816*8882eb68SXin Tian io.out_r1.bits <> io.in_r.bits 817*8882eb68SXin Tian 818*8882eb68SXin Tian io.out_r0.valid := io.in_r.valid && !r_sel 819*8882eb68SXin Tian io.out_r1.valid := io.in_r.valid && r_sel 820*8882eb68SXin Tian io.in_r.ready := Mux(r_sel, io.out_r1.ready, io.out_r0.ready) 821*8882eb68SXin Tian}