diff --git a/src/ieu/aes_instructions/aes64e.sv b/src/ieu/aes_instructions/aes64e.sv index 18f4e135e..98a18fa23 100644 --- a/src/ieu/aes_instructions/aes64e.sv +++ b/src/ieu/aes_instructions/aes64e.sv @@ -29,9 +29,11 @@ module aes64e( input logic [63:0] rs1, input logic [63:0] rs2, input logic finalround, + input logic [31:0] Sbox0Out, + output logic [31:0] SboxEIn, output logic [63:0] result ); - + logic [127:0] ShiftRowOut; logic [63:0] SboxOut, MixcolOut; @@ -39,8 +41,11 @@ module aes64e( aesshiftrow srow({rs2,rs1}, ShiftRowOut); // Apply substitution box to 2 lower words - aessboxword sbox0(ShiftRowOut[31:0], SboxOut[31:0]); - aessboxword sbox1(ShiftRowOut[63:32], SboxOut[63:32]); + // Use the shared sbox in zknde64.sv for the first sbox + assign SboxEIn = ShiftRowOut[31:0]; + assign SboxOut[31:0] = Sbox0Out; + + aessboxword sbox1(ShiftRowOut[63:32], SboxOut[63:32]); // instantiate second sbox // Apply mix columns operations aesmixcolumns mw0(SboxOut[31:0], MixcolOut[31:0]); diff --git a/src/ieu/aes_instructions/aes64ks1i.sv b/src/ieu/aes_instructions/aes64ks1i.sv index ac7d5849b..ef36e1cc6 100644 --- a/src/ieu/aes_instructions/aes64ks1i.sv +++ b/src/ieu/aes_instructions/aes64ks1i.sv @@ -28,20 +28,25 @@ module aes64ks1i( input logic [3:0] round, input logic [63:0] rs1, + input logic [31:0] Sbox0Out, + output logic [31:0] SboxKIn, output logic [63:0] result ); logic finalround; logic [7:0] rcon8; - logic [31:0] rcon, rs1Rotate, tmp2, SboxOut; + logic [31:0] rcon, rs1Rotate; rconlut128 rc(round, rcon8); // Get rcon value from lookup table assign rcon = {24'b0, rcon8}; // Zero-pad RCON assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value fo ruse in tmp2 assign finalround = (round == 4'b1010); // round 10 is the last one - assign tmp2 = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round - aessboxword sbox(tmp2, SboxOut); // Substitute bytes of value obtained for tmp2 using Rijndael sbox - assign result[31:0] = SboxOut ^ rcon; - assign result[63:32] = SboxOut ^ rcon; + assign SboxKIn = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round + + // Share sbox with encryption in zknde64. This module just sends value to shared sbox and gets result back + // send out value as SboxKIn, get back subsittuted result as Sbox0Out + + assign result[31:0] = Sbox0Out ^ rcon; + assign result[63:32] = Sbox0Out ^ rcon; endmodule diff --git a/src/ieu/kmu/zknde64.sv b/src/ieu/kmu/zknde64.sv index cae271f89..f4f79ddb4 100644 --- a/src/ieu/kmu/zknde64.sv +++ b/src/ieu/kmu/zknde64.sv @@ -35,14 +35,19 @@ module zknde64 import cvw::*; #(parameter cvw_t P) ( ); logic [63:0] aes64dRes, aes64eRes, aes64ks1iRes, aes64ks2Res; + logic [31:0] SboxEIn, SboxKIn, Sbox0In, Sbox0Out; if (P.ZKND_SUPPORTED) // ZKND supports aes64ds, aes64dsm, aes64im aes64d aes64d(.rs1(A), .rs2(B), .finalround(ZKNSelect[2]), .aes64im(ZKNSelect[3]), .result(aes64dRes)); // decode AES if (P.ZKNE_SUPPORTED) // ZKNE supports aes64es, aes64esm - aes64e aes64e(.rs1(A), .rs2(B), .finalround(ZKNSelect[2]), .result(aes64eRes)); + aes64e aes64e(.rs1(A), .rs2(B), .finalround(ZKNSelect[2]), .Sbox0Out, .SboxEIn, .result(aes64eRes)); + + // One S Box is always needed for aes64ks1i and is also needed for aes64e if that is supported. Put it at the top level to allow sharing + mux2 #(32) sboxmux(SboxEIn, SboxKIn, ZKNSelect[1], Sbox0In); + aessboxword sbox(Sbox0In, Sbox0Out); // Substitute bytes of value obtained for tmp2 using Rijndael sbox // Both ZKND and ZKNE support aes64ks1i and aes64ks2 instructions - aes64ks1i aes64ks1i(.round, .rs1(A), .result(aes64ks1iRes)); + aes64ks1i aes64ks1i(.round, .rs1(A), .Sbox0Out, .SboxKIn, .result(aes64ks1iRes)); aes64ks2 aes64ks2(.rs2(B), .rs1(A), .result(aes64ks2Res)); // Choose among decrypt, encrypt, key schedule 1, key schedule 2 results