Closed moidx closed 3 years ago
@moidx can you give me the exact values that are written into the sw app command reg? Also, did you intend to do a reseed right after an instantiate (you can, but not sure why)? Need to know the generate commands as well. Also, did you enable AES bypass? can you provide the CTRL write value as well?
we can add this test to run in the DV environment also Mark, that might make it easier for you to triage.
On Wed, Apr 7, 2021 at 12:33 PM mwbranstad @.***> wrote:
@moidx https://github.com/moidx can you give me the exact values that are written into the sw app command reg? Also, did you intend to do a reseed right after an instantiate (you can, but not sure why)? Need to know the generate commands as well. Also, did you enable AES bypass? can you provide the CTRL write value as well?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lowRISC/opentitan/issues/5982#issuecomment-815171354, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH2RSS325BHV2Y5WS5P453THSXQHANCNFSM42RJUEFA .
Here is my quick and dirty sequence. AES is turned off, no reseed cmd, just instantiate, then gen1 and gen2. Note the genbits returned are not the same in this case.
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h000000003); // enable block and disable AES block
$display("%t Request Instantiate cmd on app3...",$time);
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h0000001c1); // instantiate cmd: flag0=1, clen-12
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000001); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000002); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000003); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000004); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000005); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000006); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000007); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000008); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000009); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h00000000a); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h00000000b); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h00000000c); // additional data
wait_for_cmd_ack(0);
// begin check internal state
wr_reg({26'b0,CSRNG_HALT_MAIN_SM_OFFSET},32'h000000001);
cmp_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},32'h0000_0001,32'hffff_ffff);
wr_reg({26'b0,CSRNG_INT_STATE_NUM_OFFSET},32'h000000003);
cmp_reg({26'b0,CSRNG_INT_STATE_NUM_OFFSET},32'h0000_0003,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0001,32'hffff_ffff); // read 0
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0003,32'hffff_ffff); // read 1
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 2
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 3
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 4
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0002,32'hffff_ffff); // read 5
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 6
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 7
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 8
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0001,32'hffff_ffff); // read 9
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 10
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 11
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0000,32'hffff_ffff); // read 12
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},32'h0000_0001,32'hffff_ffff); // read 13
wr_reg({26'b0,CSRNG_HALT_MAIN_SM_OFFSET},32'h000000000);
cmp_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},32'h0000_0000,32'hffff_ffff);
// end internal state check
$display("%t Request Generate cmd on app3...",$time);
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h0000_1003); // generate cmd
wait_for_cmd_ack(0);
// check genbits through the register i/f
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0007,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
$display("%t Request Generate cmd on app3...",$time);
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h0000_1003); // generate cmd
wait_for_cmd_ack(0);
// check genbits through the register i/f
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_000d,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},32'h0000_0000,32'hffff_ffff);
Also, did you intend to do a reseed right after an instantiate (you can, but not sure why)?
This just part of the test vector specification. They expect that order of operations 1. instantiate, 2. reseed, 3. generate, 4. generate.
Reseed with clen = 0
If you do this then, this forces CSRNG to use the ES seed, and will always generate random results between Gen commands.
@mwbranstad, i've pushed a commit to #5973 that now allows you to run @moidx test in DV. The first thing it runs into you are already addressing as part of #5983
If you can pull down @moidx PR, you should be able to give it a try in your area. What sorts of problem are you having with top level sims?
Reseed with clen = 0
Is it possible to add support for reseed w/ clen = 0 and flag0 = true? This is something that will come up as part of FIPS known answer tests (I can double check with the lab).
@moidx the csrbg doc does not seem to support this at this time. However, if we use the same definition as the instantiate command, this function could be easy to add.
@tjaychen two problems with full chip. The build step seems to run, but the sim step fails with a message about ninja. Back when this was running ok, we can only run vcs (which is ok but a different tool set), but it cannot produce a wave to debug with - an issue was filed a few weeks ago by @rasmus-madsen
hmm...if you're seeing an issue with ninja, then that probably means your software build is not working.
if you go to your repo root, and just do the following, what error do you see?
$ ./meson_init.sh
$ ninja -C build-out all
Unable to find ninja. Please install ninja before running this command. make: *** [sw_build] Error 1
...work/mark.branstad/opentitan>./meson_init.sh Detected $REPO_TOP at /wdc/proj/cto/top/work/mark.branstad/opentitan. Object directory set at /wdc/proj/cto/top/work/mark.branstad/opentitan/build-out. Binary directory set at /wdc/proj/cto/top/work/mark.branstad/opentitan/build-bin. OpenTitan version: opentitan-snapshot-20191101-1-5094-gde7eba3d7
Unable to find ninja. Please install ninja before running this command
ah you need to install ninja build The following is just copied from the public install instructions. You can just pick the one you need.
$ sudo apt install autoconf bison build-essential clang-format curl doxygen \ flex g++ git libelf1 libelf-dev libftdi1-2 libftdi1-dev libncurses5 \ libssl-dev libusb-1.0-0 lsb-release make ninja-build pkgconf python3 \ python3-pip python3-setuptools python3-wheel python3-yaml srecord tree \ xsltproc zlib1g-dev xz-utils
On Wed, Apr 7, 2021 at 2:20 PM mwbranstad @.***> wrote:
Unable to find ninja. Please install ninja before running this command. make: *** [sw_build] Error 1
...work/mark.branstad/opentitan>./meson_init.sh Detected $REPO_TOP at /wdc/proj/cto/top/work/mark.branstad/opentitan. Object directory set at /wdc/proj/cto/top/work/mark.branstad/opentitan/build-out. Binary directory set at /wdc/proj/cto/top/work/mark.branstad/opentitan/build-bin. OpenTitan version: opentitan-snapshot-20191101-1-5094-gde7eba3d7
Unable to find ninja. Please install ninja before running this command
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lowRISC/opentitan/issues/5982#issuecomment-815272724, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH2RSRZWNFRCJDLWEXQ4OLTHTEDXANCNFSM42RJUEFA .
@rasmus-madsen or @tunghoang290780 i am assuming we cannot use these directions. Is there process that we use for WD internal?
I am enabling the block with AES enabled. The sequence of commands is as follows:
I have a verilator trace which I can try to share. Some quick observations:
cmd_stage_ack[2:0]
seems to toggle at the end of each command. intrs_state.cmd_hw_inst_exec
seems to be set early in the boot flow. I haven't looked into it yet. I also pushed some updates to lowrisc/opentitan#5973 to try fix some issues I found in the C code while debugging the waveforms.
@mwbranstad we cannot do anything that requires superuser privileges. but we do have ninja 1.10.2 installed
@tjaychen it looks like the meson_init scripts expects the riscV compiler to be located under /tools/ is this something specific to opentitan?
For the second point, you can override the toolchain path with TOOLCHAIN_PATH. For example, I've got it set to /src/lr/tools/lowrisc-toolchain-gcc-rv32imc-20200504-1
. Set it and then run meson_init.sh
and all should be well.
@mwbranstad we cannot do anything that requires superuser privileges. but we do have ninja 1.10.2 installed
@tjaychen it looks like the meson_init scripts expects the riscV compiler to be located under /tools/ is this something specific to opentitan?
if you look here you can see that there is a default that can also be overwritten by the user.
@mwbranstad @tjaychen I will see if I can get this going. but I have some challenges with the symbolic link for cc that points to an old version of cc (4.6) and I do not have permission to change it.
I will keep you posted
For the second point, you can override the toolchain path with TOOLCHAIN_PATH. For example, I've got it set to
/src/lr/tools/lowrisc-toolchain-gcc-rv32imc-20200504-1
. Set it and then runmeson_init.sh
and all should be well.
Hi Rupert, This is interesting, though I'm trying to think if there is some way we can leverage this and still use the package manager.
@rasmus-madsen,
I'm wondering if there might be a way to just install all the OT system deltas to a group directory, ie. with yum --installroot /our/team/directory/
(Probably a big hog) or rpm --relocate /our/team/directory/ -i <OTRQDPKG_RPMs>
. This would be super convenient moving forward. Though I don't know if this would then work with the TOOLCHAIN_PATH trick that Rupert mentioned here.
Any thoughts?
@martin-lueker I was thinking a bit along the same lines I am working on resolving some other issues first.
@mwbranstad @rasmus-madsen There are no RPM packages for the RISC-V toolchain (they are binary archives only). The TOOLCHAIN_PATH is about the RISC-V toolchain.
The problem you're seeing is with the host toolchain. For this toolchain you can and should use RPMs provided by RHEL (or maybe your IT department). RHEL provides updated toolchains as part of their SCLs, for example.
I guess the easiest option to figure out the best path forward is a meeting. If you'd like to get help there, please reach out to me or Rupert and we can schedule something.
I agree with what @imphil said. However, since I understand that you guys use module files for your EDA tools, I don't think it would be particularly difficult to wrap up a lowRISC toolchain in a module file (which could then set TOOLCHAIN_PATH for you). I'd guess that your IT department have lots of experience of this sort of thing.
I agree with what @imphil said. However, since I understand that you guys use module files for your EDA tools, I don't think it would be particularly difficult to wrap up a lowRISC toolchain in a module file (which could then set TOOLCHAIN_PATH for you). I'd guess that your IT department have lots of experience of this sort of thing.
the problem as I see it is that some of the RPMs that should be installed with the OS are missing. setting the toolchain_path is not a problem - not sure we want to set this with a module as that would make the toolchain shared by all users.
@moidx I looked at the NIST test vectors briefly. This appears very interesting, in that we need to support this and it should confirm the RTL results. I will look into this further.
"I am enabling the block with AES enabled. The sequence of commands is as follows:
0x000001c1 + 12 uint32_t (Instantiate) 0x00000002 (Reseed) 0x00004003 (Generate 4 x 128bit) I have a verilator trace which I can try to share. Some quick observations:
cmd_stage_ack[2:0] seems to toggle at the end of each command. intrs_state.cmd_hw_inst_exec seems to be set early in the boot flow. I haven't looked into it yet. I also pushed some updates to #5973 to try fix some issues I found in the C code while debugging the waveforms."
@moidx I have worked out the sequence that returns 4 x 128b through the sw port. It appears proper to me, but I noticed that the reseed command was requesting for new entropy (entropy_src). If the goal of this test is to be predictable, then the reseed command needs to have seed material also provided.
@moidx with pr #6711 merged now, you should be able to set up the DIF csrng tests and provide input nist test vectors and compare for the no_reseed and pr_false nist output vectors. The pr_true is almost there, but need to figure out the complete solution still, so hold off on those. If you need some sequencing example code, let me know and I can provide.
Hi @mwbranstad, I am revisiting this. Yes, it would be useful if you can share the nist vector sequencing you tried. I can try to add it to the dif level testing. Thanks!
Pasting a snapshot of my system verilog test file. All code is included in this one file to run nist vectors.
// Description: csrng system verilog unit test bench
// The intent of this test bench is to get basics running,
// such as clocks and reset, basic register writes and reads,
// basic block operation. No configurable BFMs are included
// in this environment.
module csrng_tb;
import tlul_pkg::*;
import entropy_src_pkg::*;
import aes_pkg::*;
import csrng_pkg::*;
import csrng_reg_pkg::*;
import lc_ctrl_pkg::*;
import lc_ctrl_state_pkg::*;
import otp_ctrl_reg_pkg::*;
import otp_ctrl_pkg::*;
import otp_ctrl_part_pkg::*;
// tests
bit smoke_test = 0;
bit sen_test = 0;
bit app1_cmd_test = 0;
bit ctr_drbg_test = 1;
bit alert_test = 0;
bit interrupt_test = 0;
// options
bit msg_rd_data = 0;
bit toggle_genbits_rdy = 1;
int vector_sel = 1; // 0 = no_reseed, 1 = pr_false, 2 = pr_true
// parameters`
localparam NHwApps = 3;
// localparam INSTID = 2;
localparam int Cmd = 3;
localparam int StateId = 4;
localparam int KeyLen = 256;
localparam int BlkLen = 128;
localparam int SeedLen = 384;
localparam int CtrLen = 32;
// localparam BE_ARB_N = 4;
// localparam BE_ARB_DW = KEYLEN+BLKLEN;
// localparam EsFifoDepth = 32;
localparam MAX_INTRP_CNT = 25;
localparam WD_DELAY = 1000*MAX_INTRP_CNT;
localparam [383:0] ENTROPY_INIT = 0;
localparam [383:0] ENTROPY_INIT_MWB = 384'h0000000C_0000000B_0000000A_00000009_00000008_00000007_00000006_00000005_00000004_00000003_00000002_00000001;
localparam [383:0] ENTROPY_INIT_SEN = 384'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_deadbeef;
// general signals
logic clk;
logic rst_n;
// otp_ctrl_part_pkg::otp_hw_cfg_t otp_hw_cfg;
// tlul signals
tlul_pkg::tl_h2d_t tl_i;
tlul_pkg::tl_d2h_t tl_o;
// entropy signals
entropy_src_pkg::entropy_src_hw_if_req_t entropy_src_hw_if_o;
entropy_src_pkg::entropy_src_hw_if_rsp_t entropy_src_hw_if_i;
// csrng app signals
csrng_pkg::csrng_req_t [NHwApps-1:0] csrng_cmd_i;
csrng_pkg::csrng_rsp_t [NHwApps-1:0] csrng_cmd_o;
// lifecycle signals
lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i;
// imported register parameters (for reference)
// Register Address
parameter int BlockAw = 7;
parameter logic [BlockAw-1:0] CSRNG_INTR_STATE_OFFSET = 7'h 0;
parameter logic [BlockAw-1:0] CSRNG_INTR_ENABLE_OFFSET = 7'h 4;
parameter logic [BlockAw-1:0] CSRNG_INTR_TEST_OFFSET = 7'h 8;
parameter logic [BlockAw-1:0] CSRNG_ALERT_TEST_OFFSET = 7'h c;
parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 7'h 10;
parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 7'h 14;
parameter logic [BlockAw-1:0] CSRNG_SUM_STS_OFFSET = 7'h 18;
parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 7'h 1c;
parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 20;
parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 24;
parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 28;
parameter logic [BlockAw-1:0] CSRNG_HALT_MAIN_SM_OFFSET = 7'h 2c;
parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STS_OFFSET = 7'h 30;
parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 34;
parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 38;
parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 3c;
parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 40;
parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 44;
//---------------------------
// testbench support
//---------------------------
parameter CNTR_MAX = 200;
bit errflag = 0;
logic [31:0] rd_data = 0;
logic [31:0] ctrl_reg = 0;
logic [31:0] thresh_level = 0;
logic [31:0] entropy_rate = 0;
logic [31:0] fifo_depth = 0;
logic [31:0] intrp_cnt = 0;
logic [31:0] cntr = 0;
bit aes_disable;
logic [1:0] ins_option;
logic [383:0] es_seed;
logic [31:0] set_cmd;
logic [383:0] set_adata;
logic [383:0] adata;
logic [383:0] entropy_incr = 384'h00000001_00000001_00000001_00000001_00000001_00000001_00000001_00000001_00000001_00000001_00000001_00000001;
logic [417:0] INTERNAL_STATE1 = 418'h10000000C_0000000B_0000000A_00000008_00000008_00000007_00000006_00000007_00000004_00000003_00000002_00000002_00000001;
logic [417:0] INTERNAL_STATE2old = 418'h1e000000c_e000000b_e000000a_e0000008_e0000008_e0000007_e0000006_e0000007_e0000004_e0000003_e0000002_e0000002_00000001;
logic [417:0] INTERNAL_STATE2 = 418'h1e000000d_e000000c_e000000b_e000000b_e0000009_e0000008_e0000007_e0000004_e0000005_e0000004_e0000003_e0000001_00000001;
logic [417:0] INTERNAL_STATE3 = 418'h1e0000001e0000007e0000001e0000002e0000001e000000fe0000001e0000001e0000001e0000007e0000001e000000000000001;
logic [127:0] genbits1= 128'h00000000_00000000_00000000_00000007;
logic [127:0] genbits2= 128'he0000005_e0000004_e0000003_e0000005;
logic [255:0] initial_key;
logic [127:0] initial_v;
logic [31:0] initial_rc;
bit chk_msg;
logic [31:0] chk_appnum;
logic [255:0] chk_key;
logic [127:0] chk_v;
logic [31:0] chk_rc;
logic [31:0] chk_sts;
logic [511:0] chk_bits;
initial
begin // force to patch reg errors
force u_csrng.u_reg.u_chk.err_o = 2'b0;
// force u_csrng.u_reg.u_reg_if.tl_err = 1'b0;
end
initial
begin // initial values
clk = 0;
rst_n = 0;
tl_i.a_valid = 0;
tl_i.a_address = 0;
tl_i.a_opcode = PutFullData; // write as default
tl_i.a_param = 3'h0;
tl_i.a_size = 2'h0;
tl_i.a_source = 8'h0;
tl_i.a_user = TL_A_USER_DEFAULT;
tl_i.a_mask = 0;
tl_i.a_data = 0;
tl_i.d_ready =1;
entropy_src_hw_if_i.es_ack = 0;
entropy_src_hw_if_i.es_bits = '0;
entropy_src_hw_if_i.es_fips = '0;
for (int i = 0; i < (NHwApps); i++) begin
csrng_cmd_i[i].csrng_req_valid = 0;
csrng_cmd_i[i].csrng_req_bus = 0;
csrng_cmd_i[i].genbits_ready = 1;
end
lc_hw_debug_en_i = lc_ctrl_pkg::On;
// otp_hw_cfg.data.en_csrng_sw_app_read = 8'hA5;
end
// bit aes_req;
// initial // aes pulse
// begin
// aes_req = 1'b0;
// repeat (4) @ (posedge clk);
// aes_req = 1'b1;
// repeat (1) @ (posedge clk);
// aes_req = 1'b0;
// end
initial // clock generation
begin
clk = 0;
forever begin
#4ns clk = !clk;
end
end
initial // reset generation
begin
repeat (4) @ (posedge clk);
rst_n = 1;
entropy_src_hw_if_i.es_bits = es_seed;
repeat (4) @ (posedge clk);
if (toggle_genbits_rdy) begin
forever begin
repeat (1) @ (posedge clk);
csrng_cmd_i[1].genbits_ready = 0;
repeat (6) @ (posedge clk);
csrng_cmd_i[1].genbits_ready = 1;
end
end
end
initial // watchdog
begin
repeat (WD_DELAY) @ (posedge clk);
$display("%t %c[1;31mCsrng watchdog triggered - FAIL!!! %c[0m",$time,27,27);
$finish;
end
task app_req(input int app, logic [383:0] adata, logic [19:0] glen, logic [3:0] flgs, logic [3:0] clen, logic [3:0] acmd);
repeat (1) @ (posedge clk); #1ps;
while (csrng_cmd_o[app].csrng_req_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
csrng_cmd_i[app].csrng_req_valid = 1;
csrng_cmd_i[app].csrng_req_bus = {glen,flgs,clen,acmd};
repeat (1) @ (posedge clk); #1ps;
while (csrng_cmd_o[app].csrng_req_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
for (int i=0; i < clen; i=i+1) begin
if (i==0) begin
csrng_cmd_i[app].csrng_req_bus = adata[1*32-1:0*32];
end else if (i==1) begin
csrng_cmd_i[app].csrng_req_bus = adata[2*32-1:1*32];
end else if (i==2) begin
csrng_cmd_i[app].csrng_req_bus = adata[3*32-1:2*32];
end else if (i==3) begin
csrng_cmd_i[app].csrng_req_bus = adata[4*32-1:3*32];
end else if (i==4) begin
csrng_cmd_i[app].csrng_req_bus = adata[5*32-1:4*32];
end else if (i==5) begin
csrng_cmd_i[app].csrng_req_bus = adata[6*32-1:5*32];
end else if (i==6) begin
csrng_cmd_i[app].csrng_req_bus = adata[7*32-1:6*32];
end else if (i==7) begin
csrng_cmd_i[app].csrng_req_bus = adata[8*32-1:7*32];
end else if (i==8) begin
csrng_cmd_i[app].csrng_req_bus = adata[9*32-1:8*32];
end else if (i==9) begin
csrng_cmd_i[app].csrng_req_bus = adata[10*32-1:9*32];
end else if (i==10) begin
csrng_cmd_i[app].csrng_req_bus = adata[11*32-1:10*32];
end else if (i==11) begin
csrng_cmd_i[app].csrng_req_bus = adata[12*32-1:11*32];
end
repeat (1) @ (posedge clk); #1ps;
while (csrng_cmd_o[app].csrng_req_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
end
csrng_cmd_i[app].csrng_req_valid = 0;
repeat (1) @ (posedge clk); #1ps;
while (csrng_cmd_o[app].csrng_req_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
endtask
//----------------------------
// NIST routines from 10.2.1
//----------------------------
task nist_block_encrypt(input bit aes_off, logic [255:0] key, logic [127:0] v,
output logic [127:0] blkout);
//repeat (1) @ (posedge clk); #1ps;
if (aes_off) begin
blkout = v;
end else begin
$display("%t %c[1;31mnist_block_encrypt does not support an AES function - FAIL!!! %c[0m",$time,27,27);
$finish;
end
endtask
task nist_update(input bit aes_off, logic [383:0] pdata, logic [255:0] key, logic [127:0] v,
output logic [255:0] keyout, logic [127:0] vout);
static bit msg = 0;
localparam SEEDLEN = 384;
localparam KEYLEN = 256;
localparam CTR_LEN = 32;
localparam BLKLEN = 128;
int temp_len;
logic [1023:0] temp;
logic [BLKLEN-1:0] V;
logic [BLKLEN-1:0] output_block;
logic [CTR_LEN-1:0] inc;
// repeat (1) @ (posedge clk); #1ps;
if (msg) begin
$display("%t upd pdata: %h",$time,pdata);
$display("%t upd keyin: %h",$time,key);
$display("%t upd vin: %h",$time,v);
end
V = v;
temp_len = 0;
while (temp_len < SEEDLEN) begin
if (CTR_LEN < BLKLEN) begin
// inc = (V[CTR_LEN-1:0]+1) % 2**CTR_LEN; // rightmost - doesn't work as is
inc = (V[CTR_LEN-1:0]+1); // rightmost
V = {(V[BLKLEN-1:BLKLEN-CTR_LEN]),inc}; // leftmost
end else begin
V = (V+1) % 2^BLKLEN;
$display("%t %c[1;31Unexpected path taken in inc loop!! %c[0m",$time,27,27);
$finish;
end
if (msg) begin
$display("%t upd V: %h",$time,V);
$display("%t upd inc: %h",$time,V);
end
nist_block_encrypt(aes_off,key,V,output_block);
if (msg) begin
$display("%t upd output_block: %h",$time,output_block);
end
temp = {temp,output_block};
temp_len = temp_len + BLKLEN;
if (msg)
$display("%t upd temp_len: %0d",$time,temp_len);
end
if (temp_len !== SEEDLEN) begin
$display("%t %c[1;31Error in computation of temp_len!! %c[0m",$time,27,27);
$finish;
end
if (msg) begin
$display("%t upd temp1: %h",$time,temp);
end
temp = temp[SEEDLEN-1:0]; // leftmost
if (msg) begin
$display("%t upd temp2: %h",$time,temp);
end
temp = temp ^ pdata;
keyout = temp[SEEDLEN-1:SEEDLEN-KEYLEN]; // leftmost
vout = temp[KEYLEN-1:0]; // rightmost
if (msg) begin
$display("%t upd keyout: %h",$time,keyout);
$display("%t upd vout: %h",$time,vout);
end
endtask
task nist_instantiate(input bit aes_off, logic [383:0] entropy_input,
logic [383:0] personalization_string, logic [7:0] security_strength,
output logic [255:0] keyout, logic [127:0] vout, logic [31:0] reseed_counter);
static bit msg = 1;
localparam SEEDLEN = 384;
localparam KEYLEN = 256;
localparam CTR_LEN = 32;
localparam BLKLEN = 128;
int temp_len;
logic [383:0] seed_material;
logic [127:0] v_init;
logic [127:0] v_temp;
logic [255:0] key_init;
logic [255:0] key_temp;
temp_len = SEEDLEN; // temp = len(personalization_string)
// if (temp_len < SEEDLEN), then personalization_string = {personalization_string,{SEEDLEN-temp_len{1'b0}};
if (temp_len !== SEEDLEN) begin
$display("%t %c[1;31Error in computation of temp_len!! %c[0m",$time,27,27);
$finish;
end
seed_material = entropy_input ^ personalization_string;
key_init = '0;
v_init = '0;
nist_update(aes_off,seed_material,key_init,v_init,key_temp,v_temp);
keyout = key_temp;
vout = v_temp;
reseed_counter = {{CTR_LEN-1{1'b0}},1'b1};
if (msg) begin
$display("%t ins keyout: %h",$time,keyout);
$display("%t ins vout: %h",$time,vout);
$display("%t ins rc: %h",$time,reseed_counter);
end
endtask
task wr_reg(input logic [31:0] addr, logic [31:0] wdata);
repeat (1) @ (posedge clk); #1ps;
while (tl_o.a_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
tl_i.a_valid =1;
tl_i.a_address = addr;
tl_i.a_opcode = PutFullData; // write = 0
tl_i.a_param = 3'h0;
tl_i.a_size = 2'h2;
tl_i.a_source = 8'h0;
tl_i.a_mask = 4'hf;
tl_i.a_data = wdata;
repeat (1) @ (posedge clk); #1ps;
tl_i.a_valid = 0;
tl_i.a_address = 0;
tl_i.a_opcode = PutFullData; // write as default
tl_i.a_param = 3'h0;
tl_i.a_size = 2'h0;
tl_i.a_source = 8'h0;
tl_i.a_mask = 0;
tl_i.a_data = 0;
repeat (1) @ (posedge clk); #1ps;
endtask
task rd_reg(input logic [31:0] addr, output logic [31:0] rdata);
repeat (1) @ (posedge clk); #1ps;
tl_i.d_ready =1;
while (tl_o.a_ready != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
tl_i.a_valid =1;
tl_i.a_address = addr;
tl_i.a_opcode = Get; // read = 4
tl_i.a_param = 3'h0;
tl_i.a_size = 2'h2;
tl_i.a_source = 8'h0;
tl_i.a_mask = 4'hf;
while (tl_o.d_valid != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
tl_i.a_valid = 0;
tl_i.d_ready = 1;
tl_i.a_address = 0;
tl_i.a_opcode = PutFullData; // write as default
tl_i.a_param = 3'h0;
tl_i.a_size = 2'h0;
tl_i.a_source = 8'h0;
tl_i.a_mask = 0;
tl_i.a_data = 0;
rdata = tl_o.d_data;
if (msg_rd_data) $display("%t rdata = %h",$time,rdata);
repeat (1) @ (posedge clk); #1ps;
endtask
task cmp_reg(input logic [31:0] addr, logic [31:0] cdata, logic [31:0] cmask);
logic [31:0] rdata;
rd_reg(addr,rdata);
if ((rdata & cmask) !== cdata) begin
$display("%t reg addr: %h",$time,addr);
$display("%t act raw data: %h",$time,rdata);
$display("%t exp mask data: %h",$time,(rdata & cmask));
$display("%t exp data: %h",$time,cdata);
$display("%t %c[1;31mRead register miscompare!!! %c[0m",$time,27,27);
$finish;
// errflag = 1;
end
endtask
task wait_for_cmd_rdy(input bit debug);
rd_reg({26'b0,CSRNG_SW_CMD_STS_OFFSET},rd_data); // check the CMD_RDY status bit
if (debug) $display("%t CSRNG_SW_CMD_STS: rd_data: %h",$time,rd_data);
while (rd_data[0] != 1) begin
repeat (1) @ (posedge clk); #1ps;
rd_reg({26'b0,CSRNG_SW_CMD_STS_OFFSET},rd_data);
if (debug) $display("%t CSRNG_SW_CMD_STS: rd_data: %h",$time,rd_data);
end
endtask
task wait_for_cmd_ack(input bit debug);
rd_reg({26'b0,CSRNG_INTR_STATE_OFFSET},rd_data); // check the CMD_ACK status bit
if (debug) $display("%t CSRNG_INTR_STATE: rd_data: %h",$time,rd_data);
while (rd_data[0] != 1) begin
repeat (1) @ (posedge clk); #1ps;
rd_reg({26'b0,CSRNG_INTR_STATE_OFFSET},rd_data);
if (debug) $display("%t CSRNG_INTR_STATE: rd_data: %h",$time,rd_data);
end
$display("%t Received a command ack...",$time);
// clear ack status bit
wr_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0001); // clear the CMD_ACK status bit
// check ack status bit
rd_reg({26'b0,CSRNG_INTR_STATE_OFFSET},rd_data); // check the CMD_ACK status bit
if (debug) $display("%t ,CSRNG_INTR_STATE: rd_data: %h",$time,rd_data);
if (rd_data[0] === 1'b1) $display("%t ,CSRNG_INTR_STATE: bit 0 is unepectedly set!!! %h",$time,rd_data);
endtask
task wait_for_genbits_vld(input bit debug);
rd_reg({26'b0,CSRNG_GENBITS_VLD_OFFSET},rd_data); // check the CMD_RDY status bit
if (debug) $display("%t CSRNG_GENBITS_VLD: rd_data: %h",$time,rd_data);
while (rd_data[0] != 1) begin
repeat (1) @ (posedge clk); #1ps;
rd_reg({26'b0,CSRNG_GENBITS_VLD_OFFSET},rd_data);
if (debug) $display("%t CSRNG_GENBITS_VLD: rd_data: %h",$time,rd_data);
end
endtask
task send_app_cmd(input bit msg, logic [31:0] appnum, input logic [31:0] acmd, logic [383:0] adata);
if (1) $display("%t send_app_cmd running on app %0d",$time,appnum);
if (appnum == 3) begin
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},acmd); // app cmd
if ( acmd[7:4] == 12) begin
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[1*32-1:0*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[2*32-1:1*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[3*32-1:2*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[4*32-1:3*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[5*32-1:4*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[6*32-1:5*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[7*32-1:6*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[8*32-1:7*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[9*32-1:8*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[10*32-1:9*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[11*32-1:10*32]); // additional data
wait_for_cmd_rdy(0);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},adata[12*32-1:11*32]); // additional data
end
if ( acmd[3:0] != 3) begin
wait_for_cmd_ack(0);
end
end else if (appnum == 1) begin
app_req(appnum,adata,0,1,12,1); // app=app_num,seed,glen=0,flgs=1,clen=12,acmd=1 (instantiate - flag0 on)
while (csrng_cmd_o[appnum].csrng_rsp_ack != 1) begin
repeat (1) @ (posedge clk); #1ps;
end
$display("%t Ack received for App %0d",$time,appnum);
end else begin
$display("%t %c[1;31msend_app_cmd does not support App %0d %c[0m",$time,appnum,27,27);
$finish;
end
endtask
task check_internal_state(input bit msg, logic [31:0] appnum, logic [31:0] sts, logic [255:0] key, logic [127:0] v, logic [31:0] rc);
static int dump_int_st = 0;
if (1) $display("%t check_internal_state running on app %0d",$time,appnum);
// halt main state machine
wr_reg({26'b0,CSRNG_HALT_MAIN_SM_OFFSET},32'h0000_0001);
rd_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},rd_data); // check the main sm status bit
if (msg) $display("%t CSRNG_MAIN_SM_STS: rd_data: %h",$time,rd_data);
while (rd_data[0] != 1) begin
repeat (1) @ (posedge clk); #1ps;
rd_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},rd_data);
if (msg) $display("%t CSRNG_MAIN_SM_STS: rd_data: %h",$time,rd_data);
end
// verify that main sm is halted
cmp_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},32'h0000_0001,32'hffff_ffff);
wr_reg({26'b0,CSRNG_INT_STATE_NUM_OFFSET},appnum);
cmp_reg({26'b0,CSRNG_INT_STATE_NUM_OFFSET},appnum,32'hffff_ffff);
if (dump_int_st) begin
msg_rd_data = 1;
for (int i=0; i < 14; i=i+1) begin
$display("%t word %0d ",$time,i);
rd_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},rd_data);
end
msg_rd_data = 0;
end else begin
if (msg) $display("%t rc word0 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},rc,32'hffff_ffff); // reseed cntr [31:0]
if (msg) $display("%t v word0 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},v[1*32-1:0*32],32'hffff_ffff); // V
if (msg) $display("%t v word1 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},v[2*32-1:1*32],32'hffff_ffff); // read 2
if (msg) $display("%t v word2 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},v[3*32-1:2*32],32'hffff_ffff); // read 3
if (msg) $display("%t v word3 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},v[4*32-1:3*32],32'hffff_ffff); // read 4
if (msg) $display("%t key word0 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[1*32-1:0*32],32'hffff_ffff); // read 5
if (msg) $display("%t key word1 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[2*32-1:1*32],32'hffff_ffff); // read 6
if (msg) $display("%t key word2 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[3*32-1:2*32],32'hffff_ffff); // read 7
if (msg) $display("%t key word3 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[4*32-1:3*32],32'hffff_ffff); // read 8
if (msg) $display("%t key word4 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[5*32-1:4*32],32'hffff_ffff); // read 9
if (msg) $display("%t key word5 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[6*32-1:5*32],32'hffff_ffff); // read 10
if (msg) $display("%t key word6 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[7*32-1:6*32],32'hffff_ffff); // read 11
if (msg) $display("%t key word7 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},key[8*32-1:7*32],32'hffff_ffff); // read 12
if (msg) $display("%t status word0 ",$time);
cmp_reg({26'b0,CSRNG_INT_STATE_VAL_OFFSET},sts,32'hffff_ffff); // read 13
end
wr_reg({26'b0,CSRNG_HALT_MAIN_SM_OFFSET},32'h000000000);
cmp_reg({26'b0,CSRNG_MAIN_SM_STS_OFFSET},32'h0000_0000,32'hffff_ffff);
endtask
task check_genbits(input bit msg, logic [31:0] appnum, logic [127:0] genbits);
if (msg) $display("%t check_genbits running on app %0d",$time,appnum);
if (genbits != '0) begin
wait_for_genbits_vld(0);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[1*32-1:0*32],32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[2*32-1:1*32],32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[3*32-1:2*32],32'hffff_ffff);
cmp_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[4*32-1:3*32],32'hffff_ffff);
end else begin
wait_for_genbits_vld(0);
rd_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[1*32-1:0*32]);
rd_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[2*32-1:1*32]);
rd_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[3*32-1:2*32]);
rd_reg({26'b0,CSRNG_GENBITS_OFFSET},genbits[4*32-1:3*32]);
end
endtask
task test_end(input bit errflag);
//cmp_reg(ENTROPY_SRC_ES_STATUS_OFFSET,32'h0000_0000,32'hffff_ffff);
if (errflag == 1) begin
$display("%t %c[1;31mCsrng Test FAIL!!! %c[0m",$time,27,27);
end else begin
$display("%t %c[1;32mCsrng Test PASSED... %c[0m",$time,27,27);
end
$finish;
endtask
always @ (posedge entropy_src_hw_if_o.es_req)
begin
if (rst_n) begin // handle reset case
if (entropy_src_hw_if_o.es_req) begin
repeat (1) @ (posedge clk); #1ps;
entropy_src_hw_if_i.es_ack = 1'b1;
// entropy_cntr=entropy_cntr+entropy_incr;
// entropy_src_hw_if_i.es_bits = entropy_cntr;
entropy_src_hw_if_i.es_bits = es_seed;
repeat (1) @ (posedge clk); #1ps;
entropy_src_hw_if_i.es_ack = 1'b0;
end else begin
#1ps;
end
end
end
//-------------------------------------
// testcases
//-------------------------------------
initial begin
while (rst_n !== 1'b1) begin // avoid initial x case
repeat (1) @ (posedge clk); #1ps;
end
// repeat (10) @ (posedge clk); #1ps;
// Comon register setup
// -> placeholder
//repeat (20) @ (posedge clk); #1ps;
//-----------------------------------------------------
if (smoke_test) begin
$display("%t Running smoke_test...",$time);
// CONFIGURE
cmp_reg({26'b0,CSRNG_CTRL_OFFSET},32'h0000_0000,32'hffff_ffff);
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h000000003);
cmp_reg({26'b0,CSRNG_CTRL_OFFSET},32'h0000_0003,32'hffff_ffff);
// INSTANTIATE
chk_msg = 0;
chk_appnum = 3;
chk_sts = 1;
chk_key = 256'h0000000000000000000000000000000100000000000000000000000000000002;
chk_v = 128'h00000000000000000000000000000003;
chk_rc = 32'h0000_0001;
wait_for_cmd_rdy(0);
$display("%t Request Instantiate cmd on SW App3...",$time);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h000000101); // instantiate cmd
wait_for_cmd_ack(0);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// GENERATE
chk_msg = 0;
chk_appnum = 3;
chk_sts = 1;
chk_key = 256'h0000000000000000000000000000000500000000000000000000000000000006;
chk_v = 128'h00000000000000000000000000000007;
chk_rc = 32'h0000_0002;
chk_bits = 512'h00000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
wait_for_cmd_rdy(0);
$display("%t Request Generate cmd on SW app3...",$time);
wr_reg({26'b0,CSRNG_CMD_REQ_OFFSET},32'h0000_1003); // generate cmd
wait_for_genbits_vld(0);
check_genbits(chk_msg,chk_appnum,chk_bits[512-1:384]);
wait_for_cmd_ack(0);
// final check: check the internal state
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
end else if (app1_cmd_test) begin
$display("%t Running app1_cmd_test...",$time);
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h000000001); // enable
// INSTANTIATE -------------------------------------------------------------------------
set_cmd = 32'h000001c1;
set_adata = 384'hdf5d73faa468649edda33b5cca79b0b05600419ccb7a879ddfec9db32ee494e5531b51de16a30f769262474c73bec010;
chk_msg = 0;
chk_appnum = 1;
chk_sts = 1;
chk_key = 256'h8c52f901632d522774c08fad0eb2c33b98a701a1861aecf3d8a25860941709fd;
chk_v = 128'h217b52142105250243c0b2c206b8f59e;
chk_rc = 32'h0000_0001;
$display("%t Request Instantiate cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// app_req(chk_appnum,0,1,12,1); // app=app_num,glen=0,flgs=1,clen=12,acmd=1 (instantiate - flag0 on)
// while (csrng_cmd_o[app_num].csrng_rsp_ack != 1) begin
// repeat (1) @ (posedge clk); #1ps;
// end
// $display("%t Ack received for App %0d",$time,app_num);
// repeat (20) @ (posedge clk); #1ps;
// app_req(app_num,4,0,0,3); // app=app_num,glen=4,flgs=0,clen=0,acmd=3 (generate - flag0 off)
// while (csrng_cmd_o[app_num].genbits_valid != 1) begin
// repeat (1) @ (posedge clk); #1ps;
// end
// $display("%t Genbits received for App %0d",$time,app_num);
// if (csrng_cmd_o[app_num].genbits_bus !== genbits1) begin
// $display("%t Actual: %h",$time,csrng_cmd_o[app_num].genbits_bus);
// $display("%t Expected: %h",$time,genbits1);
// $display("%t Error in genbits cmd...",$time); errflag = 1;
// end
//
// repeat (200) @ (posedge clk); #1ps;
end else if (sen_test) begin
$display("%t Running sen_test...",$time);
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h000000001); // enable
// INSTANTIATE -------------------------------------------------------------------------
set_cmd = 32'h000001c1;
set_adata = 384'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000deadbeef;
chk_msg = 0;
chk_appnum = 1;
chk_sts = 32'h00000001;
chk_key = 256'h530f8afb_c74536b9_a963b4f1_c4cb738b_cea7403d_4d606b6e_074ec5d3_baf39d18;
chk_v = 128'h726003ca_37a62a74_d1a2f58e_abab8b61;
chk_rc = 32'h0000_0001;
$display("%t Request Instantiate cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
end else if (ctr_drbg_test) begin
$display("%t Running ctr_drbg...",$time);
if (vector_sel == 2) begin
$display("%t Using pr_true vectors...",$time);
end else if (vector_sel == 1) begin
$display("%t Using pr_false vectors...",$time);
end else begin
$display("%t Using no_reseed vectors...",$time);
end
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h00000001); // enable block
// INSTANTIATE -------------------------------------------------------------------------
set_cmd = 32'h000001c1;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
// pr_true
set_adata = 384'hfaf346c9c8afbc5ab6e33ce492247fac6db9a7ba4297557f587a42563ddf56c90e41c6afb56233815b74e091bac7d8e5;
chk_sts = 32'h0000_0001;
chk_key = 256'ha9fccc320fea8ae31f80881556ef0c27a31ee7870ff73e115f348785872ccbd1;
chk_v = 128'h7c21c56582c419f58ad6151fcfc1ed6b;
chk_rc = 32'h0000_0001;
end else if (vector_sel == 1) begin
// pr_false
set_adata = 384'he4bc23c5089a19d86f4119cb3fa08c0a4991e0a1def17e101e4c14d9c323460a7c2fb58e0b086c6c57b55f56cae25bad;
chk_sts = 32'h0000_0001;
chk_key = 256'hb7b3a93ecfdf2f61c622ad3afb6bff818736a09c9391157e1902d10a79d0db12;
chk_v = 128'h0e4fb6443cae46188617aad8bfe46e23;
chk_rc = 32'h0000_0001;
end else begin
// no_reseed
set_adata = 384'hdf5d73faa468649edda33b5cca79b0b05600419ccb7a879ddfec9db32ee494e5531b51de16a30f769262474c73bec010;
chk_sts = 32'h0000_0001;
chk_key = 256'h8c52f901632d522774c08fad0eb2c33b98a701a1861aecf3d8a25860941709fd;
chk_v = 128'h217b52142105250243c0b2c206b8f59e;
chk_rc = 32'h0000_0001;
end
$display("%t Request Instantiate 1 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// RESEED -------------------------------------------------------------------------
if (vector_sel != 0) begin
set_cmd = 32'h000001c2;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
// pr_false
set_adata = 384'hdfc111252d7146922713720ae1e348a07ae403b5238fefb4e8592f6f6cc4a61c94828db84c6faecd1502261008011f2c;
chk_sts = 32'h0;
chk_key = 256'h0;
chk_v = 128'h0;
chk_rc = 32'h0;
end else if (vector_sel == 1) begin
// pr_false
set_adata = 384'hfd85a836bba85019881e8c6bad23c9061adc75477659acaea8e4a01dfe07a1832dad1c136f59d70f8653a5dc118663d6;
chk_sts = 32'h0000_0001;
chk_key = 256'hd230044c2594510d195ffe9923de8848bdbd19f24d0e7558b28e55b2d4de7841;
chk_v = 128'he18637ff12f514f37adc2013a40f38c1;
chk_rc = 32'h0000_0001;
end else begin
// no_reseed
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end
$display("%t Request Reseed 1 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
if (vector_sel == 1) begin
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
end
end
// GENERATE 1 ----------------------------------------------------------------------------
set_cmd = 32'h0000_4003;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
chk_bits = 512'h0;
chk_sts = 32'h0000_0001;
chk_key = 256'h59ab2aa229c17b2ccf5b633ad905aa4396d717cd7109c4396176b445e23b54b0;
chk_v = 128'h9ac50e38805dab58baf6429436e00b39;
chk_rc = 32'h0000_0002;
end else if (vector_sel == 1) begin
chk_bits = 512'h0;
chk_sts = 32'h0000_0001;
chk_key = 256'hec871bb7a4f2c45dccdd0e514a21628959aa21e9643934f619b2709b3e38697c;
chk_v = 128'hd8bbe7bfc60bfb710f39acd1088c9f41;
chk_rc = 32'h0000_0002;
end else begin
chk_bits = 512'h0b16530817166e90cf763d08378fca1ec01a083914117211a69b1bf1359fbe3e6e48e546ce7ab38fc5e00eb858d7e45d5d6e1012c58a553e88a65ec749de93f9;
chk_sts = 32'h0000_0001;
chk_key = 256'h72f4af5c93258eb3eeec8c0cacea6c1d1978a4fad44312725f1ac43b167f2d52;
chk_v = 128'he86f6d07dfb551cebad80e6bf6830ac4;
chk_rc = 32'h0000_0002;
end
$display("%t Request Generate 1 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
// check genbits through the register i/f
check_genbits(chk_msg,chk_appnum,chk_bits[512-1:384]);
check_genbits(chk_msg,chk_appnum,chk_bits[384-1:256]);
check_genbits(chk_msg,chk_appnum,chk_bits[256-1:128]);
check_genbits(chk_msg,chk_appnum,chk_bits[128-1:0]);
// final command wait
wait_for_cmd_ack(0);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// RESEED PR 1 -------------------------------------------------------------------------
if (vector_sel == 2) begin
set_cmd = 32'h000001c2;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
// pr_false
set_adata = 384'hd4528bac5b99c772347d44f4ece79bc811ca8ebea9483fa5f5040c02f77069dad1aec7adaa8a9a6a9ddabab045d328a90;
chk_sts = 32'h0;
chk_key = 256'h0;
chk_v = 128'h0;
chk_rc = 32'h0;
end else if (vector_sel == 1) begin
// pr_false
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end else begin
// no_reseed
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end
$display("%t Request Reseed PR 1 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
end
// GENERATE 2 ----------------------------------------------------------------------------
set_cmd = 32'h0000_4003;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
chk_bits = 512'hbc013dc891db12c34ad11944805bf13dfd67ff2c23176d83f5b396b69e400042252e11816c3095421137181a5d0ee37c83a339c58d080946ca90aa437d50d9cf;
chk_sts = 32'h0000_0001;
chk_key = 256'h48f4632bbc79c4bde48a8588a5395afcdccc84f2a3b25b8be2715cd8f9dd8a6b;
chk_v = 128'h24f485205e3baf899b8c226c2ffc73ce;
chk_rc = 32'h0000_0003;
// chk_rc = 32'h0000_0002; // TODO: fix bug here
end else if (vector_sel == 1) begin
chk_bits = 512'hb2cb8905c05e5950ca31895096be29ea3d5a3b82b269495554eb80fe07de43e193b9e7c3ece73b80e062b1c1f68202fbb1c52a040ea2478864295282234aaada;
chk_sts = 32'h0000_0001;
chk_key = 256'he728308a0e92cbacb269d12246d8e2d24cf5fcc678aa09564132e4972c456eda;
chk_v = 128'hc95f38da34ecb65ebf8b34c32bc215a5;
chk_rc = 32'h0000_0003;
end else begin
chk_bits = 512'hd1c07cd95af8a7f11012c84ce48bb8cb87189e99d40fccb1771c619bdf82ab2280b1dc2f2581f39164f7ac0c510494b3a43c41b7db17514c87b107ae793e01c5;
chk_sts = 32'h0000_0001;
chk_key = 256'h1a1c6e5f1cccc6974436e5fd3f015bc8e9dc0f90053b73e3c19d4dfd66d1b85a;
chk_v = 128'h53c78ac61a0bac9d7d2e92b1e73e3392;
chk_rc = 32'h0000_0003;
end
$display("%t Request Generate 2 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
// check genbits through the register i/f
check_genbits(chk_msg,chk_appnum,chk_bits[512-1:384]);
check_genbits(chk_msg,chk_appnum,chk_bits[384-1:256]);
check_genbits(chk_msg,chk_appnum,chk_bits[256-1:128]);
check_genbits(chk_msg,chk_appnum,chk_bits[128-1:0]);
// final command wait
wait_for_cmd_ack(0);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// UNINSTANTIATE -------------------------------------------------------------------------
set_cmd = 32'h0000_0005;
chk_msg = 0;
chk_appnum = 3;
chk_rc = 32'h0000_0000;
chk_key = 256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
chk_v = 128'h00000000_00000000_00000000_00000000;
chk_sts = 32'h0000_0000;
$display("%t Request uninstantiate cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
if (vector_sel == 4) begin
$display("%t Debug stop...",$time);
$finish;
end
// INSTANTIATE -------------------------------------------------------------------------
set_cmd = 32'h000001c1;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
set_adata = 384'he5d15d661cc3a5a7fb15f940554461a7c1b886a9c939d632d36d3e785c713ea2dff944485b9b35bd7503245b2081f82d;
chk_sts = 32'h0000_0001;
chk_key = 256'hb6ded79ddb86931e52764db1918f122c0f1fc6948459bd5cd423fbabe682a3ba;
chk_v = 128'had9947826c3d1fc9a4a1d1d55587cda3;
chk_rc = 32'h0000_0001;
end else if (vector_sel == 1) begin
set_adata = 384'hedfdb55e77d418a63e4414dfd42225ed257cf74e99325fba26e8f3a4524a71bc80a731af23256908cb4675a9c253ea6f;
chk_sts = 32'h0000_0001;
chk_key = 256'hbef23fa5b0912e1f9727a02e10e95666ebdbb773d45234d421a63677e8b9eca4;
chk_v = 128'hf2c732651483437c1ae48027b755dfe1;
chk_rc = 32'h0000_0001;
end else begin
set_adata = 384'h3b6fb634d35bb386927374f991c1cbc9fafba3a43c432dc411b7b2fa96cfcce8d305e135ff9bc460dbc7ba3990bf8060;
chk_sts = 32'h0000_0001;
chk_key = 256'h68603ccf141e853f3b10c008550ab842345ce399712346aa16f977292c3c51f0;
chk_v = 128'ha165e2ffc83dee140a654fb7e5b9b5ee;
chk_rc = 32'h0000_0001;
end
$display("%t Request Instantiate 2 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// RESEED -------------------------------------------------------------------------
if (vector_sel != 0) begin
set_cmd = 32'h000001c2;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
// pr_false
set_adata = 384'h0b2c49e216ef47df86254867b61969ac631c4b6a68f644cb2a6b89c7f6282faf403dccd9177b90aba32535fccea488e9;
chk_sts = 32'h0;
chk_key = 256'h0;
chk_v = 128'h0;
chk_rc = 32'h0;
end else if (vector_sel == 1) begin
// pr_false
set_adata = 384'ha9372fea93d607fbbc75a97b7f65f2d4ae8c06bd184981572e888a35c5794d2bb380a4ae04bba27f2efcc9e7914b96dc;
chk_sts = 32'h0000_0001;
chk_key = 256'hfa8718f94465637aafba7e3ae46724b1a7273a7af78c54745e6cf22cb4238bf2;
chk_v = 128'h47fb218a3c1d31b7a7e01e829666cddd;
chk_rc = 32'h0000_0001;
end else begin
// no_reseed
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end
$display("%t Request Reseed 1 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
if (vector_sel == 1) begin
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
end
end
// GENERATE 3 ----------------------------------------------------------------------------
set_cmd = 32'h0000_4003;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
chk_bits = 512'h0;
chk_sts = 32'h0000_0001;
chk_key = 256'h4446242d27df8496599e18a414956a0de73f037d68166c1c99cf31ba40893531;
chk_v = 128'h044a309cb8f887d3293b25d25e67dd19;
chk_rc = 32'h0000_0002;
end else if (vector_sel == 1) begin
chk_bits = 512'h0;
chk_sts = 32'h0000_0001;
chk_key = 256'haf3a71c889964fa84a4209646702cff0a4c61d10e4d6eb288f67842f026bff75;
chk_v = 128'h6f2e3ab7a6e8697cdcf4060896e66c0f;
chk_rc = 32'h0000_0002;
end else begin
chk_bits = 512'hcc69107953b23610bde171fcd81092a0402b2bffa6d39aba0548ae97d85a4bb7af011898fd97dfe0dc264a2eb0792e212b626c66ae97d59895096d59a62cd2a8;
chk_sts = 32'h0000_0001;
chk_key = 256'hf3ae40b109548d29a30a56c848a2ee97c09706efdd2760fcd85c1f6b0386ec9;
chk_v = 128'h85cbbdd3d168a48fdf485b5ee8fec428;
chk_rc = 32'h0000_0002;
end
$display("%t Request Generate 3 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
// check genbits through the register i/f
check_genbits(chk_msg,chk_appnum,chk_bits[512-1:384]);
check_genbits(chk_msg,chk_appnum,chk_bits[384-1:256]);
check_genbits(chk_msg,chk_appnum,chk_bits[256-1:128]);
check_genbits(chk_msg,chk_appnum,chk_bits[128-1:0]);
// final command wait
wait_for_cmd_ack(0);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
// RESEED PR 2 -------------------------------------------------------------------------
if (vector_sel == 2) begin
set_cmd = 32'h000001c2;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
// pr_false
set_adata = 384'hc6c46e98fa4b87d5e398df48aada1a713c2f7bceb366a1a746daff600618835f57475379631daad46ef01c78f4ed2154;
chk_sts = 32'h0;
chk_key = 256'h0;
chk_v = 128'h0;
chk_rc = 32'h0;
end else if (vector_sel == 1) begin
// pr_false
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end else begin
// no_reseed
set_adata = '0;
chk_sts = '0;
chk_key = '0;
chk_v = '0;
chk_rc = '0;
end
$display("%t Request Reseed PR 2 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
end
// GENERATE 4 ----------------------------------------------------------------------------
set_cmd = 32'h0000_4003;
chk_msg = 0;
chk_appnum = 3;
if (vector_sel == 2) begin
chk_bits = 512'h4963a8a8442d8d03ed868f027021c669d3a07980e56fe5ef6100413b9a1c23072977324f2d80bc4d1e2595400d4901f20e4bf17f960055dc1ff346c423807010;
chk_sts = 32'h0000_0001;
chk_key = 256'h3d845aa67b16eb390f8a6b8bda0998a7106dac0f40ed4e89fa6ce835423ecc57;
chk_v = 128'h1779a85b3222d0510bb0e30f09f8af0e;
chk_rc = 32'h0000_0003;
// chk_rc = 32'h0000_0002; // TODO: fix bug here
end else if (vector_sel == 1) begin
chk_bits = 512'h11b1a0f0bb935ec0c54e089e0cd20832d1f00e7069f30e9ea2e35b7f15ecf0577d0e90035bf0f91ffd9e8a1fa8a507503739afbec19393e02c9b7c230cdea36f;
chk_sts = 32'h0000_0001;
chk_key = 256'h6d3e50247b7197bd25978339272004e3bd7d854e277cc8390f3f2081a2584c2d;
chk_v = 128'h85f63f7d2dcb861010e525ffdd221cb3;
chk_rc = 32'h0000_0003;
end else begin
chk_bits = 512'h83a836fe1cde053164555529409337dc4fec6844594fdf15083ba9d1001eb945c3b96a1bcee3990e1e51f85c80e9f4e04de34e57b640f6cae8ed68e99624712;
chk_sts = 32'h0000_0001;
chk_key = 256'hfb63a736069acd25a9ba49865d167e8c506e787c999e5509faa75129c2c26625;
chk_v = 128'h3bccc6785beb8d11ace6816d0378ad1e;
chk_rc = 32'h0000_0003;
end
$display("%t Request Generate 4 cmd on app3...",$time);
send_app_cmd(chk_msg,chk_appnum,set_cmd,set_adata);
// check genbits through the register i/f
check_genbits(chk_msg,chk_appnum,chk_bits[512-1:384]);
check_genbits(chk_msg,chk_appnum,chk_bits[384-1:256]);
check_genbits(chk_msg,chk_appnum,chk_bits[256-1:128]);
check_genbits(chk_msg,chk_appnum,chk_bits[128-1:0]);
// final command wait
wait_for_cmd_ack(0);
check_internal_state(chk_msg,chk_appnum,chk_sts,chk_key,chk_v,chk_rc);
end else if (alert_test) begin
$display("%t Running alert_test...",$time);
wr_reg({26'b0,CSRNG_CTRL_OFFSET},32'h000000003); // disable AES
for (int i = 0; i < 16; i++) begin
$display("%t Setting bit %0d",$time,i);
wr_reg({26'b0,CSRNG_ERR_CODE_TEST_OFFSET},i); // set a fatal error
$display("%t Check if set %0d",$time,i);
cmp_reg({26'b0,CSRNG_ERR_CODE_OFFSET},(1 << i),(1 << i));
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008,32'hffff_ffff);
// clear err_code reg
$display("%t Clear interrupt status reg",$time);
wr_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008); // clear reg
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0000,32'hffff_ffff);
end
for (int i = 20; i < 26; i++) begin
$display("%t Setting bit %0d",$time,i);
wr_reg({26'b0,CSRNG_ERR_CODE_TEST_OFFSET},i); // set a fatal error
$display("%t Check if set %0d",$time,i);
cmp_reg({26'b0,CSRNG_ERR_CODE_OFFSET},(1 << i),(1 << i));
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008,32'hffff_ffff);
// clear err_code reg
$display("%t Clear interrupt status reg",$time);
wr_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008); // clear reg
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0000,32'hffff_ffff);
end
for (int i = 28; i < 31; i++) begin
$display("%t Setting bit %0d",$time,i);
wr_reg({26'b0,CSRNG_ERR_CODE_TEST_OFFSET},i); // set a fatal error
$display("%t Check if set %0d",$time,i);
cmp_reg({26'b0,CSRNG_ERR_CODE_OFFSET},(1 << i),(1 << i));
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008,32'hffff_ffff);
// clear err_code reg
$display("%t Clear interrupt status reg",$time);
wr_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0008); // clear reg
cmp_reg({26'b0,CSRNG_INTR_STATE_OFFSET},32'h0000_0000,32'hffff_ffff);
end
end else begin // initial begin
$display("%t No test selected...",$time);
end
//-----------------------------------------------------
repeat (10) @ (posedge clk);
test_end(errflag);
end
//-------------------------------------
// csrng instantiation
//-------------------------------------
csrng
#(.NHwApps(NHwApps))
u_csrng
(
.clk_i(clk),
.rst_ni(rst_n),
.tl_i(tl_i),
.tl_o(tl_o),
.otp_en_csrng_sw_app_read_i(otp_ctrl_pkg::Enabled),
.lc_hw_debug_en_i(lc_hw_debug_en_i),
// Entropy Interface
.entropy_src_hw_if_o(entropy_src_hw_if_o),
.entropy_src_hw_if_i(entropy_src_hw_if_i),
// Entropy Interface
.cs_aes_halt_i(1'b0),
.cs_aes_halt_o(),
// Application Interfaces
.csrng_cmd_i(csrng_cmd_i),
.csrng_cmd_o(csrng_cmd_o),
.alert_tx_o(),
.alert_rx_i(4'h0),
.intr_cs_cmd_req_done_o(),
.intr_cs_entropy_req_o(),
.intr_cs_hw_inst_exc_o(),
.intr_cs_fatal_err_o()
);
// //-------------------------------------
// // aes quick test
// //-------------------------------------
// parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplLut;
//
// csrng_block_encrypt #(
// .SBoxImpl(SBoxImpl),
// .Cmd(Cmd),
// .StateId(StateId),
// .BlkLen(BlkLen),
// .KeyLen(KeyLen)
// ) u_csrng_block_encrypt (
// .clk_i(clk),
// .rst_ni(rst_n),
// .block_encrypt_bypass_i(1'b0),
// .block_encrypt_enable_i(1'b1),
// .block_encrypt_lc_hw_debug_not_on_i(1'b1),
// .block_encrypt_req_i(aes_req),
// .block_encrypt_rdy_o(),
//// .block_encrypt_key_i(256'h8c52f901632d522774c08fad0eb2c33b98a701a1861aecf3d8a25860941709fd),
//// .block_encrypt_v_i(128'h217b52142105250243c0b2c206b8f59f),
// .block_encrypt_key_i(256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f),
// .block_encrypt_v_i(128'h00112233445566778899aabbccddeeff),
// .block_encrypt_cmd_i(3'h6),
// .block_encrypt_id_i(4'h3),
// .block_encrypt_ack_o(),
// .block_encrypt_rdy_i(1'b1),
// .block_encrypt_cmd_o(),
// .block_encrypt_id_o(),
// .block_encrypt_v_o(),
// .block_encrypt_quiet_o(),
// .block_encrypt_aes_cipher_sm_err_o(),
// .block_encrypt_sfifo_blkenc_err_o()
// );
endmodule
Thanks @mwbranstad, I am trying the following vector, which is used in the tb from your previous comment:
COUNT = 0
EntropyInput = df5d73faa468649edda33b5cca79b0b05600419ccb7a879ddfec9db32ee494e5531b51de16a30f769262474c73bec010
Nonce =
PersonalizationString =
** INSTANTIATE:
Key = 8c52f901632d522774c08fad0eb2c33b98a701a1861aecf3d8a25860941709fd
V = 217b52142105250243c0b2c206b8f59e
I am using flag0 = 1
in order to skip mixing the entropy source, however, the update command seems to be mixing the seed coming from the entropy source.
It seems that this is happening because in csrng_core.sv
assign cmd_entropy_avail = entropy_src_hw_if_i.es_ack;
// Capture entropy from entropy_src
assign entropy_src_seed_d =
(cmd_entropy_avail && flag0_q) ? '0 : // special case where zero is used
cmd_entropy_avail ? (entropy_src_hw_if_i.es_bits ^ seed_diversification) :
entropy_src_seed_q;
assign entropy_src_fips_d =
(cmd_entropy_avail && flag0_q) ? '0 : // special case where zero is used
cmd_entropy_avail ? entropy_src_hw_if_i.es_fips :
entropy_src_fips_q;
When flag0_q = 1
, isn't that sufficient to set the entropy_src_seed to '0
?
just for clarity, the "update" command should not be used for the nist vectors test, as that is a private one - maybe you just meant "instantiate" command. For the scenario, your instantiate command should be -> 32'h0000_01c1 (flag0 set, clen=12, instantiate cmd) Then set the "adata" to the seed value (EntropyInput). Once done, the internal state should have the above key, v, and rc values updated.
I can look at a wave if need be.
Hi @mwbranstad, that is correct, I am looking at the instantiate
command with flag0
set (32'h0000_01c1
). In order to implement the KAT test for the DRBG.instantiate
function, I need to access to the internal state values k
and v
. Right now CSRNG is mixing the entropy_src with adata
even if flag0 = 1'b1
, which causes the KAT test to fail.
I ended up looking at the internal update function to try to debug why the output was different from the expected k
, v
values and found that even if flag0 = 1'b1
, entropy_seed
was still getting mixed with adata
because entropy_src_hw_if_i.es_ack = false
. Since the KAT test is purely driven by sw, I added the question in the comment above to check if it is possible to modify the entropy_src_seed
assignment in csrng_core.sv
to something like this:
assign cmd_entropy_avail = entropy_src_hw_if_i.es_ack;
// Capture entropy from entropy_src
assign entropy_src_seed_d =
flag0_q ? '0 : // special case where zero is used
cmd_entropy_avail ? (entropy_src_hw_if_i.es_bits ^ seed_diversification) :
entropy_src_seed_q;
assign entropy_src_fips_d =
flag0_q ? '0 : // special case where zero is used
cmd_entropy_avail ? entropy_src_hw_if_i.es_fips :
entropy_src_fips_q;
The above changes are sufficient to get the KAT test to pass, but I am not sure if there are any additional changes required.
lowrisc/opentitan#7309
lowrisc/opentitan#7303 introduces an initial implementation of KAT tests for the DRBG functionality. The is still an outstanding issue with the generate output when running the test at the top level which is being tracked in lowrisc/opentitan#7505.
I am in the process of writing a functional test case to verify the hw + dif implementation using a known test vector.
https://github.com/lowRISC/opentitan/pull/5973
Test plan based on the test vector requirements:
Currently I can get to step 5 without detecting errors, and I see
CSRNG_GENBITS_VLD_GENBITS_VLD_BIT
set to 1 before reading fromCSRNG_GENBITS_REG
, however I am reading all 0's.Does the CSRNG software path require any additional initialization?
CC: @mwbranstad, @martin-lueker. @tjaychen
Test vectors: https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/random-number-generators