diff --git a/.github/workflow_metadata/pr_hash b/.github/workflow_metadata/pr_hash index 025d6cceb..d44f69a83 100644 --- a/.github/workflow_metadata/pr_hash +++ b/.github/workflow_metadata/pr_hash @@ -1 +1 @@ -ca1b84bffeaa6505df7813ec15b149c024eda5b4f6f72bbb8e7bf0a809e8620b7387021dfc397cd11953682ab2f798fd \ No newline at end of file +97174a8f4e139cd861cb3bbda2ce818e7d1dc2f237783d95448535e0204fde3de4d12e6dd81b16f56bd97711609540df \ No newline at end of file diff --git a/.github/workflow_metadata/pr_timestamp b/.github/workflow_metadata/pr_timestamp index 0637a28ff..a8afb3b31 100644 --- a/.github/workflow_metadata/pr_timestamp +++ b/.github/workflow_metadata/pr_timestamp @@ -1 +1 @@ -1727494929 \ No newline at end of file +1728602320 \ No newline at end of file diff --git a/src/doe/rtl/doe_core_cbc.sv b/src/doe/rtl/doe_core_cbc.sv index 213fe2d80..087e7a04d 100644 --- a/src/doe/rtl/doe_core_cbc.sv +++ b/src/doe/rtl/doe_core_cbc.sv @@ -250,8 +250,6 @@ module doe_core_cbc( st_IV_engine_stars: begin if (IV_updated_delayed) - IV_enc_state <= st_IV_engine_idle; - else if(enc_ready) IV_enc_state <= st_IV_engine_idle; else IV_enc_state <= st_IV_engine_stars; diff --git a/src/ecc/rtl/ecc_add_sub_mod_alter.sv b/src/ecc/rtl/ecc_add_sub_mod_alter.sv index ae11bcbe6..4118caa40 100644 --- a/src/ecc/rtl/ecc_add_sub_mod_alter.sv +++ b/src/ecc/rtl/ecc_add_sub_mod_alter.sv @@ -76,23 +76,30 @@ module ecc_add_sub_mod_alter #( ); - assign sub_n = !sub_i; assign opb0 = sub_i ? ~opb_i : opb_i; - assign opb1 = sub_i ? prime_i : ~prime_i; always_ff @(posedge clk or negedge reset_n) begin if(!reset_n) begin r0_reg <= '0; carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; end else if (zeroize) begin r0_reg <= '0; carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; end else if (add_en_i) begin r0_reg <= r0; carry0_reg <= carry0; + sub_n <= !sub_i; + if (sub_i) + opb1 <= prime_i; + else + opb1 <= ~prime_i; end end @@ -110,6 +117,6 @@ module ecc_add_sub_mod_alter #( assign ready_o = push_result_reg[0]; - assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0 : (carry0_reg) ? r0 : r1; + assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0_reg : (carry0_reg) ? r0_reg : r1; endmodule diff --git a/src/ecc/rtl/ecc_arith_unit.sv b/src/ecc/rtl/ecc_arith_unit.sv index a2c78f18e..9357aa409 100644 --- a/src/ecc/rtl/ecc_arith_unit.sv +++ b/src/ecc/rtl/ecc_arith_unit.sv @@ -46,7 +46,6 @@ module ecc_arith_unit // DATA PORT input wire [3 : 0] ecc_cmd_i, - input wire sca_en_i, input wire [ADDR_WIDTH-1 : 0] addr_i, input wire wr_op_sel_i, input wire wr_en_i, @@ -101,7 +100,6 @@ module ecc_arith_unit .reset_n(reset_n), .zeroize(zeroize), .ecc_cmd_i(ecc_cmd_i), - .sca_en_i(sca_en_i), .digit_i(digit_in), .instr_o(ecc_instr_s), .req_digit_o(req_digit), diff --git a/src/ecc/rtl/ecc_dsa_ctrl.sv b/src/ecc/rtl/ecc_dsa_ctrl.sv index 290b6c94c..c8882a57e 100644 --- a/src/ecc/rtl/ecc_dsa_ctrl.sv +++ b/src/ecc/rtl/ecc_dsa_ctrl.sv @@ -142,9 +142,7 @@ module ecc_dsa_ctrl logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] r_reg; logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] s_reg; logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] IV_reg; - logic [REG_SIZE-1 : 0] lambda; logic [REG_SIZE-1 : 0] lambda_reg; - logic [REG_SIZE-1 : 0] masking_rnd; logic [REG_SIZE-1 : 0] masking_rnd_reg; logic [REG_SIZE-1 : 0] pk_chk_reg; @@ -153,7 +151,6 @@ module ecc_dsa_ctrl logic [REG_SIZE-1 : 0] scalar_in_reg; logic [REG_SIZE-1 : 0] scalar_rnd_reg; - logic [(REG_SIZE+RND_SIZE)-1 : 0] scalar_out; logic [(REG_SIZE+RND_SIZE)-1 : 0] scalar_out_reg; logic scalar_sca_en; logic scalar_sca_busy_o; @@ -164,10 +161,6 @@ module ecc_dsa_ctrl logic [REG_SIZE-1 : 0] hmac_drbg_result; logic hmac_busy; - logic sca_point_rnd_en; - logic sca_mask_sign_en; - logic sca_scalar_rnd_en; - //interface with kv client logic kv_privkey_write_en; logic [REG_OFFSET_W-1:0] kv_privkey_write_offset; @@ -247,7 +240,6 @@ module ecc_dsa_ctrl .reset_n(reset_n), .zeroize(zeroize_reg), .ecc_cmd_i(pm_cmd_reg), - .sca_en_i(sca_scalar_rnd_en), .addr_i(prog_instr.mem_addr), .wr_op_sel_i(prog_instr.opcode.op_sel), @@ -274,9 +266,9 @@ module ecc_dsa_ctrl .privKey(privkey_reg), .hashed_msg(msg_reduced_reg), .IV(IV_reg), - .lambda(lambda), + .lambda(lambda_reg), .scalar_rnd(scalar_rnd_reg), - .masking_rnd(masking_rnd), + .masking_rnd(masking_rnd_reg), .drbg(hmac_drbg_result) ); @@ -293,21 +285,10 @@ module ecc_dsa_ctrl .en_i(scalar_sca_en), .data_i(scalar_in_reg), .rnd_i(scalar_rnd_reg[RND_SIZE-1 : 0]), - .data_o(scalar_out), + .data_o(scalar_out_reg), .busy_o(scalar_sca_busy_o) ); - //---------------------------------------------------------------- - // side-channel config update - // Update functionality for SCA registers in the core. - //---------------------------------------------------------------- - - always_comb - begin : SCA_config - scalar_out_reg = (sca_scalar_rnd_en)? scalar_out : (REG_SIZE+RND_SIZE)'(scalar_in_reg << RND_SIZE); - lambda_reg = (sca_point_rnd_en)? lambda : ONE_CONST; - masking_rnd_reg = (sca_mask_sign_en)? masking_rnd : ZERO_CONST; - end // SCA_config //---------------------------------------------------------------- // ecc_reg_update @@ -319,10 +300,6 @@ module ecc_dsa_ctrl //Mask the command if KV clients are not idle cmd_reg = {hwif_out.ECC_CTRL.DH_SHAREDKEY.value, hwif_out.ECC_CTRL.CTRL.value} & {3{kv_seed_ready}} & {3{kv_privkey_ready}}; zeroize_reg = hwif_out.ECC_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; - - sca_point_rnd_en = 1'b1; - sca_mask_sign_en = 1'b1; - sca_scalar_rnd_en = 1'b1; end //there is a clk cycle memory read delay between hw_privkey_we and read_reg @@ -481,7 +458,7 @@ module ecc_dsa_ctrl always_comb hwif_in.ECC_CTRL.PCR_SIGN.hwclr = hwif_out.ECC_CTRL.PCR_SIGN.value; // TODO add other interrupt hwset signals (errors) - always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset = error_flag_reg; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset = error_flag_edge; always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = ecc_status_done_p; @@ -674,19 +651,16 @@ module ecc_dsa_ctrl always_ff @(posedge clk or negedge reset_n) begin : error_detection - if(!reset_n) begin - error_flag_reg <= '0; - end - else if(zeroize_reg) begin - error_flag_reg <= '0; - end - else begin - error_flag_reg <= error_flag; - end + if(!reset_n) + error_flag_reg <= 1'b0; + else if(zeroize_reg) + error_flag_reg <= 1'b0; + else if (error_flag) + error_flag_reg <= 1'b1; end // error_detection - - assign error_flag_edge = error_flag & (!error_flag_reg); + assign error_flag_edge = error_flag & (!error_flag_reg); + assign privkey_input_outofrange = signing_process & ((privkey_reg == 0) | (privkey_reg >= GROUP_ORDER)); assign r_output_outofrange = signing_process & (hw_r_we & (read_reg == 0)); assign s_output_outofrange = signing_process & (hw_s_we & (read_reg == 0)); @@ -738,15 +712,22 @@ module ecc_dsa_ctrl verifying_process <= 0; sharedkey_process <= 0; end + else if (error_flag | error_flag_reg) begin + prog_cntr <= ECC_NOP; + cycle_cnt <= '0; + pm_cmd_reg <= '0; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= '0; + hmac_init <= 0; + scalar_sca_en <= 0; + keygen_process <= 0; + signing_process <= 0; + verifying_process <= 0; + sharedkey_process <= 0; + end else begin - if (error_flag_edge) begin - prog_cntr <= ECC_NOP; - cycle_cnt <= 2'd3; - pm_cmd_reg <= '0; - scalar_sca_en <= 0; - hmac_init <= 0; - end - else if (subcomponent_busy) begin //Stalled until sub-component is done + if (subcomponent_busy) begin //Stalled until sub-component is done prog_cntr <= prog_cntr; cycle_cnt <= 2'd3; pm_cmd_reg <= '0; diff --git a/src/ecc/rtl/ecc_hmac_drbg_interface.sv b/src/ecc/rtl/ecc_hmac_drbg_interface.sv index 0683761ca..02afd5b4d 100644 --- a/src/ecc/rtl/ecc_hmac_drbg_interface.sv +++ b/src/ecc/rtl/ecc_hmac_drbg_interface.sv @@ -38,8 +38,7 @@ module ecc_hmac_drbg_interface#( parameter REG_SIZE = 384, - parameter [REG_SIZE-1 : 0] GROUP_ORDER = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973, - parameter [REG_SIZE-1 : 0] LFSR_INIT_SEED = 384'hc48555929cd58779f4819c1e6570c2ef20bccd503284e2d366f3273a66e9719b07ac999c80740d6277af88ceb4c3029c // a random value + parameter [REG_SIZE-1 : 0] GROUP_ORDER = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 ) ( // Clock and reset. @@ -115,8 +114,7 @@ module ecc_hmac_drbg_interface#( hmac_drbg #( .REG_SIZE(REG_SIZE), - .HMAC_DRBG_PRIME(GROUP_ORDER), - .LFSR_INIT_SEED(LFSR_INIT_SEED) + .HMAC_DRBG_PRIME(GROUP_ORDER) ) hmac_drbg_i ( .clk(clk), @@ -200,14 +198,14 @@ module ecc_hmac_drbg_interface#( scalar_rnd_reg <= '0; masking_rnd_reg <= '0; drbg_reg <= '0; - lfsr_seed_reg <= LFSR_INIT_SEED; + lfsr_seed_reg <= '0; end else if (zeroize) begin lambda_reg <= '0; scalar_rnd_reg <= '0; masking_rnd_reg <= '0; drbg_reg <= '0; - lfsr_seed_reg <= LFSR_INIT_SEED; + lfsr_seed_reg <= '0; end else if (hmac_done_edge) begin @@ -223,7 +221,7 @@ module ecc_hmac_drbg_interface#( scalar_rnd_reg <= '0; masking_rnd_reg <= '0; drbg_reg <= '0; - lfsr_seed_reg <= LFSR_INIT_SEED; + lfsr_seed_reg <= '0; end endcase end @@ -263,8 +261,6 @@ module ecc_hmac_drbg_interface#( begin : counter_reg_update if (!reset_n) counter_reg <= '0; - else if (zeroize) - counter_reg <= '0; else counter_reg <= counter_reg + 1; end // counter_reg_update diff --git a/src/ecc/rtl/ecc_pm_ctrl.sv b/src/ecc/rtl/ecc_pm_ctrl.sv index ea8032f57..c161e475d 100644 --- a/src/ecc/rtl/ecc_pm_ctrl.sv +++ b/src/ecc/rtl/ecc_pm_ctrl.sv @@ -54,7 +54,6 @@ module ecc_pm_ctrl // from arith_unit input wire [3 : 0] ecc_cmd_i, - input wire sca_en_i, input wire digit_i, output pm_instr_struct_t instr_o, output logic req_digit_o, @@ -160,19 +159,19 @@ module ecc_pm_ctrl default : begin stalled <= 1'b0; stall_cntr <= '0; end endcase end - else if ((!stalled) | (stalled & (stall_cntr == 0))) begin + else begin stalled <= 0; unique case (prog_cntr) NOP : begin // Waiting for new valid command ecc_cmd_reg <= ecc_cmd_i; unique case (ecc_cmd_i) KEYGEN_CMD : begin // keygen - mont_cntr <= (sca_en_i)? Secp384_SCA_MONT_COUNT : Secp384_MONT_COUNT; + mont_cntr <= Secp384_SCA_MONT_COUNT; prog_cntr <= PM_INIT_G_S; end SIGN_CMD : begin // signing - mont_cntr <= (sca_en_i)? Secp384_SCA_MONT_COUNT : Secp384_MONT_COUNT; + mont_cntr <= Secp384_SCA_MONT_COUNT; prog_cntr <= PM_INIT_G_S; end @@ -194,7 +193,7 @@ module ecc_pm_ctrl end DH_SHARED_CMD : begin // DH shared key - mont_cntr <= (sca_en_i)? Secp384_SCA_MONT_COUNT : Secp384_MONT_COUNT; + mont_cntr <= Secp384_SCA_MONT_COUNT; prog_cntr <= PM_INIT_DH_S; end diff --git a/src/ecc/rtl/ecc_scalar_blinding.sv b/src/ecc/rtl/ecc_scalar_blinding.sv index 712a5c3b7..9326307c2 100644 --- a/src/ecc/rtl/ecc_scalar_blinding.sv +++ b/src/ecc/rtl/ecc_scalar_blinding.sv @@ -60,7 +60,7 @@ module ecc_scalar_blinding #( // Equivalent to $ceil(REG_SIZE/RADIX) + 1 localparam REG_DIG_NUM = (((REG_SIZE + RADIX) - 1) / RADIX) + 1; //13 localparam RND_DIG_NUM = (((RND_SIZE + RADIX) - 1) / RADIX) + 1; //7 - localparam FULL_DIG_NUM = REG_DIG_NUM + RND_DIG_NUM; //20 + localparam FULL_DIG_NUM = REG_DIG_NUM + RND_DIG_NUM - 1; //19 localparam FULL_REG_SIZE = REG_DIG_NUM * RADIX; localparam FULL_RND_SIZE = RND_DIG_NUM * RADIX; @@ -225,14 +225,14 @@ module ecc_scalar_blinding #( always_ff @(posedge clk or negedge reset_n) begin if (!reset_n) begin - product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0] - 1; + product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0]; operand_idx_reg <= '0; shift_state <= 0; add1_cin <= 0; carry_garbage_bits0 <= '0; end else if (zeroize) begin - product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0] - 1; + product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0]; operand_idx_reg <= '0; shift_state <= 0; add1_cin <= 0; @@ -245,7 +245,7 @@ module ecc_scalar_blinding #( add1_cin <= 0; end else begin - if (product_idx < (FULL_DIG_NUM-1)) begin + if (product_idx < FULL_DIG_NUM) begin if (shift_state) begin product_idx_reg <= product_idx + 1; if (product_idx < (REG_DIG_NUM-1)) @@ -272,7 +272,7 @@ module ecc_scalar_blinding #( assign accu_store = (accu_done)? 0 : (!shift_state); assign accu_shift = (accu_done)? 0 : shift_state; - assign accu_done = (product_idx == (FULL_DIG_NUM-1)); + assign accu_done = (product_idx == FULL_DIG_NUM); // Determines which a and b is pushed through the multiplier always_comb begin diff --git a/src/ecc/tb/ecc_arith_unit_tb.sv b/src/ecc/tb/ecc_arith_unit_tb.sv deleted file mode 100644 index 1a01493e0..000000000 --- a/src/ecc/tb/ecc_arith_unit_tb.sv +++ /dev/null @@ -1,674 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//====================================================================== -// -// ecc_arith_unit_tb.sv -// -------- -// -// -// -//====================================================================== - -module ecc_arith_unit_tb #( - parameter TEST_VECTOR_NUM = 15 -) -(); - - //---------------------------------------------------------------- - // Internal constant and parameter definitions. - //---------------------------------------------------------------- - parameter [383 : 0] E_a_MONT = 384'hfffffffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffbffffffff00000002fffffffdffffffff; - parameter [383 : 0] ONE_p_MONT = 384'h100000000ffffffffffffffff0000000100000000; - parameter [383 : 0] G_X_MONT = 384'h299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e6e1e26a4ee117bfa3dd07565fc8607664d3aadc2; - parameter [383 : 0] G_Y_MONT = 384'h5a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050cd385481a72d556e23043dad1f8af93c2b78abc2; - parameter [383 : 0] G_Z_MONT = 384'h100000000ffffffffffffffff0000000100000000; - //parameter [383 : 0] R2_MONT = 384'h10000000200000000fffffffe000000000000000200000000fffffffe000000010000000000000000; - - // q - parameter [383 : 0] group_order = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973; - parameter [383 : 0] R2_q_MONT = 384'h3fb05b7a28266895d40d49174aab1cc5bf030606de609f43be80721782118942bfd3ccc974971bd0d8d34124f50ddb2d; - parameter [383 : 0] ONE_q_MONT = 384'h389cb27e0bc8d220a7e5f24db74f58851313e695333ad68d00000000; - - - parameter [383 : 0] UOP_OPR_CONST_ZERO = 8'd00; - parameter [383 : 0] UOP_OPR_CONST_ONE = 8'd01; - parameter [383 : 0] UOP_OPR_CONST_E_a = 8'd02; - parameter [383 : 0] UOP_OPR_CONST_ONE_MONT = 8'd03; - - parameter [383 : 0] UOP_OPR_CONST_GX_MONT = 8'd05; - parameter [383 : 0] UOP_OPR_CONST_GY_MONT = 8'd06; - parameter [383 : 0] UOP_OPR_CONST_GZ_MONT = 8'd07; - - parameter [383 : 0] UOP_OPR_Qx_AFFN = 8'd16; - parameter [383 : 0] UOP_OPR_Qy_AFFN = 8'd17; - - parameter [383 : 0] UOP_OPR_SIGN_R = 8'd18; - parameter [383 : 0] UOP_OPR_SIGN_S = 8'd19; - - parameter [383 : 0] UOP_OPR_PRIVKEY = 8'd20; - parameter [383 : 0] UOP_OPR_HASH_MSG = 8'd21; - parameter [383 : 0] UOP_OPR_SCALAR_G = 8'd22; - - parameter [383 : 0] UOP_OPR_CONST_ONE_q_MONT = 8'd28; // Mont_mult(1, R2) % q - parameter [383 : 0] UOP_OPR_CONST_q_R2 = 8'd29; - - parameter R_WIDTH = 384; - typedef bit [R_WIDTH-1:0] r_t; - typedef bit [383 : 0] operand_t; - typedef struct packed { - operand_t x; - operand_t y; - } affn_point_t; - - typedef struct packed { - operand_t X; - operand_t Y; - operand_t Z; - } proj_point_t; - - typedef struct packed { - operand_t hashed_msg; - operand_t privkey; - affn_point_t pubkey; - operand_t k; - operand_t R; - operand_t S; - } test_vector_t; - - test_vector_t [TEST_VECTOR_NUM-1:0] test_vectors; - //---------------------------------------------------------------- - // Internal constant and parameter definitions. - //---------------------------------------------------------------- - parameter DEBUG = 0; - - parameter CLK_HALF_PERIOD = 1; - parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; - - parameter REG_SIZE = 384; - parameter PRIME = 384'hfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff; - parameter ADD_NUM_ADDS = 1; - parameter ADD_BASE_SZ = 384; - - - localparam NOP_CMD = 3'b000; - localparam KEYGEN_CMD = 3'b001; - localparam SIGN_CMD = 3'b010; - localparam VERIFY_CMD = 3'b100; - //---------------------------------------------------------------- - // Register and Wire declarations. - //---------------------------------------------------------------- - reg [63 : 0] cycle_ctr; - reg [63 : 0] error_ctr; - reg [63 : 0] tc_ctr; - - reg clk_tb; - reg reset_n_tb; - - logic [2 : 0] ecc_cmd_i_tb; - logic [7 : 0] addr_i_tb; - logic wr_input_sel_i_tb; - logic [1 : 0] wr_op_sel_i_tb; - logic [3 : 0] wr_word_sel_i_tb; - logic wr_en_i_tb; - logic rd_reg_i_tb; - logic [1 : 0] rd_op_sel_i_tb; - logic [3 : 0] rd_word_sel_i_tb; - logic [31: 0] data_i_tb; - logic [31: 0] data_o_tb; - logic busy_o_tb; - - logic [383 : 0] read_data; - reg [384 : 0] d_fixed_MSB; - - int test_vector_cnt; - - //---------------------------------------------------------------- - // Device Under Test. - //---------------------------------------------------------------- - ecc_arith_unit #( - .REG_SIZE(REG_SIZE), - .ADD_NUM_ADDS(ADD_NUM_ADDS), - .ADD_BASE_SZ(ADD_BASE_SZ) - ) - dut ( - .clk(clk_tb), - .reset_n(reset_n_tb), - .ecc_cmd_i(ecc_cmd_i_tb), - .addr_i(addr_i_tb), - .wr_input_sel_i(wr_input_sel_i_tb), - .wr_op_sel_i(wr_op_sel_i_tb), - .wr_word_sel_i(wr_word_sel_i_tb), - .wr_en_i(wr_en_i_tb), - .rd_reg_i(rd_reg_i_tb), - .rd_op_sel_i(rd_op_sel_i_tb), - .rd_word_sel_i(rd_word_sel_i_tb), - .data_i(data_i_tb), - .data_o(data_o_tb), - .busy_o(busy_o_tb) - ); - - - //---------------------------------------------------------------- - // clk_gen - // - // Always running clock generator process. - //---------------------------------------------------------------- - always - begin : clk_gen - #CLK_HALF_PERIOD; - clk_tb = !clk_tb; - end // clk_gen - - - //---------------------------------------------------------------- - // sys_monitor() - // - // An always running process that creates a cycle counter and - // conditionally displays information about the DUT. - //---------------------------------------------------------------- - always - begin : sys_monitor - #(CLK_PERIOD); - cycle_ctr = cycle_ctr + 1; - end - - - //---------------------------------------------------------------- - // reset_dut() - // - // Toggle reset to put the DUT into a well known state. - //---------------------------------------------------------------- - task reset_dut; - begin - $display("*** Toggle reset."); - reset_n_tb = 0; - - #(2 * CLK_PERIOD); - reset_n_tb = 1; - $display(""); - end - endtask // reset_dut - - - //---------------------------------------------------------------- - // display_test_results() - // - // Display the accumulated test results. - //---------------------------------------------------------------- - task display_test_results; - begin - if (error_ctr == 0) - begin - $display("*** All %02d test cases completed successfully", tc_ctr); - $display("* TESTCASE PASSED"); - end - else - begin - $display("*** %02d tests completed - %02d test cases did not complete successfully.", - tc_ctr, error_ctr); - $display("* TESTCASE FAILED"); - end - end - endtask // display_test_results - - - - //---------------------------------------------------------------- - // init_sim() - // - // Initialize all counters and testbed functionality as well - // as setting the DUT inputs to defined values. - //---------------------------------------------------------------- - task init_sim; - begin - cycle_ctr = 0; - error_ctr = 0; - tc_ctr = 0; - - clk_tb = 1; - reset_n_tb = 0; - - ecc_cmd_i_tb = NOP_CMD; - addr_i_tb = 0; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = 0; - wr_word_sel_i_tb = 0; - wr_en_i_tb = 0; - rd_reg_i_tb = 0; - rd_op_sel_i_tb = 0; - rd_word_sel_i_tb = 0; - data_i_tb = 0; - end - endtask // init_sim - - - //---------------------------------------------------------------- - // wait_ready() - // - // Initialize all counters and testbed functionality as well - // as setting the DUT inputs to defined values. - //---------------------------------------------------------------- - task wait_ready(); - begin - while (busy_o_tb == 1) - begin - #CLK_PERIOD; - end - end - endtask // init_sim - - - //---------------------------------------------------------------- - // read_word() - // - // Read a data word from the given address in the DUT. - // the word read will be available in the global variable - // read_data. - //---------------------------------------------------------------- - task read_single_word(input [1 : 0] reg_type, input [7 : 0] address, input [7 : 0] word_sel); - begin - ecc_cmd_i_tb = NOP_CMD; - addr_i_tb = address; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = 0; - wr_word_sel_i_tb = 0; - wr_en_i_tb = 0; - rd_reg_i_tb = 1; - rd_op_sel_i_tb = reg_type; - rd_word_sel_i_tb = word_sel; - data_i_tb = 0; - #(CLK_PERIOD); - end - endtask // read_word - - - //---------------------------------------------------------------- - // read_reg() - // - // Read a reg from the given address in the DUT. - // the reg will be available in the global variable - // read_data. - //---------------------------------------------------------------- - task read_reg(input [7 : 0] address); - begin - read_single_word(2'b00, address, 0); - #(2*CLK_PERIOD); - for (int i = 0; i < 12; i++) begin - read_single_word(2'b00, address, i); - read_data = {data_o_tb, read_data[383 : 32]}; - end - end - endtask // read_reg - - - //---------------------------------------------------------------- - // read_scalar() - // - // Read a reg from the given address in the DUT. - // the reg will be available in the global variable - // read_data. - //---------------------------------------------------------------- - task read_scalar(); - begin - for (int i = 0; i < 12; i++) begin - read_single_word(2'b01, 8'h00, i); - read_data = {data_o_tb, read_data[383 : 32]}; - end - end - endtask // read_scalar - - - //---------------------------------------------------------------- - // write_single_word() - // - // Write the given word to the DUT using the DUT interface. - //---------------------------------------------------------------- - task write_single_word(input [1 : 0] reg_type, input [7 : 0] address, input [7 : 0] word_sel, input [31 : 0] word); - begin - ecc_cmd_i_tb = NOP_CMD; - addr_i_tb = address; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = reg_type; - wr_word_sel_i_tb = word_sel; - wr_en_i_tb = 1; - rd_reg_i_tb = 0; - rd_op_sel_i_tb = 0; - rd_word_sel_i_tb = 0; - data_i_tb = word; - #(CLK_PERIOD); - end - endtask // write_single_word - - - //---------------------------------------------------------------- - // write_reg() - // - // Write the given word to the DUT using the DUT interface. - //---------------------------------------------------------------- - task write_reg(input [7 : 0] address, input [383 : 0] word); - begin - for (int i = 0; i < 12; i++) begin - write_single_word(2'b00, address, i, word[32*i +: 32]); - end - #(CLK_PERIOD); - ecc_cmd_i_tb = NOP_CMD; - addr_i_tb = 0; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = 0; - wr_word_sel_i_tb = 0; - wr_en_i_tb = 0; - rd_reg_i_tb = 0; - rd_op_sel_i_tb = 0; - rd_word_sel_i_tb = 0; - data_i_tb = 0; - #(CLK_PERIOD); - end - endtask // write_reg - - - //---------------------------------------------------------------- - // write_scalar() - // - // Write the given word to the DUT using the DUT interface. - //---------------------------------------------------------------- - task write_scalar(input [384 : 0] word); - begin - for (int i = 0; i < 13; i++) begin - write_single_word(2'b01, 8'h00 , i, word[32*i +: 32]); - end - #(CLK_PERIOD); - ecc_cmd_i_tb = NOP_CMD; - addr_i_tb = 0; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = 0; - wr_word_sel_i_tb = 0; - wr_en_i_tb = 0; - rd_reg_i_tb = 0; - rd_op_sel_i_tb = 0; - rd_word_sel_i_tb = 0; - data_i_tb = 0; - #(CLK_PERIOD); - end - endtask // write_scalar - - - //---------------------------------------------------------------- - // fix_MSB() - // - // Set MSB of scalar to 1. - //---------------------------------------------------------------- - task fix_MSB(input [383 : 0] d); - reg [385 : 0] d_q; - reg [385 : 0] d_2q; - begin - d_q = d + group_order; - d_2q = d_q + group_order; - if ((d_q >> 384) == 1) - d_fixed_MSB = d_q[384 : 0]; - else - d_fixed_MSB = d_2q[384 : 0]; - end - endtask // fix_MSB - - //---------------------------------------------------------------- - // trig_ECPM() - // - // Write the given word to the DUT using the DUT interface. - //---------------------------------------------------------------- - task trig_ECPM(input [2 : 0] cmd); - begin - ecc_cmd_i_tb = cmd; - addr_i_tb = 0; - wr_input_sel_i_tb = 0; - wr_op_sel_i_tb = 0; - wr_word_sel_i_tb = 0; - wr_en_i_tb = 0; - rd_reg_i_tb = 0; - rd_op_sel_i_tb = 0; - rd_word_sel_i_tb = 0; - data_i_tb = 0; - #(CLK_PERIOD); - end - endtask // trig_ECPM - - - //---------------------------------------------------------------- - // ecc_keygen_test() - // - // Perform a single point multiplication block test. - //---------------------------------------------------------------- - task ecc_keygen_test(input [7 : 0] tc_number, - input test_vector_t test_vector); - reg [31 : 0] start_time; - reg [31 : 0] end_time; - affn_point_t pubkey; - begin - $display("*** TC %0d keygen test started.", tc_number); - tc_ctr = tc_ctr + 1; - - start_time = cycle_ctr; - // writing constant values - write_reg(UOP_OPR_CONST_ZERO, 384'h0); - write_reg(UOP_OPR_CONST_ONE, 384'h1); - write_reg(UOP_OPR_CONST_E_a, E_a_MONT); - write_reg(UOP_OPR_CONST_ONE_MONT, ONE_p_MONT); - write_reg(UOP_OPR_CONST_GX_MONT, G_X_MONT); - write_reg(UOP_OPR_CONST_GY_MONT, G_Y_MONT); - write_reg(UOP_OPR_CONST_GZ_MONT, G_Z_MONT); - - fix_MSB(test_vector.privkey); - write_scalar(d_fixed_MSB); - - trig_ECPM(KEYGEN_CMD); - - wait_ready(); - - read_reg(UOP_OPR_Qx_AFFN); - pubkey.x = read_data; - - read_reg(UOP_OPR_Qy_AFFN); - pubkey.y = read_data; - - end_time = cycle_ctr - start_time; - $display("*** keygen test processing time = %01d cycles.", end_time); - $display("privkey : 0x%96x", test_vector.privkey); - - if (pubkey == test_vector.pubkey) - begin - $display("*** TC %0d keygen successful.", tc_number); - $display(""); - end - else - begin - $display("*** ERROR: TC %0d keygen NOT successful.", tc_number); - $display("Expected_x: 0x%96x", test_vector.pubkey.x); - $display("Got: 0x%96x", pubkey.x); - $display("Expected_y: 0x%96x", test_vector.pubkey.y); - $display("Got: 0x%96x", pubkey.y); - $display(""); - - error_ctr = error_ctr + 1; - end - end - endtask // ecc_keygen_test - - -//---------------------------------------------------------------- - // ecc_signing_test() - // - // Perform a single signing operation test. - //---------------------------------------------------------------- - task ecc_signing_test(input [7 : 0] tc_number, - input test_vector_t test_vector); - reg [31 : 0] start_time; - reg [31 : 0] end_time; - reg [383 : 0] R; - reg [383 : 0] S; - - begin - $display("*** TC %0d signing test started.", tc_number); - tc_ctr = tc_ctr + 1; - - start_time = cycle_ctr; - write_reg(UOP_OPR_CONST_ZERO, 384'h0); - write_reg(UOP_OPR_CONST_ONE, 384'h1); - write_reg(UOP_OPR_CONST_E_a, E_a_MONT); - write_reg(UOP_OPR_CONST_ONE_MONT, ONE_p_MONT); - write_reg(UOP_OPR_CONST_ONE_q_MONT, ONE_q_MONT); - write_reg(UOP_OPR_CONST_q_R2, R2_q_MONT); - - write_reg(UOP_OPR_CONST_GX_MONT, G_X_MONT); - write_reg(UOP_OPR_CONST_GY_MONT, G_Y_MONT); - write_reg(UOP_OPR_CONST_GZ_MONT, G_Z_MONT); - - write_reg(UOP_OPR_HASH_MSG, test_vector.hashed_msg); - write_reg(UOP_OPR_PRIVKEY, test_vector.privkey); - write_reg(UOP_OPR_SCALAR_G, test_vector.k); - - fix_MSB(test_vector.k); - write_scalar(d_fixed_MSB); - - trig_ECPM(SIGN_CMD); - - wait_ready(); - - read_reg(UOP_OPR_SIGN_R); - R = read_data; - - read_reg(UOP_OPR_SIGN_S); - S = read_data; - - end_time = cycle_ctr - start_time; - $display("*** signing test processing time = %01d cycles.", end_time); - $display("privkey : 0x%96x", test_vector.privkey); - - if (R == test_vector.R & S == test_vector.S) - begin - $display("*** TC %0d signing successful.", tc_number); - $display(""); - end - else - begin - $display("*** ERROR: TC %0d signing NOT successful.", tc_number); - $display("Expected_R: 0x%96x", test_vector.R); - $display("Got: 0x%96x", R); - $display("Expected_S: 0x%96x", test_vector.S); - $display("Got: 0x%96x", S); - $display(""); - - error_ctr = error_ctr + 1; - end - end - endtask // ecc_signing_test - - - - //---------------------------------------------------------------- - // ecc_test() - // - //---------------------------------------------------------------- - task ecc_test(); - begin - $display("ECC KEYGEN TEST"); - $display("---------------------"); - - for (int i = 0; i < test_vector_cnt; i++) begin: test_vector_loop - ecc_keygen_test(i, test_vectors[i]); - ecc_signing_test(i, test_vectors[i]); - end - - $display("ECC SIGNING TEST"); - $display("---------------------"); - - end - endtask // ecc_test - - - task read_test_vectors(input string fname); - integer values_per_test_vector; - integer line_cnt; - integer fin; - integer rv; - r_t val; // must be the largest width of any possible value - test_vector_t test_vector; - - // ATTN: Must match the number of fields generated by gen_mm_test_vectors.py script - values_per_test_vector = 8; - line_cnt = 0; - test_vector_cnt = 0; - - fin = $fopen(fname, "r"); - if (fin == 0) - $error("Can't open file %s", fname); - while (!$feof(fin)) begin - rv = $fscanf(fin, "%h\n", val); - if (rv != 1) begin - $error("Failed to read a matching string"); - $fclose(fin); - $finish; - end - // ATTN: the number of cases must be equal to 'values_per_test_vector'. - // ATTN: the order of values must be the same as in gen_mm_test_vectors.py script. - case (line_cnt % values_per_test_vector) - 0: test_vector.hashed_msg = val; - 1: test_vector.privkey = val; - 2: test_vector.pubkey.x = val; - 3: test_vector.pubkey.y = val; - 4: test_vector.k = val; - 5: test_vector.R = val; - 6: begin - test_vector.S = val; - test_vectors[test_vector_cnt] = test_vector; - end - 7 : test_vector_cnt++; - endcase - - line_cnt++; - end - $fclose(fin); - - $display("Read %0d test vectors from %s", test_vector_cnt, fname); - endtask - - //---------------------------------------------------------------- - // main - // - // The main test functionality. - //---------------------------------------------------------------- - initial - begin : main - - string fname; - - $display(" -= Testbench for ecc started =-"); - $display(" =============================="); - $display(""); - - fname = "/home/mojtabab/workspace_aha_poc/ws1/Caliptra/src/ecc/tb/test_vectors/ecc_test_vectors.hex"; - read_test_vectors(fname); - - init_sim(); - reset_dut(); - - ecc_test(); - - display_test_results(); - - $display(""); - $display("*** ecc simulation done. ***"); - $finish; - end // main - -endmodule // ecc_arith_unit_tb diff --git a/src/ecc/tb/ecc_top_tb.sv b/src/ecc/tb/ecc_top_tb.sv index fef121d63..54ba90fdf 100644 --- a/src/ecc/tb/ecc_top_tb.sv +++ b/src/ecc/tb/ecc_top_tb.sv @@ -957,6 +957,69 @@ module ecc_top_tb end endtask // zeroize_test + + //---------------------------------------------------------------- + // ecc_fault_test() + // + //---------------------------------------------------------------- + task ecc_fault_test(); + operand_t privKey_faulty; + + begin + privKey_faulty = '0; + wait_ready(); + + $display("*** fault test started."); + tc_ctr = tc_ctr + 1; + + //enable the interrupt + write_single_word(`ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R, `ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK); + write_single_word(`ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R, `ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_MASK); + + write_block(`ECC_REG_ECC_PRIVKEY_IN_0, privKey_faulty); + trig_ECC(ECC_CMD_SIGNING); + wait_ready(); + + #(2 * CLK_PERIOD); //there are 2 cycles latency to set error_intr + + if (error_intr_tb) + begin + $display("*** fault test successful."); + $display(""); + end + else + begin + $display("*** ERROR: fault test NOT successful."); + $display(""); + + error_ctr = error_ctr + 1; + end + + trig_ECC(ECC_CMD_SIGNING); + + wait_ready(); + + trig_ECC(`ECC_REG_ECC_CTRL_ZEROIZE_MASK); //zeroize + + #(2 * CLK_PERIOD); + + if (dut.ecc_dsa_ctrl_i.error_flag_reg == 0) + begin + $display("*** fault test successful."); + $display(""); + end + else + begin + $display("*** ERROR: fault test NOT successful."); + $display(""); + + error_ctr = error_ctr + 1; + end + + reset_dut(); + end + endtask // ecc_fault_test + //---------------------------------------------------------------- // ecc_openssl_keygen_test() // @@ -1036,6 +1099,7 @@ module ecc_top_tb continuous_cmd_test(test_vectors[0]); zeroize_test(test_vectors[1]); + ecc_fault_test(); end endtask // ecc_test diff --git a/src/hmac/rtl/hmac_core.v b/src/hmac/rtl/hmac_core.v index 2bca8ab67..b4780fc0f 100644 --- a/src/hmac/rtl/hmac_core.v +++ b/src/hmac/rtl/hmac_core.v @@ -22,9 +22,6 @@ //====================================================================== module hmac_core -#( - parameter [383 : 0] LFSR_INIT_SEED = 384'hc48555929cd58779f4819c1e6570c2ef20bccd503284e2d366f3273a66e9719b07ac999c80740d6277af88ceb4c3029c // a random value -) ( // Clock and reset. input wire clk, @@ -154,8 +151,7 @@ module hmac_core generate for (i=0; i < 12; i++) begin : gen_lfsr hmac_lfsr #( - .REG_SIZE(32), - .INIT_SEED(LFSR_INIT_SEED[i*32 +: 32]) + .REG_SIZE(32) ) lfsr_inst_i ( diff --git a/src/hmac/rtl/hmac_lfsr.sv b/src/hmac/rtl/hmac_lfsr.sv index 96fe14579..3c171d0d7 100644 --- a/src/hmac/rtl/hmac_lfsr.sv +++ b/src/hmac/rtl/hmac_lfsr.sv @@ -22,8 +22,7 @@ module hmac_lfsr #( - parameter REG_SIZE = 32, - parameter [REG_SIZE-1 : 0] INIT_SEED = 32'h3CAB_FFB0 // a random value + parameter REG_SIZE = 32 ) ( // Clock and reset. @@ -46,6 +45,9 @@ module hmac_lfsr reg [REG_SIZE-1 : 0] rnd_next; logic feedback; + logic lockup; + logic [REG_SIZE-1 : 0] counter_reg; + logic [REG_SIZE-1 : 0] counter_next; //---------------------------------------------------------------- // reg_update @@ -60,15 +62,32 @@ module hmac_lfsr always_ff @ (posedge clk or negedge reset_n) begin if (!reset_n) - rnd_reg <= INIT_SEED; + rnd_reg <= '0; else if (zeroize) - rnd_reg <= INIT_SEED; + rnd_reg <= counter_reg; else if (en) rnd_reg <= seed; + else if (lockup) + rnd_reg <= counter_reg; else rnd_reg <= rnd_next; end + always_comb counter_next = counter_reg + 1; + + always_ff @(posedge clk or negedge reset_n) + begin : counter_reg_update + if (!reset_n) + counter_reg <= '0; + else if (&counter_next) + counter_reg <= '0; + else + counter_reg <= counter_next; + end // counter_reg_update + + // lockup condition is all-one + assign lockup = &rnd_reg; + assign rnd = rnd_reg; endmodule \ No newline at end of file diff --git a/src/hmac_drbg/rtl/hmac_drbg.sv b/src/hmac_drbg/rtl/hmac_drbg.sv index 4b3dee23b..fadf2474b 100644 --- a/src/hmac_drbg/rtl/hmac_drbg.sv +++ b/src/hmac_drbg/rtl/hmac_drbg.sv @@ -33,8 +33,7 @@ module hmac_drbg #( parameter REG_SIZE = 384, - parameter [REG_SIZE-1 : 0] HMAC_DRBG_PRIME = 384'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973, - parameter [REG_SIZE-1 : 0] LFSR_INIT_SEED = 384'hc48555929cd58779f4819c1e6570c2ef20bccd503284e2d366f3273a66e9719b07ac999c80740d6277af88ceb4c3029c // a random value + parameter [REG_SIZE-1 : 0] HMAC_DRBG_PRIME = 384'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973 ) ( // Clock and reset. @@ -121,9 +120,7 @@ module hmac_drbg //---------------------------------------------------------------- // HMAC module instantiation. //---------------------------------------------------------------- - hmac_core #( - .LFSR_INIT_SEED(LFSR_INIT_SEED) - ) + hmac_core HMAC_K ( .clk(clk), @@ -167,42 +164,40 @@ module hmac_drbg HMAC_tag_valid_last <= HMAC_tag_valid; end - always_ff @ (posedge clk or negedge reset_n) - begin - if (!reset_n) - ready_reg <= '0; - else if (zeroize) - ready_reg <= '0; - else - ready_reg <= (drbg_st_reg == IDLE_ST); - end - always_ff @ (posedge clk or negedge reset_n) begin : valid_drbg_regs_updates if (!reset_n) begin - valid_reg <= 0; - drbg_reg <= '0; + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; end else if (zeroize) begin - valid_reg <= 0; - drbg_reg <= '0; + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; end else begin unique case (drbg_st_reg) IDLE_ST: begin - if (init_cmd | next_cmd) - valid_reg <= 0; + if (init_cmd | next_cmd) begin + ready_reg <= 1'b0; + valid_reg <= 1'b0; + end + else + ready_reg <= 1'b1; end DONE_ST: begin drbg_reg <= HMAC_tag; valid_reg <= HMAC_tag_valid; + ready_reg <= HMAC_ready; end default: begin - valid_reg <= 0; - drbg_reg <= '0; + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; end endcase end diff --git a/src/sha512_masked/rtl/sha512_masked_core.sv b/src/sha512_masked/rtl/sha512_masked_core.sv index 9ba0f1471..81f3fda16 100644 --- a/src/sha512_masked/rtl/sha512_masked_core.sv +++ b/src/sha512_masked/rtl/sha512_masked_core.sv @@ -48,7 +48,7 @@ // from Secworks. // // For providing the required random values to mask intermediate values, -// we use a lightweight 74-bit LFSR. Based on +// we use a lightweight LFSR. Based on // "Spin Me Right Round Rotational Symmetry for FPGA-specific AES" by // Wegener et. al., LFSR is sufficient for masking statistical randomness. //======================================================================