diff --git a/src/ecc/coverage/ecc_top_cov_if.sv b/src/ecc/coverage/ecc_top_cov_if.sv index ec86e056b..97f1a8cac 100644 --- a/src/ecc/coverage/ecc_top_cov_if.sv +++ b/src/ecc/coverage/ecc_top_cov_if.sv @@ -39,6 +39,8 @@ interface ecc_top_cov_if logic pubkeyx_input_outofrange; logic pubkeyy_input_outofrange; logic pubkey_input_invalid; + logic pcr_sign_input_invalid; + logic keygen_process; logic signing_process; logic verifying_process; @@ -96,6 +98,8 @@ interface ecc_top_cov_if assign pubkeyx_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyx_input_outofrange; assign pubkeyy_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyy_input_outofrange; assign pubkey_input_invalid = ecc_top.ecc_dsa_ctrl_i.pubkey_input_invalid; + assign pcr_sign_input_invalid = ecc_top.ecc_dsa_ctrl_i.pcr_sign_input_invalid; + assign keygen_process = ecc_top.ecc_dsa_ctrl_i.keygen_process; assign signing_process = ecc_top.ecc_dsa_ctrl_i.signing_process; assign verifying_process = ecc_top.ecc_dsa_ctrl_i.verifying_process; @@ -119,6 +123,7 @@ interface ecc_top_cov_if pubkeyx_input_outofrange_cp: coverpoint pubkeyx_input_outofrange; pubkeyy_input_outofrange_cp: coverpoint pubkeyy_input_outofrange; pubkey_input_invalid_cp: coverpoint pubkey_input_invalid; + pcr_sign_input_invalid_cp: coverpoint pcr_sign_input_invalid; cmd_ready_cp: cross ecc_sw_cmd, ready; cmd_kv_cp: cross ecc_cmd, dest_keyvault; @@ -128,6 +133,8 @@ interface ecc_top_cov_if zeroize_cmd_cp: cross zeroize, ecc_cmd; zeroize_error_cp: cross zeroize, error_flag; zeroize_ready_cp: cross ready, zeroize; + pcr_sign_input_invalid_cmd_cp: cross error_flag, ecc_cmd; + error_keygen_cp: cross error_flag, keygen_process; error_signing_cp: cross error_flag, signing_process; error_verifying_cp: cross error_flag, verifying_process; diff --git a/src/ecc/rtl/ecc_add_sub_mod_alter.sv b/src/ecc/rtl/ecc_add_sub_mod_alter.sv index d9d6d208c..2bf3eb332 100644 --- a/src/ecc/rtl/ecc_add_sub_mod_alter.sv +++ b/src/ecc/rtl/ecc_add_sub_mod_alter.sv @@ -51,6 +51,7 @@ module ecc_add_sub_mod_alter #( logic carry0_reg; logic carry1; + logic [1 : 0] push_result_reg; ecc_adder #( .RADIX(REG_SIZE) @@ -84,22 +85,31 @@ module ecc_add_sub_mod_alter #( if(!reset_n) begin r0_reg <= '0; carry0_reg <= '0; - ready_o <= 1'b0; end else if (zeroize) begin r0_reg <= '0; carry0_reg <= '0; - ready_o <= 1'b0; end else if (add_en_i) begin r0_reg <= r0; carry0_reg <= carry0; - ready_o <= 1'b0; end - else - ready_o <= 1'b1; end + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= (push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0 : (carry0_reg) ? r0 : r1; endmodule diff --git a/src/ecc/rtl/ecc_dsa_ctrl.sv b/src/ecc/rtl/ecc_dsa_ctrl.sv index 389ee7542..48eb05af2 100644 --- a/src/ecc/rtl/ecc_dsa_ctrl.sv +++ b/src/ecc/rtl/ecc_dsa_ctrl.sv @@ -201,6 +201,7 @@ module ecc_dsa_ctrl logic pubkeyx_input_outofrange; logic pubkeyy_input_outofrange; logic pubkey_input_invalid; + logic pcr_sign_input_invalid; logic error_flag; logic error_flag_reg; @@ -649,7 +650,9 @@ module ecc_dsa_ctrl assign pubkeyy_input_outofrange = verifying_process & (pubkeyy_reg >= PRIME); assign pubkey_input_invalid = verifying_process & (pk_chk_reg != 0); - assign error_flag = privkey_input_outofrange | r_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid; + assign pcr_sign_input_invalid = ((cmd_reg == KEYGEN) | (cmd_reg == VERIFY)) & pcr_sign_mode; + + assign error_flag = privkey_input_outofrange | r_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid | pcr_sign_input_invalid; //---------------------------------------------------------------- // ECDSA_FSM_flow diff --git a/src/ecc/rtl/ecc_fau.sv b/src/ecc/rtl/ecc_fau.sv index b729cec65..56b82a6ec 100644 --- a/src/ecc/rtl/ecc_fau.sv +++ b/src/ecc/rtl/ecc_fau.sv @@ -51,7 +51,9 @@ module ecc_fau #( reg mult_start; reg mult_start_dly; wire mult_start_edge; - reg add_en; + logic add_start; + logic add_start_dly; + logic add_start_edge; reg sub; logic add_ready_o; @@ -97,7 +99,7 @@ module ecc_fau #( .reset_n(reset_n), .zeroize(zeroize), - .add_en_i(add_en), + .add_en_i(add_start_edge), .sub_i(sub), .opa_i(opa_i), .opb_i(opb_i), @@ -114,34 +116,41 @@ module ecc_fau #( begin if (!reset_n) begin mult_start <= '0; - add_en <= '0; + add_start <= '0; sub <= '0; end else if (zeroize) begin mult_start <= '0; - add_en <= '0; + add_start <= '0; sub <= '0; end else begin mult_start <= mult_en_i; - add_en <= add_en_i; + add_start <= add_en_i; sub <= sub_i; end end always_ff @(posedge clk or negedge reset_n) begin - if (!reset_n) + if (!reset_n) begin mult_start_dly <= '0; - else if (zeroize) + add_start_dly <= '0; + end + else if (zeroize) begin mult_start_dly <= '0; - else + add_start_dly <= '0; + end + else begin mult_start_dly <= mult_start; + add_start_dly <= add_start; + end end assign ready_garbage_bit = add_ready_o & mult_ready_o; // generate a pulse enable for mult assign mult_start_edge = mult_start & ~mult_start_dly; + assign add_start_edge = add_start & ~add_start_dly; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. diff --git a/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c b/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c index e92734cdd..d6d358ca7 100644 --- a/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c +++ b/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c @@ -219,6 +219,7 @@ void main() { uint8_t offset; volatile uint32_t * reg_ptr; + uint8_t privkey_inject_cmd; if(rst_count == 0) { @@ -461,7 +462,7 @@ void main() { //inject seed to kv key reg (in RTL) printf("Inject PRIVKEY into KV slot 7\n"); - uint8_t privkey_inject_cmd = 0x88 + 0x7; + privkey_inject_cmd = 0x88 + 0x7; printf("%c", privkey_inject_cmd); printf("Inject MSG into SHA512 digest\n"); @@ -482,8 +483,87 @@ void main() { } ecc_zeroize(); + //Issue warm reset + rst_count++; + printf("%c",0xf6); } + else if(rst_count == 7) { + // wait for ECC to be ready + while((lsu_read_32(CLP_ECC_REG_ECC_STATUS) & ECC_REG_ECC_STATUS_READY_MASK) == 0); + + printf("\n TEST PCR WITH INVALID INPUT COMMAND\n"); + + // Program ECC IV + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_IV_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_IV_11) { + *reg_ptr++ = ecc_iv[offset++]; + } + + //inject seed to kv key reg (in RTL) + printf("Inject PRIVKEY into KV slot 7\n"); + privkey_inject_cmd = 0x88 + 0x7; + printf("%c", privkey_inject_cmd); + + printf("Inject MSG into SHA512 digest\n"); + printf("%c", 0x90); + + // Enable ECC PCR KEYGEN core + printf("\nECC PCR KEYGEN\n"); + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_KEYGEN | + ((1 << ECC_REG_ECC_CTRL_PCR_SIGN_LOW) & ECC_REG_ECC_CTRL_PCR_SIGN_MASK)); + + + // wait for ECC KEYGEN process to be done + wait_for_ecc_intr(); + if ((cptra_intr_rcv.ecc_error == 0)){ + printf("\nECC PCR invalid command error is not detected.\n"); + printf("%c", 0x1); + while(1); + } + + ecc_zeroize(); + //Issue warm reset + rst_count++; + printf("%c",0xf6); + } + else if(rst_count == 8) { + // wait for ECC to be ready + while((lsu_read_32(CLP_ECC_REG_ECC_STATUS) & ECC_REG_ECC_STATUS_READY_MASK) == 0); + + printf("\n TEST PCR WITH INVALID INPUT COMMAND\n"); + + // Program ECC IV + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_IV_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_IV_11) { + *reg_ptr++ = ecc_iv[offset++]; + } + + //inject seed to kv key reg (in RTL) + printf("Inject PRIVKEY into KV slot 7\n"); + privkey_inject_cmd = 0x88 + 0x7; + printf("%c", privkey_inject_cmd); + + printf("Inject MSG into SHA512 digest\n"); + printf("%c", 0x90); + + // Enable ECC PCR VERIFYING core + printf("\nECC PCR VERIFYING\n"); + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_VERIFYING | + ((1 << ECC_REG_ECC_CTRL_PCR_SIGN_LOW) & ECC_REG_ECC_CTRL_PCR_SIGN_MASK)); + + // wait for ECC VERIFYING process to be done + wait_for_ecc_intr(); + if ((cptra_intr_rcv.ecc_error == 0)){ + printf("\nECC PCR invalid command error is not detected.\n"); + printf("%c", 0x1); + while(1); + } + + ecc_zeroize(); + } printf("%c",0xff); //End the test