diff --git a/docs/CaliptraHardwareSpecification.md b/docs/CaliptraHardwareSpecification.md index a69a2b219..e6354ba93 100644 --- a/docs/CaliptraHardwareSpecification.md +++ b/docs/CaliptraHardwareSpecification.md @@ -160,8 +160,8 @@ Vector 0 is reserved by the RISC-V processor and may not be used, so vector assi | ECC (Notifications) | 4 | 7 | | HMAC (Errors) | 5 | 8 | | HMAC (Notifications) | 6 | 7 | -| KeyVault (Errors) | 7 | 8 | -| KeyVault (Notifications) | 8 | 7 | +| Key Vault (Errors) | 7 | 8 | +| Key Vault (Notifications) | 8 | 7 | | SHA512 (Errors) | 9 | 8 | | SHA512 (Notifications) | 10 | 7 | | SHA256 (Errors) | 11 | 8 | @@ -430,7 +430,7 @@ Caliptra provides a clock gating feature that turns off clocks when the microcon | :------------------- | :---------------- | :------------------------ | | CPTRA_CLK_GATING_EN | 0x300300bc | Register bit to enable or disable the clock gating feature. | -When enabled, halting the microcontroller turns off clocks to all of the cryptographic subsystem, the vaults (keyvault, PCR vault, and data vault), mailbox SRAM, SoC interface, and peripherals subsystem. The Watchdog timer and SoC registers run on the gated RDC clock. The RV core implements its own clock gating mechanism. Halting the core automatically turns off its clock. +When enabled, halting the microcontroller turns off clocks to all of the cryptographic subsystem, the vaults (key vault, PCR vault, and data vault), mailbox SRAM, SoC interface, and peripherals subsystem. The Watchdog timer and SoC registers run on the gated RDC clock. The RV core implements its own clock gating mechanism. Halting the core automatically turns off its clock. There are a total of 4 clocks in Caliptra: ungated clock, gated clock, gated RDC clock, and gated SoC IFC clock. The following table shows the different modules and their designated clocks. @@ -1385,10 +1385,10 @@ FW must set a last cycle flag before running the last iteration of the SHA engin Key Vault (KV) is a register file that stores the keys to be used by the microcontroller, but this register file is not observed by the microcontroller. Each cryptographic function has a control register and functional block designed to read from and write to the KV.  -| KV register | Description | -| :------------------------------- | :------------------------------------------------------- | -| Key Control\[7:0\] | 8 Control registers, 32 bits each | -| Key Entry\[7:0\]\[15:0\]\[31:0\] | 8 Key entries, 512 bits each
No read or write access | +| KV register | Description | +| :-------------------------------- | :-------------------------------------------------------- | +| Key Control\[31:0\] | 32 Control registers, 32 bits each | +| Key Entry\[31:0\]\[11:0\]\[31:0\] | 32 Key entries, 384 bits each
No read or write access | ### Key vault functional block @@ -1414,14 +1414,18 @@ The destination valid field is programmed by FW in the cryptographic block gener A generic block is instantiated in each cryptographic block to enable access to KV.  -Each input to a cryptographic engine can have a key vault read block associated with it. The KV read block takes in a keyvault read control register that drives an FSM to copy an entry from the keyvault into the appropriate input register of the cryptographic engine. +Each input to a cryptographic engine can have a key vault read block associated with it. The KV read block takes in a key vault read control register that drives an FSM to copy an entry from the key vault into the appropriate input register of the cryptographic engine. -Each output generated by a cryptographic engine can have its result copied to a slot in the keyvault. The KV write block takes in a keyvault write control register. This register drives an FSM to copy the result from the cryptographic engine into the appropriate keyvault entry. It also programs a control field for that entry to indicate where that entry can be used. +Each output generated by a cryptographic engine can have its result copied to a slot in the key vault. The KV write block takes in a key vault write control register. This register drives an FSM to copy the result from the cryptographic engine into the appropriate key vault entry. It also programs a control field for that entry to indicate where that entry can be used. After programming the key vault read control, FW needs to query the associated key vault read status to confirm that the requested key was copied successfully. After valid is set and the error field reports success, the key is ready to be used. Similarly, after programming the key vault write control and initiating the cryptographic function that generates the key to be written, FW needs to query the associated key vault write status to confirm that the requested key was generated and written successfully. +When a key is read from the key vault, the API register is locked and any result generated from the cryptographic block is not readable by firmware. The digest can only be sent to the key vault by appropriately programming the key vault write controls. After the cryptographic block completes its operation, the lock is cleared and the key is cleared from the API registers. + +If multiple iterations of the cryptographic function are required, the key vault read and write controls must be programmed for each iteration. This ensures that the lock is set and the digest is not readable. + The following tables describe read, write, and status values for key vault blocks. | KV Read Ctrl Reg | Description | @@ -1476,11 +1480,11 @@ A de-obfuscation engine (DOE) is used in conjunction with AES cryptography to de The following tables describe DOE register and control fields. -| DOE Register | Address | Description  | -| :----------- | :--------- | :----------------------------------------------------------------------------------------------------------------------------- | -| IV | 0x10000000 | 128 bit IV for DOE flow. Stored in big-endian representation. | -| CTRL | 0x10000010 | Controls for DOE flows. | -| STATUS | 0x10000014 | Valid indicates the command is done and results are stored in keyvault. Ready indicates the core is ready for another command. | +| DOE Register | Address | Description  | +| :----------- | :--------- | :------------------------------------------------------------------------------------------------------------------------------ | +| IV | 0x10000000 | 128 bit IV for DOE flow. Stored in big-endian representation. | +| CTRL | 0x10000010 | Controls for DOE flows. | +| STATUS | 0x10000014 | Valid indicates the command is done and results are stored in key vault. Ready indicates the core is ready for another command. | | DOE Ctrl Fields  | Reset  | Description  | | :--------------- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------- | @@ -1510,9 +1514,10 @@ Data vault is a set of generic scratch pad registers with specific lock function The following table describes cryptographic errors. -| Errors | Error type | Description | -| :--------- | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ECC_R_ZERO | HW_ERROR_NON_FATAL | Indicates a non-fatal error in ECC signing if the computed signature R is equal to 0. FW should change the message or privkey to perform a valid signing. | +| Errors | Error type | Description | +| :----------- | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ECC_R_ZERO | HW_ERROR_NON_FATAL | Indicates a non-fatal error in ECC signing if the computed signature R is equal to 0. FW should change the message or privkey to perform a valid signing. | +| CRYPTO_ERROR | HW_ERROR_FATAL | Indicates a fatal error due to multiple cryptographic operations occurring simultaneously. FW must only operate one cryptographic engine at a time. | # Terminology diff --git a/src/doe/rtl/doe_cbc.sv b/src/doe/rtl/doe_cbc.sv index 70dec5840..dfab5a36b 100644 --- a/src/doe/rtl/doe_cbc.sv +++ b/src/doe/rtl/doe_cbc.sv @@ -66,6 +66,8 @@ module doe_cbc output logic clear_obf_secrets, + output logic busy_o, + //interface with kv output kv_write_t kv_write, input logic debugUnlock_or_scan_mode_switch @@ -287,6 +289,8 @@ doe_reg i_doe_reg ( assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; +always_comb busy_o = flow_in_progress | ~core_ready; + endmodule // doe //====================================================================== diff --git a/src/doe/rtl/doe_ctrl.sv b/src/doe/rtl/doe_ctrl.sv index 03fb1306f..5ecad1a92 100644 --- a/src/doe/rtl/doe_ctrl.sv +++ b/src/doe/rtl/doe_ctrl.sv @@ -59,6 +59,8 @@ module doe_ctrl output logic clear_obf_secrets, + output logic busy_o, + // Interrupt output logic error_intr, output logic notif_intr, @@ -91,6 +93,7 @@ module doe_ctrl .read_data(doe_read_data[31:0]), .error_intr(error_intr), .notif_intr(notif_intr), + .busy_o(busy_o), .clear_obf_secrets(clear_obf_secrets), .kv_write(kv_write), .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) diff --git a/src/doe/tb/doe_cbc_tb.sv b/src/doe/tb/doe_cbc_tb.sv index 6e9b5b7d0..6aee2b397 100644 --- a/src/doe/tb/doe_cbc_tb.sv +++ b/src/doe/tb/doe_cbc_tb.sv @@ -148,7 +148,7 @@ module doe_cbc_tb(); .obf_uds_seed(obf_uds_seed), .kv_write(), - + .busy_o(), .error_intr(), .notif_intr() ); diff --git a/src/ecc/rtl/ecc_dsa_ctrl.sv b/src/ecc/rtl/ecc_dsa_ctrl.sv index c4a9c5b1d..6bbadcb1b 100644 --- a/src/ecc/rtl/ecc_dsa_ctrl.sv +++ b/src/ecc/rtl/ecc_dsa_ctrl.sv @@ -79,6 +79,8 @@ module ecc_dsa_ctrl //PCR Signing input pcr_signing_t pcr_signing_data, + output logic busy_o, + // Interrupts (from ecc_reg) output logic error_intr, output logic notif_intr, @@ -178,9 +180,12 @@ module ecc_dsa_ctrl logic kv_privkey_ready, kv_privkey_done; logic kv_seed_ready, kv_seed_done ; logic kv_write_ready, kv_write_done; - //KV Read Data Present - logic kv_read_data_present; - logic kv_read_data_present_set, kv_read_data_present_reset; + //KV Seed Data Present + logic kv_seed_data_present; + logic kv_seed_data_present_set, kv_seed_data_present_reset; + //KV Key Data Present + logic kv_key_data_present; + logic kv_key_data_present_set, kv_key_data_present_reset; kv_read_ctrl_reg_t kv_privkey_read_ctrl_reg; kv_read_ctrl_reg_t kv_seed_read_ctrl_reg; @@ -309,7 +314,8 @@ module ecc_dsa_ctrl // read the registers written by sw always_comb begin - cmd_reg = hwif_out.ECC_CTRL.CTRL.value; + //Mask the command if KV clients are not idle + cmd_reg = hwif_out.ECC_CTRL.CTRL.value & {2{kv_seed_ready}} & {2{kv_privkey_ready}}; zeroize_reg = hwif_out.ECC_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; sca_point_rnd_en = 1'b1; @@ -324,23 +330,27 @@ module ecc_dsa_ctrl privkey_we_reg <= '0; privkey_we_reg_ff <= '0; kv_reg <= '0; - kv_read_data_present <= '0; + kv_seed_data_present <= '0; + kv_key_data_present <= '0; end else if (zeroize_reg) begin privkey_we_reg <= '0; privkey_we_reg_ff <= '0; kv_reg <= '0; - kv_read_data_present <= '0; + kv_seed_data_present <= '0; + kv_key_data_present <= '0; end //Store private key here before pushing to keyvault else begin privkey_we_reg <= hw_privkey_we; privkey_we_reg_ff <= privkey_we_reg; - if (privkey_out_we & (dest_keyvault | kv_read_data_present)) + if (privkey_out_we & (dest_keyvault | kv_seed_data_present)) kv_reg <= read_reg; - kv_read_data_present <= kv_read_data_present_set ? '1 : - kv_read_data_present_reset ? '0 : kv_read_data_present; + kv_seed_data_present <= kv_seed_data_present_set ? '1 : + kv_seed_data_present_reset ? '0 : kv_seed_data_present; + kv_key_data_present <= kv_key_data_present_set ? '1 : + kv_key_data_present_reset ? '0 : kv_key_data_present; end end @@ -368,13 +378,16 @@ module ecc_dsa_ctrl //don't store the private key generated in sw accessible register if it's going to keyvault privkey_reg[dword] = hwif_out.ECC_PRIVKEY_IN[11-dword].PRIVKEY_IN.value; hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.we = (pcr_sign_mode | (kv_privkey_write_en & (kv_privkey_write_offset == dword))) & !zeroize_reg; - hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.next = pcr_sign_mode ? pcr_signing_data.pcr_signing_privkey[dword] : kv_privkey_write_en? kv_privkey_write_data : read_reg[11-dword]; - hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.hwclr = zeroize_reg; + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.next = pcr_sign_mode ? pcr_signing_data.pcr_signing_privkey[dword] : + kv_privkey_write_en ? kv_privkey_write_data : + read_reg[11-dword]; + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.hwclr = zeroize_reg | kv_key_data_present_reset | (kv_privkey_error == KV_READ_FAIL); + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.swwe = dsa_ready_reg & ~kv_key_data_present; end for (int dword=0; dword < 12; dword++)begin //If keyvault is not enabled, grab the sw value as usual - hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.we = (privkey_out_we & ~(dest_keyvault | kv_read_data_present)) & !zeroize_reg; + hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.we = (privkey_out_we & ~(dest_keyvault | kv_seed_data_present)) & !zeroize_reg; hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.next = read_reg[11-dword]; hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.hwclr = zeroize_reg; end @@ -383,7 +396,8 @@ module ecc_dsa_ctrl seed_reg[dword] = hwif_out.ECC_SEED[11-dword].SEED.value; hwif_in.ECC_SEED[dword].SEED.we = (kv_seed_write_en & (kv_seed_write_offset == dword)) & !zeroize_reg; hwif_in.ECC_SEED[dword].SEED.next = kv_seed_write_data; - hwif_in.ECC_SEED[dword].SEED.hwclr = zeroize_reg | kv_read_data_present_reset; + hwif_in.ECC_SEED[dword].SEED.hwclr = zeroize_reg | kv_seed_data_present_reset | (kv_seed_error == KV_READ_FAIL); + hwif_in.ECC_SEED[dword].SEED.swwe = dsa_ready_reg & ~kv_seed_data_present; end for (int dword=0; dword < 12; dword++)begin @@ -454,7 +468,7 @@ module ecc_dsa_ctrl end - always_comb hwif_in.ECC_CTRL.CTRL.hwclr = |hwif_out.ECC_CTRL.CTRL.value; + always_comb hwif_in.ECC_CTRL.CTRL.hwclr = |cmd_reg; always_comb hwif_in.ECC_CTRL.PCR_SIGN.hwclr = hwif_out.ECC_CTRL.PCR_SIGN.value; // TODO add other interrupt hwset signals (errors) @@ -490,9 +504,12 @@ module ecc_dsa_ctrl `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_seed_read_ctrl_reg, ecc_kv_rd_seed_ctrl) `CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_write_ctrl_reg, ecc_kv_wr_pkey_ctrl) - //Force result into KV reg whenever source came from KV - always_comb kv_read_data_present_set = kv_seed_read_ctrl_reg.read_en; - always_comb kv_read_data_present_reset = kv_read_data_present & privkey_out_we; + //Detect keyvault data coming in to lock api registers and protect outputs + always_comb kv_seed_data_present_set = kv_seed_read_ctrl_reg.read_en; + always_comb kv_seed_data_present_reset = kv_seed_data_present & ecc_status_done_p; + + always_comb kv_key_data_present_set = kv_privkey_read_ctrl_reg.read_en; + always_comb kv_key_data_present_reset = kv_key_data_present & ecc_status_done_p; always_comb pcr_sign_mode = hwif_out.ECC_CTRL.PCR_SIGN.value; @@ -900,4 +917,6 @@ module ecc_dsa_ctrl .dest_done(kv_write_done) ); +always_comb busy_o = ~dsa_ready_reg | ~kv_write_ready | ~kv_seed_ready | ~kv_privkey_ready; + endmodule diff --git a/src/ecc/rtl/ecc_reg.rdl b/src/ecc/rtl/ecc_reg.rdl index 12239e82f..848d91234 100644 --- a/src/ecc/rtl/ecc_reg.rdl +++ b/src/ecc/rtl/ecc_reg.rdl @@ -119,7 +119,7 @@ addrmap ecc_reg { default hw = rw; default we = true; default resetsignal = reset_b; - field {desc = "Input seed field"; swwe = ecc_ready; hwclr;} SEED[32] = 32'b0; + field {desc = "Input seed field"; swwe; hwclr;} SEED[32] = 32'b0; } ECC_SEED[12] @0x00000080; @@ -192,7 +192,7 @@ addrmap ecc_reg { default hw = rw; default we = true; default resetsignal = reset_b; - field {desc = "Private key field"; swwe = ecc_ready; hwclr;} PRIVKEY_IN[32] = 32'b0; + field {desc = "Private key field"; swwe; hwclr;} PRIVKEY_IN[32] = 32'b0; } ECC_PRIVKEY_IN[12] @0x00000580; diff --git a/src/ecc/rtl/ecc_reg.sv b/src/ecc/rtl/ecc_reg.sv index 5d7e9c5b5..cd5fccc18 100644 --- a/src/ecc/rtl/ecc_reg.sv +++ b/src/ecc/rtl/ecc_reg.sv @@ -733,7 +733,7 @@ module ecc_reg ( automatic logic load_next_c; next_c = field_storage.ECC_SEED[i0].SEED.value; load_next_c = '0; - if(decoded_reg_strb.ECC_SEED[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + if(decoded_reg_strb.ECC_SEED[i0] && decoded_req_is_wr && hwif_in.ECC_SEED[i0].SEED.swwe) begin // SW write next_c = (field_storage.ECC_SEED[i0].SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); load_next_c = '1; end else if(hwif_in.ECC_SEED[i0].SEED.we) begin // HW Write - we @@ -1010,7 +1010,7 @@ module ecc_reg ( automatic logic load_next_c; next_c = field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value; load_next_c = '0; - if(decoded_reg_strb.ECC_PRIVKEY_IN[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + if(decoded_reg_strb.ECC_PRIVKEY_IN[i0] && decoded_req_is_wr && hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.swwe) begin // SW write next_c = (field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); load_next_c = '1; end else if(hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.we) begin // HW Write - we diff --git a/src/ecc/rtl/ecc_reg_pkg.sv b/src/ecc/rtl/ecc_reg_pkg.sv index d729b5a14..148c39089 100644 --- a/src/ecc/rtl/ecc_reg_pkg.sv +++ b/src/ecc/rtl/ecc_reg_pkg.sv @@ -51,6 +51,7 @@ package ecc_reg_pkg; typedef struct packed{ logic [31:0] next; logic we; + logic swwe; logic hwclr; } ecc_reg__ECC_SEED__SEED__in_t; @@ -147,6 +148,7 @@ package ecc_reg_pkg; typedef struct packed{ logic [31:0] next; logic we; + logic swwe; logic hwclr; } ecc_reg__ECC_PRIVKEY_IN__PRIVKEY_IN__in_t; diff --git a/src/ecc/rtl/ecc_top.sv b/src/ecc/rtl/ecc_top.sv index b78ae1535..394ffda30 100644 --- a/src/ecc/rtl/ecc_top.sv +++ b/src/ecc/rtl/ecc_top.sv @@ -56,6 +56,8 @@ module ecc_top //PCR Signing input pcr_signing_t pcr_signing_data, + output logic busy_o, + output logic error_intr, output logic notif_intr, input logic debugUnlock_or_scan_mode_switch @@ -148,6 +150,8 @@ module ecc_top .kv_wr_resp(kv_wr_resp), .pcr_signing_data(pcr_signing_data), + .busy_o(busy_o), + .error_intr(error_intr), .notif_intr(notif_intr), .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) diff --git a/src/ecc/tb/ecc_top_tb.sv b/src/ecc/tb/ecc_top_tb.sv index 9112a4718..f046c5f6d 100644 --- a/src/ecc/tb/ecc_top_tb.sv +++ b/src/ecc/tb/ecc_top_tb.sv @@ -170,7 +170,7 @@ module ecc_top_tb .kv_rd_resp(kv_rd_resp_tb), .kv_wr_resp(kv_wr_resp_tb), .pcr_signing_data(pcr_signing_data_tb), - + .busy_o(), .error_intr(error_intr_tb), .notif_intr(notif_intr_tb), .debugUnlock_or_scan_mode_switch('0) diff --git a/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv b/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv index 01fffdedb..1438e3d28 100644 --- a/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv +++ b/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv @@ -114,7 +114,7 @@ import uvmf_base_pkg_hdl::*; .hresp_o (ECC_out_agent_bus.hresp), .hreadyout_o (ECC_out_agent_bus.hreadyout), .hrdata_o (ECC_out_agent_bus.hrdata), - + .busy_o (), .error_intr (), .notif_intr (), .debugUnlock_or_scan_mode_switch('0) diff --git a/src/hmac/rtl/hmac.sv b/src/hmac/rtl/hmac.sv index a9d0114c4..af429cc91 100644 --- a/src/hmac/rtl/hmac.sv +++ b/src/hmac/rtl/hmac.sv @@ -49,6 +49,8 @@ module hmac input kv_rd_resp_t [1:0] kv_rd_resp, input kv_wr_resp_t kv_wr_resp, + output logic busy_o, + output wire error_intr, output wire notif_intr, input logic debugUnlock_or_scan_mode_switch @@ -104,8 +106,9 @@ module hmac logic [4:0] kv_block_write_offset; logic [31:0] kv_block_write_data; //KV Read Data Present - logic kv_read_data_present; - logic kv_read_data_present_set, kv_read_data_present_reset; + logic kv_key_data_present, kv_key_data_present_set; + logic [BLOCK_NUM_DWORDS-1:0] block_reg_lock, block_reg_lock_nxt; + logic kv_data_present, kv_data_present_set, kv_data_present_reset; logic dest_keyvault; kv_error_code_e kv_key_error, kv_block_error, kv_write_error; @@ -177,7 +180,9 @@ module hmac tag_reg <= '0; tag_valid_reg <= '0; ready_reg <= '0; - kv_read_data_present <= '0; + block_reg_lock <= '0; + kv_key_data_present <= '0; + kv_data_present <= '0; end else if (zeroize_reg) begin @@ -185,7 +190,9 @@ module hmac tag_reg <= '0; tag_valid_reg <= '0; ready_reg <= '0; - kv_read_data_present <= '0; + block_reg_lock <= '0; + kv_key_data_present <= '0; + kv_data_present <= '0; end else begin @@ -193,13 +200,16 @@ module hmac ready_reg <= core_ready; //write to sw register - if (core_tag_we & ~(dest_keyvault | kv_read_data_present)) + if (core_tag_we & ~(dest_keyvault | kv_data_present)) tag_reg <= core_tag; - if (core_tag_we & (dest_keyvault | kv_read_data_present)) + if (core_tag_we & (dest_keyvault | kv_data_present)) kv_reg <= core_tag; - kv_read_data_present <= kv_read_data_present_set ? '1 : - kv_read_data_present_reset ? '0 : kv_read_data_present; + block_reg_lock <= block_reg_lock_nxt; + kv_key_data_present <= kv_key_data_present_set ? '1 : + kv_data_present_reset ? '0 : kv_key_data_present; + kv_data_present <= kv_data_present_set ? '1 : + kv_data_present_reset ? '0 : kv_data_present; end end // reg_update @@ -215,8 +225,9 @@ always_comb begin hwif_in.HMAC384_VERSION[1].VERSION.next = HMAC_CORE_VERSION[63:32]; //assign hardware readable registers to drive hmac core - init_reg = hwif_out.HMAC384_CTRL.INIT.value; - next_reg = hwif_out.HMAC384_CTRL.NEXT.value; + //mask the command until kv clients are idle + init_reg = hwif_out.HMAC384_CTRL.INIT.value & kv_key_ready & kv_block_ready; + next_reg = hwif_out.HMAC384_CTRL.NEXT.value & kv_key_ready & kv_block_ready; zeroize_reg = hwif_out.HMAC384_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; //drive hardware writeable registers from hmac core @@ -228,14 +239,16 @@ always_comb begin end //drive hardware writable registers from key vault for (int dword=0; dword < BLOCK_NUM_DWORDS; dword++)begin - hwif_in.HMAC384_BLOCK[dword].BLOCK.we = (kv_block_write_en & (kv_block_write_offset == dword)) & !(zeroize_reg | kv_read_data_present_reset); + hwif_in.HMAC384_BLOCK[dword].BLOCK.we = (kv_block_write_en & (kv_block_write_offset == dword)) & !(zeroize_reg | kv_data_present_reset); hwif_in.HMAC384_BLOCK[dword].BLOCK.next = kv_block_write_data; - hwif_in.HMAC384_BLOCK[dword].BLOCK.hwclr = zeroize_reg | kv_read_data_present_reset; + hwif_in.HMAC384_BLOCK[dword].BLOCK.hwclr = zeroize_reg | kv_data_present_reset | (kv_block_error == KV_READ_FAIL); + hwif_in.HMAC384_BLOCK[dword].BLOCK.swwel = block_reg_lock[dword]; end for (int dword=0; dword < KEY_NUM_DWORDS; dword++)begin - hwif_in.HMAC384_KEY[dword].KEY.we = (kv_key_write_en & (kv_key_write_offset == dword)) & !(zeroize_reg | kv_read_data_present_reset); + hwif_in.HMAC384_KEY[dword].KEY.we = (kv_key_write_en & (kv_key_write_offset == dword)) & !(zeroize_reg | kv_data_present_reset); hwif_in.HMAC384_KEY[dword].KEY.next = kv_key_write_data; - hwif_in.HMAC384_KEY[dword].KEY.hwclr = zeroize_reg | kv_read_data_present_reset; + hwif_in.HMAC384_KEY[dword].KEY.hwclr = zeroize_reg | kv_data_present_reset | (kv_key_error == KV_READ_FAIL); + hwif_in.HMAC384_KEY[dword].KEY.swwel = kv_key_data_present; end //set ready when keyvault isn't busy hwif_in.HMAC384_KV_RD_KEY_STATUS.READY.next = kv_key_ready; @@ -270,14 +283,28 @@ always_comb begin end end +//set the lock for the part of the block being written by KV logic +//release the lock once init has been seen +always_comb begin + for (int dword=0; dword< BLOCK_NUM_DWORDS; dword++) begin + if (init_reg | next_reg) begin + block_reg_lock_nxt[dword] = '0; + end + else begin + block_reg_lock_nxt[dword] = (kv_block_write_en & (kv_block_write_offset == dword)) ? '1 : block_reg_lock[dword]; + end + end +end + //keyvault control reg macros for assigning to struct `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_key_read_ctrl_reg, HMAC384_KV_RD_KEY_CTRL) `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_block_read_ctrl_reg, HMAC384_KV_RD_BLOCK_CTRL) `CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_write_ctrl_reg, HMAC384_KV_WR_CTRL) //Force result into KV reg whenever source came from KV -always_comb kv_read_data_present_set = kv_key_read_ctrl_reg.read_en | kv_block_read_ctrl_reg.read_en; -always_comb kv_read_data_present_reset = kv_read_data_present & core_tag_we; +always_comb kv_key_data_present_set = kv_key_read_ctrl_reg.read_en; +always_comb kv_data_present_set = kv_key_read_ctrl_reg.read_en | kv_block_read_ctrl_reg.read_en; +always_comb kv_data_present_reset = kv_data_present & core_tag_we; // Register block hmac_reg i_hmac_reg ( @@ -395,6 +422,8 @@ hmac_result_kv_write .dest_done(kv_write_done) ); +always_comb busy_o = ~kv_write_ready | ~kv_block_ready | ~kv_key_ready | ~core_ready; + endmodule // hmac //====================================================================== diff --git a/src/hmac/rtl/hmac_ctrl.sv b/src/hmac/rtl/hmac_ctrl.sv index 04ee61a4c..8498d0e6b 100644 --- a/src/hmac/rtl/hmac_ctrl.sv +++ b/src/hmac/rtl/hmac_ctrl.sv @@ -56,6 +56,8 @@ module hmac_ctrl input kv_rd_resp_t [1:0] kv_rd_resp, input kv_wr_resp_t kv_wr_resp, + output logic busy_o, + // Interrupt output logic error_intr, output logic notif_intr, @@ -90,6 +92,7 @@ module hmac_ctrl .kv_wr_resp(kv_wr_resp), .error_intr(error_intr), .notif_intr(notif_intr), + .busy_o(busy_o), .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) ); diff --git a/src/hmac/rtl/hmac_reg.rdl b/src/hmac/rtl/hmac_reg.rdl index 0f7713955..c4a3f7220 100644 --- a/src/hmac/rtl/hmac_reg.rdl +++ b/src/hmac/rtl/hmac_reg.rdl @@ -117,7 +117,7 @@ addrmap hmac_reg { default hw = rw; default we = true; default resetsignal = reset_b; - field {desc = "Input HMAC384 key field"; hwclr;} KEY[32] = 32'b0; + field {desc = "Input HMAC384 key field"; hwclr; swwel;} KEY[32] = 32'b0; } HMAC384_KEY[12] @0x00000040; @@ -134,7 +134,7 @@ addrmap hmac_reg { default hw = rw; default we = true; default resetsignal = reset_b; - field {desc = "Input message block field"; hwclr;} BLOCK[32] = 32'b0; + field {desc = "Input message block field"; hwclr; swwel;} BLOCK[32] = 32'b0; } HMAC384_BLOCK[32] @0x00000080; diff --git a/src/hmac/rtl/hmac_reg.sv b/src/hmac/rtl/hmac_reg.sv index 6b80b0098..57ec3b8fd 100644 --- a/src/hmac/rtl/hmac_reg.sv +++ b/src/hmac/rtl/hmac_reg.sv @@ -781,7 +781,7 @@ module hmac_reg ( automatic logic load_next_c; next_c = field_storage.HMAC384_KEY[i0].KEY.value; load_next_c = '0; - if(decoded_reg_strb.HMAC384_KEY[i0] && decoded_req_is_wr) begin // SW write + if(decoded_reg_strb.HMAC384_KEY[i0] && decoded_req_is_wr && !(hwif_in.HMAC384_KEY[i0].KEY.swwel)) begin // SW write next_c = (field_storage.HMAC384_KEY[i0].KEY.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); load_next_c = '1; end else if(hwif_in.HMAC384_KEY[i0].KEY.we) begin // HW Write - we @@ -810,7 +810,7 @@ module hmac_reg ( automatic logic load_next_c; next_c = field_storage.HMAC384_BLOCK[i0].BLOCK.value; load_next_c = '0; - if(decoded_reg_strb.HMAC384_BLOCK[i0] && decoded_req_is_wr) begin // SW write + if(decoded_reg_strb.HMAC384_BLOCK[i0] && decoded_req_is_wr && !(hwif_in.HMAC384_BLOCK[i0].BLOCK.swwel)) begin // SW write next_c = (field_storage.HMAC384_BLOCK[i0].BLOCK.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); load_next_c = '1; end else if(hwif_in.HMAC384_BLOCK[i0].BLOCK.we) begin // HW Write - we diff --git a/src/hmac/rtl/hmac_reg_pkg.sv b/src/hmac/rtl/hmac_reg_pkg.sv index e17e253cb..d25da565c 100644 --- a/src/hmac/rtl/hmac_reg_pkg.sv +++ b/src/hmac/rtl/hmac_reg_pkg.sv @@ -38,6 +38,7 @@ package hmac_reg_pkg; typedef struct packed{ logic [31:0] next; logic we; + logic swwel; logic hwclr; } hmac_reg__HMAC384_KEY__KEY__in_t; @@ -48,6 +49,7 @@ package hmac_reg_pkg; typedef struct packed{ logic [31:0] next; logic we; + logic swwel; logic hwclr; } hmac_reg__HMAC384_BLOCK__BLOCK__in_t; diff --git a/src/hmac/tb/hmac_ctrl_tb.sv b/src/hmac/tb/hmac_ctrl_tb.sv index c070ed310..38af22f3c 100644 --- a/src/hmac/tb/hmac_ctrl_tb.sv +++ b/src/hmac/tb/hmac_ctrl_tb.sv @@ -176,7 +176,7 @@ module hmac_ctrl_tb(); .kv_write(), .kv_rd_resp('x), .kv_wr_resp('x), - + .busy_o(), .error_intr(), .notif_intr(), .debugUnlock_or_scan_mode_switch('0) diff --git a/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv b/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv index 24bbe0a1c..29b6b2e38 100644 --- a/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv +++ b/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv @@ -25,6 +25,7 @@ module hdl_top; import HMAC_parameters_pkg::*; import uvmf_base_pkg_hdl::*; +import kv_defines_pkg::*; // pragma attribute hdl_top partition_module_xrtl // pragma uvmf custom clock_generator begin @@ -43,10 +44,15 @@ import uvmf_base_pkg_hdl::*; // pragma uvmf custom reset_generator begin bit rst; + bit cptra_pwrgood; // Instantiate a rst driver // tbx clkgen initial begin rst = 0; + cptra_pwrgood = 0; + @(negedge clk) + @(posedge clk) + cptra_pwrgood = 1; #200ns; rst = 1; end @@ -83,12 +89,21 @@ import uvmf_base_pkg_hdl::*; //verilog_dut dut_verilog( .clk(clk), .rst(rst), .in_signal(vhdl_to_verilog_signal), .out_signal(verilog_to_vhdl_signal)); //vhdl_dut dut_vhdl ( .clk(clk), .rst(rst), .in_signal(verilog_to_vhdl_signal), .out_signal(vhdl_to_verilog_signal)); +var kv_rd_resp_t [1:0] kv_rd_resp; +var kv_wr_resp_t kv_wr_resp; +initial begin + kv_rd_resp[0] = '{default:0}; + kv_rd_resp[1] = '{default:0}; + kv_wr_resp = '{default:0}; +end + hmac_ctrl #( .AHB_DATA_WIDTH(32), .AHB_ADDR_WIDTH(32) ) dut ( - .clk (HMAC_in_agent_bus.clk), + .clk (HMAC_in_agent_bus.clk), .reset_n (HMAC_in_agent_bus.hmac_rst), + .cptra_pwrgood (cptra_pwrgood), .haddr_i (HMAC_in_agent_bus.haddr), .hwdata_i (HMAC_in_agent_bus.hwdata), .hsel_i (HMAC_in_agent_bus.hsel), @@ -101,8 +116,9 @@ hmac_ctrl #( .hrdata_o (HMAC_out_agent_bus.hrdata), .kv_read (), .kv_write (), - .kv_rd_resp (), - .kv_wr_resp (), + .kv_rd_resp (kv_rd_resp), + .kv_wr_resp (kv_wr_resp), + .busy_o (), .error_intr (), .notif_intr (), .debugUnlock_or_scan_mode_switch('0) diff --git a/src/integration/rtl/caliptra_reg.h b/src/integration/rtl/caliptra_reg.h index eb10fd96d..ac337181e 100644 --- a/src/integration/rtl/caliptra_reg.h +++ b/src/integration/rtl/caliptra_reg.h @@ -5350,6 +5350,8 @@ #define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_MASK (0x2) #define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW (2) #define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK (0x4) +#define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW (3) +#define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK (0x8) #define CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (0x30030004) #define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (0x4) #define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW (0) @@ -5800,6 +5802,8 @@ #define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_DCCM_ECC_UNC_MASK (0x2) #define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_LOW (2) #define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_MASK (0x4) +#define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_LOW (3) +#define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_MASK (0x8) #define CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (0x30030634) #define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (0x634) #define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_NO_LOCK_LOW (0) diff --git a/src/integration/rtl/caliptra_reg_defines.svh b/src/integration/rtl/caliptra_reg_defines.svh index c7af5ea04..a3c69ed81 100644 --- a/src/integration/rtl/caliptra_reg_defines.svh +++ b/src/integration/rtl/caliptra_reg_defines.svh @@ -5350,6 +5350,8 @@ `define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_MASK (32'h2) `define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW (2) `define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK (32'h4) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW (3) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK (32'h8) `define CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (32'h30030004) `define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (32'h4) `define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW (0) @@ -5800,6 +5802,8 @@ `define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_DCCM_ECC_UNC_MASK (32'h2) `define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_LOW (2) `define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_MASK (32'h4) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_LOW (3) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_MASK (32'h8) `define CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (32'h30030634) `define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (32'h634) `define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_NO_LOCK_LOW (0) diff --git a/src/integration/rtl/caliptra_top.sv b/src/integration/rtl/caliptra_top.sv index fd2181cce..c0fab416f 100755 --- a/src/integration/rtl/caliptra_top.sv +++ b/src/integration/rtl/caliptra_top.sv @@ -269,6 +269,12 @@ module caliptra_top logic lsu_addr_ph, lsu_data_ph, lsu_sel; logic ic_addr_ph, ic_data_ph, ic_sel; + logic hmac_busy, ecc_busy, doe_busy; + logic crypto_error; + + always_comb crypto_error = (hmac_busy & ecc_busy) | + (ecc_busy & doe_busy) | + (hmac_busy & doe_busy); always_comb begin mbox_sram_cs = mbox_sram_req.cs; @@ -824,6 +830,7 @@ doe_ctrl #( .error_intr(doe_error_intr), .notif_intr(doe_notif_intr), .clear_obf_secrets(clear_obf_secrets), //Output + .busy_o(doe_busy), .kv_write (kv_write[KV_NUM_WRITE-1]), .kv_wr_resp (kv_wr_resp[KV_NUM_WRITE-1]), .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) @@ -855,7 +862,7 @@ ecc_top1 .kv_write (kv_write[2]), .kv_wr_resp (kv_wr_resp[2]), .pcr_signing_data(pcr_signing_data), - + .busy_o (ecc_busy), .error_intr (ecc_error_intr), .notif_intr (ecc_notif_intr), .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) @@ -882,7 +889,7 @@ hmac_ctrl #( .kv_write (kv_write[0]), .kv_rd_resp (kv_rd_resp[1:0]), .kv_wr_resp (kv_wr_resp[0]), - + .busy_o (hmac_busy), .error_intr(hmac_error_intr), .notif_intr(hmac_notif_intr), .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) @@ -1251,7 +1258,8 @@ soc_ifc_top1 .clk_gating_en(clk_gating_en), .rdc_clk_dis(rdc_clk_dis), .fw_update_rst_window(fw_update_rst_window), - + //multiple cryptos operating at once, assert fatal error + .crypto_error(crypto_error), //caliptra uncore jtag ports .cptra_uncore_dmi_reg_en ( cptra_uncore_dmi_reg_en ), .cptra_uncore_dmi_reg_wr_en( cptra_uncore_dmi_reg_wr_en ), diff --git a/src/integration/stimulus/L0_regression.yml b/src/integration/stimulus/L0_regression.yml index 2614e6710..c261c8d60 100644 --- a/src/integration/stimulus/L0_regression.yml +++ b/src/integration/stimulus/L0_regression.yml @@ -35,7 +35,8 @@ contents: - ../test_suites/smoke_test_kv_securitystate/smoke_test_kv_securitystate.yml - ../test_suites/smoke_test_kv_ecc_flow/smoke_test_kv_ecc_flow.yml - ../test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.yml - - ../test_suites/smoke_test_kv_sha512_flow/smoke_test_kv_sha512_flow.yml + - ../test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.yml + #- ../test_suites/smoke_test_kv_sha512_flow/smoke_test_kv_sha512_flow.yml Removed SHA KV functionality - ../test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.yml #- ../test_suites/smoke_test_kv_cg/smoke_test_kv_cg.yml - ../test_suites/pv_hash_and_sign/pv_hash_and_sign.yml diff --git a/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml b/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml index 7e0ad8302..1c0bce644 100644 --- a/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml +++ b/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml @@ -33,6 +33,7 @@ contents: - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_securitystate/smoke_test_kv_securitystate.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_ecc_flow/smoke_test_kv_ecc_flow.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_sha512_flow/smoke_test_kv_sha512_flow.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/pv_hash_and_sign/pv_hash_and_sign.yml diff --git a/src/integration/tb/caliptra_top_tb.sv b/src/integration/tb/caliptra_top_tb.sv index 18f0722ee..217227be5 100755 --- a/src/integration/tb/caliptra_top_tb.sv +++ b/src/integration/tb/caliptra_top_tb.sv @@ -256,6 +256,9 @@ module caliptra_top_tb ( else if (PRDATA[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW]) begin generic_input_wires <= {32'h0, NMI_FATAL_OBSERVED}; end + else if (PRDATA[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW]) begin + generic_input_wires <= {32'h0, CRYPTO_ERROR_OBSERVED}; + end else begin generic_input_wires <= {32'h0, ERROR_NONE_SET}; end diff --git a/src/integration/tb/caliptra_top_tb_pkg.sv b/src/integration/tb/caliptra_top_tb_pkg.sv index 28f97e6f2..3dc9a58f6 100644 --- a/src/integration/tb/caliptra_top_tb_pkg.sv +++ b/src/integration/tb/caliptra_top_tb_pkg.sv @@ -80,6 +80,7 @@ localparam PROT_OOO_NON_FATAL_OBSERVED = 32'h600dcafe; localparam ICCM_FATAL_OBSERVED = 32'hdeadaca1; localparam DCCM_FATAL_OBSERVED = 32'hdeadbeef; localparam NMI_FATAL_OBSERVED = 32'hdeadc0a7; +localparam CRYPTO_ERROR_OBSERVED = 32'hdeadface; localparam DMA_ERROR_OBSERVED = 32'hfadebadd; localparam ERROR_NONE_SET = 32'hba5eba11; /* default value for a test with no activity observed by TB */ diff --git a/src/integration/test_suites/libs/ecc/ecc.c b/src/integration/test_suites/libs/ecc/ecc.c index 5f97375f0..054406393 100644 --- a/src/integration/test_suites/libs/ecc/ecc.c +++ b/src/integration/test_suites/libs/ecc/ecc.c @@ -58,6 +58,12 @@ void ecc_keygen_flow(ecc_io seed, ecc_io nonce, ecc_io iv, ecc_io privkey, ecc_i lsu_write_32(CLP_ECC_REG_ECC_KV_RD_SEED_CTRL, (ECC_REG_ECC_KV_RD_SEED_CTRL_READ_EN_MASK | ((seed.kv_id << ECC_REG_ECC_KV_RD_SEED_CTRL_READ_ENTRY_LOW) & ECC_REG_ECC_KV_RD_SEED_CTRL_READ_ENTRY_MASK))); + // Try to overwrite ECC SEED from keyvault + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_SEED_0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_SEED_11) { + *reg_ptr++ = 0; + } + // Check that ECC SEED is loaded while((lsu_read_32(CLP_ECC_REG_ECC_KV_RD_SEED_STATUS) & ECC_REG_ECC_KV_RD_SEED_STATUS_VALID_MASK) == 0); } @@ -177,6 +183,12 @@ void ecc_signing_flow(ecc_io privkey, ecc_io msg, ecc_io iv, ecc_io sign_r, ecc_ lsu_write_32(CLP_ECC_REG_ECC_KV_RD_PKEY_CTRL, (ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_EN_MASK | ((privkey.kv_id << ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_ENTRY_LOW) & ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_ENTRY_MASK))); + // Try to overwrite ECC PRIVKEY from key vault + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_PRIVKEY_IN_0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_PRIVKEY_IN_11) { + *reg_ptr++ = 0; + } + // Check that ECC PRIVKEY is loaded while((lsu_read_32(CLP_ECC_REG_ECC_KV_RD_PKEY_STATUS) & ECC_REG_ECC_KV_RD_PKEY_STATUS_VALID_MASK) == 0); } diff --git a/src/integration/test_suites/libs/hmac/hmac.c b/src/integration/test_suites/libs/hmac/hmac.c index 7d6f28e46..8b6a3e8d8 100644 --- a/src/integration/test_suites/libs/hmac/hmac.c +++ b/src/integration/test_suites/libs/hmac/hmac.c @@ -38,7 +38,7 @@ void hmac_zeroize(){ lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, (1 << HMAC_REG_HMAC384_CTRL_ZEROIZE_LOW) & HMAC_REG_HMAC384_CTRL_ZEROIZE_MASK); } -void hmac_flow(hmac_io key, hmac_io block, hmac_io lfsr_seed, hmac_io tag){ +void hmac_flow(hmac_io key, hmac_io block, hmac_io lfsr_seed, hmac_io tag, BOOL init){ uint8_t offset; volatile uint32_t * reg_ptr; uint8_t fail_cmd = 0x1; @@ -54,6 +54,12 @@ void hmac_flow(hmac_io key, hmac_io block, hmac_io lfsr_seed, hmac_io tag){ lsu_write_32(CLP_HMAC_REG_HMAC384_KV_RD_KEY_CTRL, HMAC_REG_HMAC384_KV_RD_KEY_CTRL_READ_EN_MASK | ((key.kv_id << HMAC_REG_HMAC384_KV_RD_KEY_CTRL_READ_ENTRY_LOW) & HMAC_REG_HMAC384_KV_RD_KEY_CTRL_READ_ENTRY_MASK)); + VPRINTF(LOW, "Try to Overwrite Key data in HMAC\n"); + reg_ptr = (uint32_t*) CLP_HMAC_REG_HMAC384_KEY_0; + while (reg_ptr <= (uint32_t*) CLP_HMAC_REG_HMAC384_KEY_11) { + *reg_ptr++ = 0; + } + // Check that HMAC KEY is loaded while((lsu_read_32(CLP_HMAC_REG_HMAC384_KV_RD_KEY_STATUS) & HMAC_REG_HMAC384_KV_RD_KEY_STATUS_VALID_MASK) == 0); @@ -74,6 +80,12 @@ void hmac_flow(hmac_io key, hmac_io block, hmac_io lfsr_seed, hmac_io tag){ lsu_write_32(CLP_HMAC_REG_HMAC384_KV_RD_BLOCK_CTRL, HMAC_REG_HMAC384_KV_RD_BLOCK_CTRL_READ_EN_MASK | ((block.kv_id << HMAC_REG_HMAC384_KV_RD_BLOCK_CTRL_READ_ENTRY_LOW) & HMAC_REG_HMAC384_KV_RD_BLOCK_CTRL_READ_ENTRY_MASK)); + VPRINTF(LOW, "Try to Overwrite Block data in HMAC\n"); + reg_ptr = (uint32_t*) CLP_HMAC_REG_HMAC384_BLOCK_0; + while (reg_ptr <= (uint32_t*) CLP_HMAC_REG_HMAC384_BLOCK_31) { + *reg_ptr++ = 0; + } + // Check that HMAC BLOCK is loaded while((lsu_read_32(CLP_HMAC_REG_HMAC384_KV_RD_BLOCK_STATUS) & HMAC_REG_HMAC384_KV_RD_BLOCK_STATUS_VALID_MASK) == 0); } @@ -105,7 +117,12 @@ void hmac_flow(hmac_io key, hmac_io block, hmac_io lfsr_seed, hmac_io tag){ } // Enable HMAC core - lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, HMAC_REG_HMAC384_CTRL_INIT_MASK); + if (init) { + lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, HMAC_REG_HMAC384_CTRL_INIT_MASK); + } + else { + lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, HMAC_REG_HMAC384_CTRL_NEXT_MASK); + } // wait for HMAC process to be done wait_for_hmac_intr(); diff --git a/src/integration/test_suites/libs/hmac/hmac.h b/src/integration/test_suites/libs/hmac/hmac.h index b8ee2da5b..967440d70 100644 --- a/src/integration/test_suites/libs/hmac/hmac.h +++ b/src/integration/test_suites/libs/hmac/hmac.h @@ -31,7 +31,7 @@ typedef struct { uint32_t data[32]; }hmac_io; -void hmac_flow(hmac_io hmac_key, hmac_io block, hmac_io lfsr_seed, hmac_io tag); +void hmac_flow(hmac_io hmac_key, hmac_io block, hmac_io lfsr_seed, hmac_io tag, BOOL init); void hmac_zeroize(); #endif diff --git a/src/integration/test_suites/smoke_test_fw_kv_backtoback_hmac/smoke_test_fw_kv_backtoback_hmac.c b/src/integration/test_suites/smoke_test_fw_kv_backtoback_hmac/smoke_test_fw_kv_backtoback_hmac.c index 8b2cc5203..88093da0e 100644 --- a/src/integration/test_suites/smoke_test_fw_kv_backtoback_hmac/smoke_test_fw_kv_backtoback_hmac.c +++ b/src/integration/test_suites/smoke_test_fw_kv_backtoback_hmac/smoke_test_fw_kv_backtoback_hmac.c @@ -181,7 +181,7 @@ void main() { uint8_t key_inject_cmd = 0xa0 + (hmac_key.kv_id & 0x7); printf("%c", key_inject_cmd); - hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag); + hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag, TRUE); printf("KV HMAC flow is completed.\n\n"); diff --git a/src/integration/test_suites/smoke_test_hmac/smoke_test_hmac.c b/src/integration/test_suites/smoke_test_hmac/smoke_test_hmac.c index 4015330b1..484d7edaf 100644 --- a/src/integration/test_suites/smoke_test_hmac/smoke_test_hmac.c +++ b/src/integration/test_suites/smoke_test_hmac/smoke_test_hmac.c @@ -154,7 +154,7 @@ void main() { hmac_tag.data[i] = expected_tag[i]; - hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag); + hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag, TRUE); hmac_zeroize(); // Write 0xff to STDOUT for TB to terminate test. diff --git a/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.c b/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.c index 12383a871..bc3ba1b6a 100644 --- a/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.c +++ b/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.c @@ -151,7 +151,7 @@ void kv_hmac(uint8_t key_id, uint8_t block_id, uint8_t tag_id){ //uint8_t key_inject_cmd = 0xa0 + (hmac_key.kv_id & 0x1f); //printf("%c", key_inject_cmd); - hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag); + hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag, TRUE); //printf("%c", 0x1); } diff --git a/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.c b/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.c index f43580d77..3a162a5f9 100644 --- a/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.c +++ b/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.c @@ -142,7 +142,7 @@ void main() { hmac_key.kv_intf = TRUE; hmac_key.kv_id = hmackey_kv_id; - hmac_block.kv_intf = FALSE; + hmac_block.kv_intf = TRUE; hmac_block.kv_id = hmacblock_kv_id; hmac_block.data_size = 32; for (int i = 0; i < hmac_block.data_size; i++) @@ -164,7 +164,7 @@ void main() { uint8_t key_inject_cmd = 0xa0 + (hmac_key.kv_id & 0x7); printf("%c", key_inject_cmd); - hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag); + hmac_flow(hmac_key, hmac_block, hmac_lfsr_seed, hmac_tag, TRUE); hmac_zeroize(); printf("%c",0xff); //End the test diff --git a/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/caliptra_isr.h b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/caliptra_isr.h new file mode 100644 index 000000000..8f5779e04 --- /dev/null +++ b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/caliptra_isr.h @@ -0,0 +1,247 @@ +// 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. +// +// --------------------------------------------------------------------- +// File: caliptra_isr.h +// Description: +// Provides function declarations for use by external test files, so +// that the ISR functionality may behave like a library. +// TODO: +// This header file includes inline function definitions for event and +// test specific interrupt service behavior, so it should be copied and +// modified for each test. +// --------------------------------------------------------------------- + +#ifndef CALIPTRA_ISR_H + #define CALIPTRA_ISR_H + +#define EN_ISR_PRINTS 1 + +#include "caliptra_defines.h" +#include +#include "printf.h" + +/* --------------- symbols/typedefs --------------- */ +typedef struct { + uint32_t doe_error; + uint32_t doe_notif; + uint32_t ecc_error; + uint32_t ecc_notif; + uint32_t hmac_error; + uint32_t hmac_notif; + uint32_t kv_error; + uint32_t kv_notif; + uint32_t sha512_error; + uint32_t sha512_notif; + uint32_t sha256_error; + uint32_t sha256_notif; + uint32_t qspi_error; + uint32_t qspi_notif; + uint32_t uart_error; + uint32_t uart_notif; + uint32_t i3c_error; + uint32_t i3c_notif; + uint32_t soc_ifc_error; + uint32_t soc_ifc_notif; + uint32_t sha512_acc_error; + uint32_t sha512_acc_notif; +} caliptra_intr_received_s; +extern volatile caliptra_intr_received_s cptra_intr_rcv; + +////////////////////////////////////////////////////////////////////////////// +// Function Declarations +// + +// Performs all the CSR setup to configure and enable vectored external interrupts +void init_interrupts(void); + +// These inline functions are used to insert event-specific functionality into the +// otherwise generic ISR that gets laid down by the parameterized macro "nonstd_veer_isr" +inline void service_doe_error_intr() {return;} +inline void service_doe_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.doe_notif |= DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad doe_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_ecc_error_intr() {return;} +inline void service_ecc_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.ecc_notif |= ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad ecc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_hmac_error_intr() {return;} +inline void service_hmac_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.hmac_notif |= HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad hmac_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_kv_error_intr() {return;} +inline void service_kv_notif_intr() {return;} +inline void service_sha512_error_intr() {return;} +inline void service_sha512_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha512_notif |= SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha512_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_sha256_error_intr() {return;} +inline void service_sha256_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha256_notif |= SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha256_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_qspi_error_intr() {return;} +inline void service_qspi_notif_intr() {return;} +inline void service_uart_error_intr() {return;} +inline void service_uart_notif_intr() {return;} +inline void service_i3c_error_intr() {return;} +inline void service_i3c_notif_intr() {return;} + +inline void service_soc_ifc_error_intr() { + uint32_t * reg = (uint32_t *) (CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad soc_ifc_error_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_soc_ifc_notif_intr () { + uint32_t * reg = (uint32_t *) (CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad soc_ifc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_sha512_acc_error_intr() {return;} +inline void service_sha512_acc_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha512_acc_notif |= SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha512_acc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + + +#endif //CALIPTRA_ISR_H diff --git a/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.c b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.c new file mode 100644 index 000000000..f7fcd2d75 --- /dev/null +++ b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.c @@ -0,0 +1,282 @@ +// 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. +// + +#include "caliptra_defines.h" +#include "caliptra_isr.h" +#include "riscv_hw_if.h" +#include "riscv-csr.h" +#include +#include +#include +#include "printf.h" +#include "hmac.h" +#include "ecc.h" + +volatile char* stdout = (char *)STDOUT; +volatile uint32_t intr_count = 0; + +#ifdef CPT_VERBOSITY + enum printf_verbosity verbosity_g = CPT_VERBOSITY; +#else + enum printf_verbosity verbosity_g = LOW; +#endif + +volatile caliptra_intr_received_s cptra_intr_rcv = { + .doe_error = 0, + .doe_notif = 0, + .ecc_error = 0, + .ecc_notif = 0, + .hmac_error = 0, + .hmac_notif = 0, + .kv_error = 0, + .kv_notif = 0, + .sha512_error = 0, + .sha512_notif = 0, + .sha256_error = 0, + .sha256_notif = 0, + .qspi_error = 0, + .qspi_notif = 0, + .uart_error = 0, + .uart_notif = 0, + .i3c_error = 0, + .i3c_notif = 0, + .soc_ifc_error = 0, + .soc_ifc_notif = 0, + .sha512_acc_error = 0, + .sha512_acc_notif = 0, +}; + +void main() { + printf("----------------------------------\n"); + printf(" KV Smoke Test With hmac384 flow !!\n"); + printf("----------------------------------\n"); + + //Call interrupt init + init_interrupts(); + + uint32_t block1[32] = {0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000}; + + uint32_t block2[32] = {0x80000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000800}; + + //this is a random lfsr_seed + uint32_t lfsr_seed_data[12] = {0xC8F518D4, + 0xF3AA1BD4, + 0x6ED56C1C, + 0x3C9E16FB, + 0x800AF504, + 0xC8F518D4, + 0xF3AA1BD4, + 0x6ED56C1C, + 0x3C9E16FB, + 0x800AF504, + 0xC8F518D4, + 0xF3AA1BD4}; + + uint32_t expected_tag[12] = {0xd0a3c3b9, + 0x9971a651, + 0x73b83116, + 0xaf89678f, + 0x3fea4219, + 0x40c8728b, + 0x3496a9ed, + 0x08479c4a, + 0xeda828b6, + 0x99929015, + 0x68d2a9c8, + 0xcbfd31b9}; + + uint32_t expected_sign_r[] = {0xB3F46F0A, + 0x732812F1, + 0x50E2D1EC, + 0x8B09340C, + 0xAA758D8C, + 0xD95CC1A0, + 0xF8CE6A17, + 0x646A7D61, + 0xAD50316A, + 0x05BA79D5, + 0xC94098EE, + 0xF8F9C3C3}; + + uint32_t expected_sign_s[] = {0xABB6AA85, + 0x5DD68A8D, + 0x6900D6CB, + 0x6477CDF7, + 0xE39AF7DA, + 0xE6A60EC2, + 0x65FBFF84, + 0xDEB82CF7, + 0xD5787E22, + 0x626E0703, + 0x56D1B743, + 0x702C57B7}; + + uint32_t ecc_iv[] = {0x3401CEFA, + 0xE20A7376, + 0x49073AC1, + 0xA351E329, + 0x26DB9ED0, + 0xDB6B1CFF, + 0xAB0493DA, + 0xAFB93DDD, + 0xD83EDEA2, + 0x8A803D0D, + 0x003B2633, + 0xB9D0F1BF}; + + uint8_t hmackey_kv_id = 0x2; + uint8_t hmacblock_kv_id = 0x1; + uint8_t store_to_kv = 0x1; + uint8_t tag_kv_id = 0x0; + + hmac_io hmac_key; + hmac_io hmac_block1; + hmac_io hmac_block2; + hmac_io hmac_lfsr_seed; + hmac_io hmac_tag; + + uint8_t privkey_kv_id = 0x0; + + ecc_io iv; + ecc_io privkey; + ecc_io msg; + ecc_io sign_r; + ecc_io sign_s; + + hmac_key.kv_intf = TRUE; + hmac_key.kv_id = hmackey_kv_id; + + hmac_block1.kv_intf = FALSE; + hmac_block1.kv_id = hmacblock_kv_id; + hmac_block1.data_size = 32; + for (int i = 0; i < hmac_block1.data_size; i++) + hmac_block1.data[i] = block1[i]; + + hmac_block2.kv_intf = FALSE; + hmac_block2.kv_id = hmacblock_kv_id; + hmac_block2.data_size = 32; + for (int i = 0; i < hmac_block2.data_size; i++) + hmac_block2.data[i] = block2[i]; + + hmac_lfsr_seed.kv_intf = FALSE; + hmac_lfsr_seed.data_size = 12; + for (int i = 0; i < hmac_lfsr_seed.data_size; i++) + hmac_lfsr_seed.data[i] = lfsr_seed_data[i]; + + hmac_tag.kv_intf = TRUE; + hmac_tag.kv_id = tag_kv_id; + hmac_tag.data_size = 12; + for (int i = 0; i < hmac_tag.data_size; i++) + hmac_tag.data[i] = expected_tag[i]; + + + iv.kv_intf = FALSE; + for (int i = 0; i < 12; i++) + iv.data[i] = ecc_iv[i]; + + msg.kv_intf = FALSE; + for (int i = 0; i < 12; i++) + msg.data[i] = 0; + + privkey.kv_intf = TRUE; + privkey.kv_id = privkey_kv_id; + + sign_r.kv_intf = FALSE; + for (int i = 0; i < 12; i++) + sign_r.data[i] = expected_sign_r[i]; + + sign_s.kv_intf = FALSE; + for (int i = 0; i < 12; i++) + sign_s.data[i] = expected_sign_s[i]; + + //inject hmac_key to kv key reg (in RTL) + uint8_t key_inject_cmd = 0xa0 + (hmac_key.kv_id & 0x7); + printf("%c", key_inject_cmd); + + hmac_flow(hmac_key, hmac_block1, hmac_lfsr_seed, hmac_tag, TRUE); + hmac_flow(hmac_key, hmac_block2, hmac_lfsr_seed, hmac_tag, FALSE); + hmac_zeroize(); + + //sign with the generated key + ecc_signing_flow(privkey, msg, iv, sign_r, sign_s); + cptra_intr_rcv.ecc_notif = 0; + + ecc_zeroize(); + + printf("%c",0xff); //End the test + +} diff --git a/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.yml b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.yml new file mode 100644 index 000000000..a28498d1c --- /dev/null +++ b/src/integration/test_suites/smoke_test_kv_hmac_multiblock_flow/smoke_test_kv_hmac_multiblock_flow.yml @@ -0,0 +1,17 @@ +# 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. +# +--- +seed: 1 +testname: smoke_test_kv_hmac_multiblock_flow \ No newline at end of file diff --git a/src/integration/test_suites/smoke_test_ras/smoke_test_ras.c b/src/integration/test_suites/smoke_test_ras/smoke_test_ras.c index 80602d475..629e87e90 100644 --- a/src/integration/test_suites/smoke_test_ras/smoke_test_ras.c +++ b/src/integration/test_suites/smoke_test_ras/smoke_test_ras.c @@ -48,6 +48,8 @@ #include #include #include "printf.h" +#include "ecc.h" +#include "doe.h" //////////////////////////////////////////////////////////////////// // Typedefs @@ -72,6 +74,7 @@ enum tb_resp_value { ICCM_FATAL_OBSERVED = 0xdeadaca1, DCCM_FATAL_OBSERVED = 0xdeadbeef, NMI_FATAL_OBSERVED = 0xdeadc0a7, + CRYPTO_ERROR_OBSERVED = 0xdeadface, DMA_ERROR_OBSERVED = 0xfadebadd, ERROR_NONE_SET = 0xba5eba11, /* default value for a test with no activity observed by TB */ }; @@ -143,6 +146,9 @@ enum test_list { PROT_NO_LOCK_MASKED , PROT_OOO_UNMASKED , PROT_OOO_MASKED , + CRYPTO_HMAC_ECC , + CRYPTO_HMAC_DOE , + CRYPTO_DOE_ECC , TEST_COUNT , }; enum boot_count_list { @@ -154,9 +160,10 @@ enum boot_count_list { BEFORE_FIRST_NMI_FAILURE , BEFORE_SECOND_NMI_FAILURE , BEFORE_THIRD_NMI_FAILURE , - AFTER_THIRD_NMI_FAILURE , - AFTER_FIRST_MBOX_OOO_FAILURE , - AFTER_SECOND_MBOX_OOO_FAILURE + BEFORE_FIRST_CRYPTO_FAILURE , + BEFORE_SECOND_CRYPTO_FAILURE , + BEFORE_THIRD_CRYPTO_FAILURE , + AFTER_THIRD_CRYPTO_FAILURE }; //enum boot_count_list { // RUN_MBOX_AND_FIRST_ICCM_SRAM_ECC = 1, @@ -234,6 +241,9 @@ enum test_progress test_progress_g[TEST_COUNT] __attribute__((section(".dccm.per NOT_STARTED, NOT_STARTED, NOT_STARTED, + NOT_STARTED, + NOT_STARTED, + NOT_STARTED, NOT_STARTED }; @@ -264,6 +274,10 @@ uint32_t check_mbox_ooo_error (enum mask_config test_mask); void run_nmi_test (enum mask_config test_mask); uint32_t check_nmi_test (enum mask_config test_mask); +/* Crypto Error */ +void run_crypto_error (enum test_list test_case); +uint32_t check_crypto_error (enum test_list test_case); + /* Supporting code */ void nmi_handler (void); void execute_from_iccm (void) __attribute__ ((aligned(4),section (".data_iccm0"))); @@ -985,6 +999,60 @@ void run_mbox_ooo_error(enum mask_config test_mask) { } +void run_crypto_error(enum test_list test_case) { + enum test_list cur_test; + VPRINTF(MEDIUM, "\n*** Run Crypto Case ***\n"); + + // Get test ID + if (test_case == CRYPTO_DOE_ECC) { cur_test = CRYPTO_DOE_ECC; } + else if (test_case == CRYPTO_HMAC_DOE) { cur_test = CRYPTO_HMAC_DOE; } + else if (test_case == CRYPTO_HMAC_ECC) { cur_test = CRYPTO_HMAC_ECC; } + + //start appropriate crypto engines + if (test_case == CRYPTO_DOE_ECC) { + //start ecc and doe together + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_KEYGEN); + lsu_write_32(CLP_DOE_REG_DOE_CTRL, DOE_UDS << DOE_REG_DOE_CTRL_CMD_LOW); + } else if (test_case == CRYPTO_HMAC_DOE) { + //start hmac and doe together + lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, HMAC_REG_HMAC384_CTRL_INIT_MASK); + lsu_write_32(CLP_DOE_REG_DOE_CTRL, DOE_FE << DOE_REG_DOE_CTRL_CMD_LOW); + } else if (test_case == CRYPTO_HMAC_ECC) { + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_KEYGEN); + lsu_write_32(CLP_HMAC_REG_HMAC384_CTRL, HMAC_REG_HMAC384_CTRL_INIT_MASK); + } + + // Flag test as having run + test_progress_g[cur_test] = RUN_NOT_CHECKED; + +} + +uint32_t check_crypto_error(enum test_list test_case) { + uint32_t sts = 0; + enum test_list cur_test; + VPRINTF(MEDIUM, "\n*** Check Crypto Case ***\n "); + // Get test ID + if (test_case == CRYPTO_DOE_ECC) { cur_test = CRYPTO_DOE_ECC; } + else if (test_case == CRYPTO_HMAC_DOE) { cur_test = CRYPTO_HMAC_DOE; } + else if (test_case == CRYPTO_HMAC_ECC) { cur_test = CRYPTO_HMAC_ECC; } + + // Check for generic_input_wires activity + if (!(cptra_intr_rcv.soc_ifc_notif & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK)) { + VPRINTF(ERROR, "ERROR: Gen-in did not tgl\n"); + sts |= BAD_CPTRA_SIG; + test_progress_g[cur_test] = RUN_AND_FAILED; + } else if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0) != CRYPTO_ERROR_OBSERVED) { + VPRINTF(ERROR, "ERROR: Gen-in bad val\n"); + sts |= BAD_CPTRA_SIG; + test_progress_g[cur_test] = RUN_AND_FAILED; + } else { + sts |= SUCCESS; + test_progress_g[cur_test] = RUN_AND_PASSED; + } + + return sts; +} + uint32_t check_mbox_no_lock_error(enum mask_config test_mask) { enum test_list cur_test; uint32_t sts = 0; @@ -1142,7 +1210,8 @@ void nmi_handler (void) { while(1); } // NMI occurred, check if we had a fatal error - if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL) & (SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_ICCM_ECC_UNC_MASK | + if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL) & (SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK| + SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_ICCM_ECC_UNC_MASK | SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK)) { //Save generic_input_wires value before reset to compare later. This is to avoid flagging the toggle during reset as an error generic_input_wires_0_before_rst = lsu_read_32(CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0); @@ -1179,6 +1248,8 @@ void main(void) { // Setup the NMI Handler lsu_write_32((uintptr_t) (CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR), (uint32_t) (nmi_handler)); + VPRINTF(LOW, "Boot Count: %d\n", boot_count); + // Test Mailbox SRAM ECC if (boot_count == BEFORE_FIRST_ICCM_FAILURE) { test_mbox_sram_ecc(NO_MASK); @@ -1210,19 +1281,26 @@ void main(void) { run_nmi_test(WITH_MASK); } else if (boot_count == BEFORE_THIRD_NMI_FAILURE) { check_nmi_test(WITH_MASK); // Test NMI from Masked ICCM ECC through LSU - run_iccm_sram_ecc(WITH_MASK, FROM_LSU); } - else if (boot_count == AFTER_THIRD_NMI_FAILURE) { check_iccm_sram_ecc(WITH_MASK, FROM_LSU); } + run_iccm_sram_ecc(WITH_MASK, FROM_LSU); } + else if (boot_count == BEFORE_FIRST_CRYPTO_FAILURE) { check_iccm_sram_ecc(WITH_MASK, FROM_LSU); } // Test Mailbox Protocol Violations (no reset expected) - if (boot_count == AFTER_THIRD_NMI_FAILURE) { run_mbox_no_lock_error ( NO_MASK); - check_mbox_no_lock_error ( NO_MASK); - run_mbox_ooo_error ( NO_MASK); - check_mbox_ooo_error ( NO_MASK); - run_mbox_no_lock_error (WITH_MASK); - check_mbox_no_lock_error (WITH_MASK); - run_mbox_ooo_error (WITH_MASK); - check_mbox_ooo_error (WITH_MASK); } - + if (boot_count == BEFORE_FIRST_CRYPTO_FAILURE) { run_mbox_no_lock_error ( NO_MASK); + check_mbox_no_lock_error ( NO_MASK); + run_mbox_ooo_error ( NO_MASK); + check_mbox_ooo_error ( NO_MASK); + run_mbox_no_lock_error (WITH_MASK); + check_mbox_no_lock_error (WITH_MASK); + run_mbox_ooo_error (WITH_MASK); + check_mbox_ooo_error (WITH_MASK); } + // Test crypto error due to simultaneous use + if (boot_count == BEFORE_FIRST_CRYPTO_FAILURE) { run_crypto_error (CRYPTO_DOE_ECC); } + else if (boot_count == BEFORE_SECOND_CRYPTO_FAILURE) { check_crypto_error(CRYPTO_DOE_ECC); + run_crypto_error (CRYPTO_HMAC_DOE); } + else if (boot_count == BEFORE_THIRD_CRYPTO_FAILURE) { check_crypto_error(CRYPTO_HMAC_DOE); + run_crypto_error (CRYPTO_HMAC_ECC); } + else if (boot_count == AFTER_THIRD_CRYPTO_FAILURE) { check_crypto_error(CRYPTO_HMAC_ECC); } + // Final Report VPRINTF(MEDIUM, "Eval test progress...\n"); for (enum test_list tests = 0; tests < TEST_COUNT; tests++) { diff --git a/src/keyvault/rtl/kv.sv b/src/keyvault/rtl/kv.sv index e92ad0838..e83c476ce 100644 --- a/src/keyvault/rtl/kv.sv +++ b/src/keyvault/rtl/kv.sv @@ -78,6 +78,9 @@ kv_reg__out_t kv_reg_hwif_out; logic [KV_NUM_KEYS-1:0] key_entry_clear; +logic [$clog2(KV_NUM_WRITE)-1:0] kv_write_cnt; +logic kv_multi_write_err; + ahb_slv_sif #( .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), .AHB_DATA_WIDTH(AHB_DATA_WIDTH), @@ -127,6 +130,16 @@ always_comb begin : keyvault_pcr_signing end end +always_comb begin + kv_write_cnt = 0; + for (int client = 0; client < KV_NUM_WRITE; client++)begin + if (kv_write[client].write_en) + kv_write_cnt = kv_write_cnt + 'd1; + end +end + +always_comb kv_multi_write_err = kv_write_cnt > 1; + //Generate clear signal for each key entry //don't clear when writes are locked //hold the clear when writes are in progress @@ -137,7 +150,8 @@ generate key_entry_clear[g_entry] <= '0; end else begin - key_entry_clear[g_entry] <= (kv_reg_hwif_out.KEY_CTRL[g_entry].clear.value & ~lock_wr_q[g_entry] & ~lock_use_q[g_entry]) | + key_entry_clear[g_entry] <= kv_multi_write_err | + (kv_reg_hwif_out.KEY_CTRL[g_entry].clear.value & ~lock_wr_q[g_entry] & ~lock_use_q[g_entry]) | (key_entry_clear[g_entry] & key_entry_ctrl_we[g_entry]); end end diff --git a/src/keyvault/rtl/kv_def.rdl b/src/keyvault/rtl/kv_def.rdl index aa9b9308a..4e31bb807 100644 --- a/src/keyvault/rtl/kv_def.rdl +++ b/src/keyvault/rtl/kv_def.rdl @@ -63,7 +63,7 @@ field {desc = "Key Vault entry to store the result";} write_entry[KV_ENTRY_ADDRESS_W] = 0; field {desc = "HMAC KEY is a valid destination";} hmac_key_dest_valid = 0; field {desc = "HMAC BLOCK is a valid destination";} hmac_block_dest_valid = 0; - field {desc = "SHA BLOCK is a valid destination";} sha_block_dest_valid = 0; + field {desc = "Reserved field. No SHA key vault interface";} sha_block_dest_valid = 0; field {desc = "ECC PKEY is a valid destination";} ecc_pkey_dest_valid = 0; field {desc = "ECC SEED is a valid destination";} ecc_seed_dest_valid = 0; field {desc = "Reserved field";} rsvd[21] = 0; diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh index 9af627d82..5ad68879a 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh @@ -153,7 +153,7 @@ virtual task queue_writes(); gen_rand_entries(); std::randomize(wr_clients); - fork + // fork begin if (wr_clients[HMAC_WRITE]) begin `uvm_info("QUEUE_HMAC_WRITE", $sformatf("hmac write with entry = %h", hmac_write_entry), UVM_HIGH) @@ -182,7 +182,7 @@ virtual task queue_writes(); ecc_write_seq.start(configuration.kv_ecc_write_agent_config.sequencer); end end - join + // join configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh index 7e32d9da8..9bed226c1 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh @@ -137,7 +137,7 @@ class kv_wr_rd_cold_rst_sequence #( fork begin //Wait for reset to finish if rand write_id is not current client id - if(write_id != ECC) + // if(write_id != ECC) active_phase.wait_ptrigger; //Do the writes repeat(10) begin @@ -145,112 +145,154 @@ class kv_wr_rd_cold_rst_sequence #( ecc_write_seq.start(configuration.kv_ecc_write_agent_config.sequencer); end //Trigger event after writes are done - if(write_id == ECC) + // if(write_id == ECC) write_event.trigger; - end - begin - if(read_id != ECC_PRIVKEY) - active_phase.wait_ptrigger; + // end + // begin + // if(read_id != ECC_PRIVKEY) + // active_phase.wait_ptrigger; repeat(10) begin ecc_privkey_read_seq.start(configuration.kv_ecc_privkey_read_agent_config.sequencer); end - if(read_id == ECC_PRIVKEY) + // if(read_id == ECC_PRIVKEY) read_event.trigger; end - begin - if(write_id != DOE) - active_phase.wait_ptrigger; - repeat(10) begin - uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_doe_write_agent.sequencer.doe_write_seq", "local_write_entry",doe_write_entry); - doe_write_seq.start(configuration.kv_doe_write_agent_config.sequencer); + begin + // write_event.wait_ptrigger; + // read_event.wait_ptrigger; + kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); + if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin + active_phase.trigger; end - if(write_id == DOE) - write_event.trigger; - end - begin - if(write_id != SHA512) - active_phase.wait_ptrigger; + - repeat(10) begin - uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_sha512_write_agent.sequencer.sha512_write_seq", "local_write_entry",sha512_write_entry); - sha512_write_seq.start(configuration.kv_sha512_write_agent_config.sequencer); - end - if(write_id == SHA512) - write_event.trigger; - + join + + fork + begin + // if(write_id != DOE) + active_phase.wait_ptrigger; + + repeat(10) begin + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_doe_write_agent.sequencer.doe_write_seq", "local_write_entry",doe_write_entry); + doe_write_seq.start(configuration.kv_doe_write_agent_config.sequencer); end - begin - if(read_id != HMAC_BLOCK) - active_phase.wait_ptrigger; + // if(write_id == DOE) + write_event.trigger; + + end + begin + // write_event.wait_ptrigger; + // read_event.wait_ptrigger; + kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); + if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin + active_phase.trigger; + end + end + join + fork + begin + // if(write_id != SHA512) + active_phase.wait_ptrigger; - repeat(10) begin - hmac_block_read_seq.start(configuration.kv_hmac_block_read_agent_config.sequencer); - end - if(read_id == HMAC_BLOCK) - read_event.trigger; - + repeat(10) begin + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_sha512_write_agent.sequencer.sha512_write_seq", "local_write_entry",sha512_write_entry); + sha512_write_seq.start(configuration.kv_sha512_write_agent_config.sequencer); end - begin - if(write_id != HMAC) - active_phase.wait_ptrigger; + // if(write_id == SHA512) + write_event.trigger; + + // end + // begin + // if(read_id != HMAC_BLOCK) + // active_phase.wait_ptrigger; - repeat(10) begin - uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_entry",hmac_write_entry); - hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); - end - if(write_id == HMAC) - write_event.trigger; - + repeat(10) begin + hmac_block_read_seq.start(configuration.kv_hmac_block_read_agent_config.sequencer); end - begin - if(read_id != SHA512_BLOCK) - active_phase.wait_ptrigger; + // if(read_id == HMAC_BLOCK) + read_event.trigger; + + end + begin + // write_event.wait_ptrigger; + // read_event.wait_ptrigger; + kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); + if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin + active_phase.trigger; + end + end + join + fork + begin + // if(write_id != HMAC) + active_phase.wait_ptrigger; - repeat(10) begin - sha512_block_read_seq.start(configuration.kv_sha512_block_read_agent_config.sequencer); - end - if(read_id == SHA512_BLOCK) - read_event.trigger; + repeat(10) begin + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_entry",hmac_write_entry); + hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); + end + // if(write_id == HMAC) + write_event.trigger; + + // end + // begin + // if(read_id != SHA512_BLOCK) + // active_phase.wait_ptrigger; + repeat(10) begin + sha512_block_read_seq.start(configuration.kv_sha512_block_read_agent_config.sequencer); end - begin - if(read_id != HMAC_KEY) - active_phase.wait_ptrigger; + // if(read_id == SHA512_BLOCK) + read_event.trigger; - repeat(10) begin - hmac_key_read_seq.start(configuration.kv_hmac_key_read_agent_config.sequencer); - end - if(read_id == HMAC_KEY) - read_event.trigger; + end + begin + // write_event.wait_ptrigger; + // read_event.wait_ptrigger; + kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); + if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin + active_phase.trigger; end - begin - if(read_id != ECC_SEED) - active_phase.wait_ptrigger; + end + join + fork + begin + // if(read_id != HMAC_KEY) + active_phase.wait_ptrigger; - repeat(10) begin - ecc_seed_read_seq.start(configuration.kv_ecc_seed_read_agent_config.sequencer); - end - if(read_id == ECC_SEED) - read_event.trigger; - + repeat(10) begin + hmac_key_read_seq.start(configuration.kv_hmac_key_read_agent_config.sequencer); end - - begin - write_event.wait_ptrigger; - read_event.wait_ptrigger; - kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); - if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin - active_phase.trigger; - end + // if(read_id == HMAC_KEY) + read_event.trigger; + end + begin + // if(read_id != ECC_SEED) + active_phase.wait_ptrigger; + + repeat(10) begin + ecc_seed_read_seq.start(configuration.kv_ecc_seed_read_agent_config.sequencer); end + // if(read_id == ECC_SEED) + read_event.trigger; - + end + begin + // write_event.wait_ptrigger; + // read_event.wait_ptrigger; + kv_rst_agent_cold_rst_seq.start(configuration.kv_rst_agent_config.sequencer); + if(kv_rst_agent_cold_rst_seq.req.set_pwrgood && !kv_rst_agent_cold_rst_seq.req.assert_rst) begin + active_phase.trigger; + end + end join + active_phase.reset; configuration.kv_rst_agent_config.wait_for_num_clocks(1000); configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1000); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh index 114d7a2c0..cdca858c5 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh @@ -135,7 +135,7 @@ class kv_wr_rd_debug_lock_clear_rst_sequence #( //Set each CTRL reg with random lock data for(write_entry = 0; write_entry < KV_NUM_KEYS; write_entry++) begin // Construct the transaction - lock_data = 'h3; //$urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together + lock_data = $urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together //3 reg_model.kv_reg_rm.KEY_CTRL[write_entry].write(sts, lock_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); assert(sts == UVM_IS_OK) else `uvm_error("AHB_LOCK_SET", $sformatf("Failed when writing to KEY_CTRL[%d]",write_entry)) end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh index 7305ec891..91e3ab3c4 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh @@ -186,7 +186,7 @@ class kv_wr_rd_lock_sequence #( kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); else `uvm_error("KV_WR_RD_LOCK", "kv_rst_agent_config.sequencer is null!") - fork + // fork begin repeat(20) begin //Set each CTRL reg with random lock data @@ -212,9 +212,9 @@ class kv_wr_rd_lock_sequence #( configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); end - join + // join - fork + // fork begin repeat(20) begin //Set each CTRL reg with random lock data @@ -253,7 +253,7 @@ class kv_wr_rd_lock_sequence #( configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); end - join + // join endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh index 173f61e47..3b5eced6c 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh @@ -139,6 +139,7 @@ class kv_wr_rd_rst_sequence #( begin repeat(10) ecc_privkey_read_seq.start(configuration.kv_ecc_privkey_read_agent_config.sequencer); end + join begin if(reset_phase.is_on) begin active_phase.wait_ptrigger; @@ -149,6 +150,7 @@ class kv_wr_rd_rst_sequence #( doe_write_seq.start(configuration.kv_doe_write_agent_config.sequencer); end end + fork begin if(reset_phase.is_on) begin active_phase.wait_ptrigger; @@ -162,6 +164,8 @@ class kv_wr_rd_rst_sequence #( begin repeat(10) hmac_block_read_seq.start(configuration.kv_hmac_block_read_agent_config.sequencer); end + join + fork begin if(reset_phase.is_on) begin active_phase.wait_ptrigger; diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh index e12a1ac9f..9da9ca758 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh @@ -112,6 +112,7 @@ class kv_wr_rd_sequence #( else `uvm_error("KV WR RD", "kv_ecc_privkey_read_agent_config.sequencer is null!"); end + join begin if(configuration.kv_doe_write_agent_config.sequencer != null) repeat(10) begin @@ -121,6 +122,7 @@ class kv_wr_rd_sequence #( else `uvm_error("KV WR RD", "kv_doe_write_agent_config.sequencer is null!"); end + fork begin if(configuration.kv_sha512_write_agent_config.sequencer != null) repeat(10) begin @@ -136,6 +138,8 @@ class kv_wr_rd_sequence #( else `uvm_error("KV WR RD", "kv_hmac_block_read_agent_config.sequencer is null!"); end + join + fork begin if(configuration.kv_hmac_write_agent_config.sequencer != null) repeat(10) begin diff --git a/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv b/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv index 3d18b690c..be7cc84da 100755 --- a/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv +++ b/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv @@ -791,12 +791,16 @@ import soc_ifc_pkg::*; ); logic cptra_dmi_reg_en_jtag_acccess_allowed, cptra_dmi_reg_wr_en_jtag_acccess_allowed, cptra_jtag_access_allowed; - + logic veer_dmi_reg_en_jtag_acccess_allowed, veer_dmi_reg_wr_en_jtag_acccess_allowed, veer_jtag_access_allowed; + // reg enable towards core is not enabled unless it is equal to or less than 0x4F - as in 0x50 to 0x7F are not routed // Core tap reg aperture is 0x0 to 0x4F and uncore is 0x50 to 0x7F assign cptra_uncore_tap_aperture = (dmi_reg_addr[6] & (dmi_reg_addr[5] | dmi_reg_addr[4])); - // All JTAG accesses are blocked unless debug mode or manufacturing mode is enabled + // JTAG Accesses are permissable to VeeR aperture only when debug is unlocked + assign veer_jtag_access_allowed = ~(cptra_security_state_Latched.debug_locked); + + // Cptra JTAG accesses are blocked unless debug mode or manufacturing mode is enabled // JTAG access is allowed if Caliptra is in debug or manuf mode (driven by SOC security_state inputs) when caliptra reset is deasserted // Any change to debug or manuf mode bits after Caliptra reset is deasserted will keep JTAG locked. assign cptra_jtag_access_allowed = ~(cptra_security_state_Latched.debug_locked) | @@ -804,12 +808,16 @@ import soc_ifc_pkg::*; assign cptra_dmi_reg_en_jtag_acccess_allowed = dmi_reg_en_preQ & cptra_jtag_access_allowed; assign cptra_dmi_reg_wr_en_jtag_acccess_allowed = dmi_reg_wr_en_preQ & cptra_jtag_access_allowed; + + assign veer_dmi_reg_en_jtag_acccess_allowed = dmi_reg_en_preQ & veer_jtag_access_allowed; + assign veer_dmi_reg_wr_en_jtag_acccess_allowed = dmi_reg_wr_en_preQ & veer_jtag_access_allowed; + assign cptra_dmi_reg_en_preQ = dmi_reg_en_preQ; // Driving core vs uncore enables based on the right aperture - assign dmi_reg_en = cptra_uncore_tap_aperture ? '0 : cptra_dmi_reg_en_jtag_acccess_allowed; + assign dmi_reg_en = cptra_uncore_tap_aperture ? '0 : veer_dmi_reg_en_jtag_acccess_allowed; assign cptra_uncore_dmi_reg_en = cptra_uncore_tap_aperture ? cptra_dmi_reg_en_jtag_acccess_allowed : '0; - assign dmi_reg_wr_en = cptra_uncore_tap_aperture ? '0 : cptra_dmi_reg_wr_en_jtag_acccess_allowed; + assign dmi_reg_wr_en = cptra_uncore_tap_aperture ? '0 : veer_dmi_reg_wr_en_jtag_acccess_allowed; assign cptra_uncore_dmi_reg_wr_en = cptra_uncore_tap_aperture ? cptra_dmi_reg_wr_en_jtag_acccess_allowed : '0; // Qualified read data from core vs uncore diff --git a/src/sha512/rtl/sha512.sv b/src/sha512/rtl/sha512.sv index 04ffe38b4..4b68a835f 100644 --- a/src/sha512/rtl/sha512.sv +++ b/src/sha512/rtl/sha512.sv @@ -275,8 +275,9 @@ module sha512 hwif_in.SHA512_VERSION[0].VERSION.next = SHA512_CORE_VERSION0; hwif_in.SHA512_VERSION[1].VERSION.next = SHA512_CORE_VERSION1; - init_reg = gen_hash_ip ? gen_hash_init_reg : hwif_out.SHA512_CTRL.INIT.value; - next_reg = gen_hash_ip ? gen_hash_next_reg : hwif_out.SHA512_CTRL.NEXT.value; + //Mask commands when keyvault is busy to prevent runs with partial keys. + init_reg = gen_hash_ip ? gen_hash_init_reg : (hwif_out.SHA512_CTRL.INIT.value & kv_src_ready); + next_reg = gen_hash_ip ? gen_hash_next_reg : (hwif_out.SHA512_CTRL.NEXT.value & kv_src_ready); mode_reg = gen_hash_ip ? 2'b10 : hwif_out.SHA512_CTRL.MODE.value; zeroize_reg = hwif_out.SHA512_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; last_reg = gen_hash_ip ? gen_hash_last_reg : hwif_out.SHA512_CTRL.LAST.value; @@ -347,8 +348,9 @@ always_comb begin block_reg_lock_nxt[dword] = '0; end else begin + //Lock the block for any keyvault data block_reg_lock_nxt[dword] = (gen_hash_ip) ? '1 : - (pcr_hash_extend_ip & kv_src_write_en & (kv_src_write_offset == dword)) ? '1 : block_reg_lock[dword]; + (kv_src_write_en & (kv_src_write_offset == dword)) ? '1 : block_reg_lock[dword]; end end end @@ -388,10 +390,10 @@ assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; //Read Block -always_comb kv_read = ~pcr_hash_extend_ip ? vault_read : '0; +always_comb kv_read = '0; always_comb pv_read = gen_hash_ip ? gen_hash_pv_read : pcr_hash_extend_ip ? vault_read : '0; -always_comb vault_rd_resp = pcr_hash_extend_ip ? pv_rd_resp : kv_rd_resp; +always_comb vault_rd_resp = pv_rd_resp; kv_read_client #( .DATA_WIDTH(BLOCK_SIZE), @@ -421,14 +423,14 @@ sha512_block_kv_read ); -always_comb kv_write = ~pcr_hash_extend_ip ? vault_write : '0; +always_comb kv_write = '0; always_comb begin pv_write.write_data = pcr_hash_extend_ip ? vault_write.write_data : '0; pv_write.write_en = pcr_hash_extend_ip ? vault_write.write_en : '0; pv_write.write_entry = pcr_hash_extend_ip ? vault_write.write_entry : '0; pv_write.write_offset = pcr_hash_extend_ip ? vault_write.write_offset : '0; end -always_comb vault_wr_resp = pcr_hash_extend_ip ? pv_wr_resp : kv_wr_resp; +always_comb vault_wr_resp = pv_wr_resp; //during PCR hash extend overload write control //force write enable and always write to the source address that we read from diff --git a/src/soc_ifc/rtl/caliptra_top_reg.h b/src/soc_ifc/rtl/caliptra_top_reg.h index 790b71cb8..38a9ba7c7 100644 --- a/src/soc_ifc/rtl/caliptra_top_reg.h +++ b/src/soc_ifc/rtl/caliptra_top_reg.h @@ -128,6 +128,8 @@ #define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_MASK (0x2) #define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW (2) #define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK (0x4) +#define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW (3) +#define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK (0x8) #define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL (0x30030004) #define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL (0x4) #define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW (0) diff --git a/src/soc_ifc/rtl/caliptra_top_reg_defines.svh b/src/soc_ifc/rtl/caliptra_top_reg_defines.svh index 344d910ea..515b69f12 100644 --- a/src/soc_ifc/rtl/caliptra_top_reg_defines.svh +++ b/src/soc_ifc/rtl/caliptra_top_reg_defines.svh @@ -128,6 +128,8 @@ `define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_MASK (32'h2) `define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW (2) `define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK (32'h4) +`define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW (3) +`define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK (32'h8) `define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL (32'h30030004) `define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL (32'h4) `define GENERIC_AND_FUSE_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW (0) diff --git a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl index ef9714f38..a5fa87dba 100644 --- a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl +++ b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl @@ -27,6 +27,7 @@ reg { rw_rw_sticky_hw iccm_ecc_unc=0; /* Uncorrectable double-bit error in ICCM */ rw_rw_sticky_hw dccm_ecc_unc=0; /* Uncorrectable double-bit error in DCCM */ rw_rw_sticky_hw nmi_pin=0; /* Non-Maskable Interrupt due to WDT timeout */ + rw_rw_sticky_hw crypto_err=0; /* Crypto parallel operation error No Mask */ } CPTRA_HW_ERROR_FATAL; reg { name = "Hardware Error Non-Fatal"; diff --git a/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl b/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl index 7db011708..dcb906302 100644 --- a/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl +++ b/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl @@ -47,7 +47,7 @@ reg { reg { name = "FW Update Reset Wait Cycles"; - desc = "Control register to set the number of cycles for which FW update reset must be asserted. Default is 5. Max value is 255 (8 bit). + desc = "Control register to set the number of cycles for which FW update reset must be asserted. Minimum value is 5. Max value is 255 (8 bit). [br]Caliptra Access: RW [br]SOC Access: RO"; @@ -85,6 +85,7 @@ reg { rw_ro_hw mask_iccm_ecc_unc=0; /* Uncorrectable double-bit error in ICCM */ rw_ro_hw mask_dccm_ecc_unc=0; /* Uncorrectable double-bit error in DCCM */ rw_ro_hw mask_nmi_pin=0; /* Non-Maskable Interrupt due to WDT timeout */ + ro_ro mask_crypto_err=0; /* Crypto parallel operation error No Mask */ } internal_hw_error_fatal_mask; reg { name = "Hardware Error Non-Fatal Mask"; diff --git a/src/soc_ifc/rtl/soc_ifc_reg.sv b/src/soc_ifc/rtl/soc_ifc_reg.sv index 0fe3754c0..c69e98d54 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg.sv +++ b/src/soc_ifc/rtl/soc_ifc_reg.sv @@ -349,6 +349,10 @@ module soc_ifc_reg ( logic next; logic load_next; } nmi_pin; + struct packed{ + logic next; + logic load_next; + } crypto_err; } CPTRA_HW_ERROR_FATAL; struct packed{ struct packed{ @@ -1240,6 +1244,9 @@ module soc_ifc_reg ( struct packed{ logic value; } nmi_pin; + struct packed{ + logic value; + } crypto_err; } CPTRA_HW_ERROR_FATAL; struct packed{ struct packed{ @@ -1979,6 +1986,30 @@ module soc_ifc_reg ( end end assign hwif_out.CPTRA_HW_ERROR_FATAL.nmi_pin.value = field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_FATAL.crypto_err + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.next = next_c; + field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.load_next) begin + field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value <= field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_FATAL.crypto_err.value = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value; // Field: soc_ifc_reg.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock always_comb begin automatic logic [0:0] next_c; @@ -5745,7 +5776,8 @@ module soc_ifc_reg ( assign readback_array[0][0:0] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value : '0; assign readback_array[0][1:1] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value : '0; assign readback_array[0][2:2] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value : '0; - assign readback_array[0][31:3] = '0; + assign readback_array[0][3:3] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value : '0; + assign readback_array[0][31:4] = '0; assign readback_array[1][0:0] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value : '0; assign readback_array[1][1:1] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value : '0; assign readback_array[1][2:2] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value : '0; @@ -5881,7 +5913,8 @@ module soc_ifc_reg ( assign readback_array[141][0:0] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value : '0; assign readback_array[141][1:1] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value : '0; assign readback_array[141][2:2] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value : '0; - assign readback_array[141][31:3] = '0; + assign readback_array[141][3:3] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? 1'h0 : '0; + assign readback_array[141][31:4] = '0; assign readback_array[142][0:0] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value : '0; assign readback_array[142][1:1] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value : '0; assign readback_array[142][2:2] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value : '0; diff --git a/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh b/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh index 0b835415e..3fbdbf65e 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh +++ b/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh @@ -30,12 +30,14 @@ covergroup soc_ifc_reg__CPTRA_HW_ERROR_FATAL_fld_cg with function sample( input bit [1-1:0] iccm_ecc_unc, input bit [1-1:0] dccm_ecc_unc, - input bit [1-1:0] nmi_pin + input bit [1-1:0] nmi_pin, + input bit [1-1:0] crypto_err ); option.per_instance = 1; iccm_ecc_unc_cp : coverpoint iccm_ecc_unc; dccm_ecc_unc_cp : coverpoint dccm_ecc_unc; nmi_pin_cp : coverpoint nmi_pin; + crypto_err_cp : coverpoint crypto_err; endgroup @@ -1384,13 +1386,15 @@ covergroup soc_ifc_reg__internal_hw_error_fatal_mask_fld_cg with function sample( input bit [1-1:0] mask_iccm_ecc_unc, input bit [1-1:0] mask_dccm_ecc_unc, - input bit [1-1:0] mask_nmi_pin + input bit [1-1:0] mask_nmi_pin, + input bit [1-1:0] mask_crypto_err ); option.per_instance = 1; option.auto_bin_max = 64; mask_iccm_ecc_unc_cp : coverpoint mask_iccm_ecc_unc; mask_dccm_ecc_unc_cp : coverpoint mask_dccm_ecc_unc; mask_nmi_pin_cp : coverpoint mask_nmi_pin; + mask_crypto_err_cp : coverpoint mask_crypto_err {illegal_bins ro_value = {1};} endgroup diff --git a/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv b/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv index 5ed0446ca..d932b6fdb 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +++ b/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv @@ -15,6 +15,7 @@ package soc_ifc_reg_pkg; soc_ifc_reg__rw_rw_sticky_hw__in_t iccm_ecc_unc; soc_ifc_reg__rw_rw_sticky_hw__in_t dccm_ecc_unc; soc_ifc_reg__rw_rw_sticky_hw__in_t nmi_pin; + soc_ifc_reg__rw_rw_sticky_hw__in_t crypto_err; } soc_ifc_reg__CPTRA_HW_ERROR_FATAL__in_t; typedef struct packed{ @@ -477,6 +478,7 @@ package soc_ifc_reg_pkg; soc_ifc_reg__rw_rw_sticky_hw__out_t iccm_ecc_unc; soc_ifc_reg__rw_rw_sticky_hw__out_t dccm_ecc_unc; soc_ifc_reg__rw_rw_sticky_hw__out_t nmi_pin; + soc_ifc_reg__rw_rw_sticky_hw__out_t crypto_err; } soc_ifc_reg__CPTRA_HW_ERROR_FATAL__out_t; typedef struct packed{ diff --git a/src/soc_ifc/rtl/soc_ifc_reg_sample.svh b/src/soc_ifc/rtl/soc_ifc_reg_sample.svh index e677131de..a115f455c 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_sample.svh +++ b/src/soc_ifc/rtl/soc_ifc_reg_sample.svh @@ -27,9 +27,10 @@ foreach(iccm_ecc_unc_bit_cg[bt]) this.iccm_ecc_unc_bit_cg[bt].sample(data[0 + bt]); foreach(dccm_ecc_unc_bit_cg[bt]) this.dccm_ecc_unc_bit_cg[bt].sample(data[1 + bt]); foreach(nmi_pin_bit_cg[bt]) this.nmi_pin_bit_cg[bt].sample(data[2 + bt]); + foreach(crypto_err_bit_cg[bt]) this.crypto_err_bit_cg[bt].sample(data[3 + bt]); end if (get_coverage(UVM_CVR_FIELD_VALS)) begin - this.fld_cg.sample( data[0:0]/*iccm_ecc_unc*/ , data[1:1]/*dccm_ecc_unc*/ , data[2:2]/*nmi_pin*/ ); + this.fld_cg.sample( data[0:0]/*iccm_ecc_unc*/ , data[1:1]/*dccm_ecc_unc*/ , data[2:2]/*nmi_pin*/ , data[3:3]/*crypto_err*/ ); end endfunction @@ -38,9 +39,10 @@ foreach(iccm_ecc_unc_bit_cg[bt]) this.iccm_ecc_unc_bit_cg[bt].sample(iccm_ecc_unc.get_mirrored_value() >> bt); foreach(dccm_ecc_unc_bit_cg[bt]) this.dccm_ecc_unc_bit_cg[bt].sample(dccm_ecc_unc.get_mirrored_value() >> bt); foreach(nmi_pin_bit_cg[bt]) this.nmi_pin_bit_cg[bt].sample(nmi_pin.get_mirrored_value() >> bt); + foreach(crypto_err_bit_cg[bt]) this.crypto_err_bit_cg[bt].sample(crypto_err.get_mirrored_value() >> bt); end if (get_coverage(UVM_CVR_FIELD_VALS)) begin - this.fld_cg.sample( iccm_ecc_unc.get_mirrored_value() , dccm_ecc_unc.get_mirrored_value() , nmi_pin.get_mirrored_value() ); + this.fld_cg.sample( iccm_ecc_unc.get_mirrored_value() , dccm_ecc_unc.get_mirrored_value() , nmi_pin.get_mirrored_value() , crypto_err.get_mirrored_value() ); end endfunction @@ -1571,9 +1573,10 @@ foreach(mask_iccm_ecc_unc_bit_cg[bt]) this.mask_iccm_ecc_unc_bit_cg[bt].sample(data[0 + bt]); foreach(mask_dccm_ecc_unc_bit_cg[bt]) this.mask_dccm_ecc_unc_bit_cg[bt].sample(data[1 + bt]); foreach(mask_nmi_pin_bit_cg[bt]) this.mask_nmi_pin_bit_cg[bt].sample(data[2 + bt]); + foreach(mask_crypto_err_bit_cg[bt]) this.mask_crypto_err_bit_cg[bt].sample(data[3 + bt]); end if (get_coverage(UVM_CVR_FIELD_VALS)) begin - this.fld_cg.sample( data[0:0]/*mask_iccm_ecc_unc*/ , data[1:1]/*mask_dccm_ecc_unc*/ , data[2:2]/*mask_nmi_pin*/ ); + this.fld_cg.sample( data[0:0]/*mask_iccm_ecc_unc*/ , data[1:1]/*mask_dccm_ecc_unc*/ , data[2:2]/*mask_nmi_pin*/ , data[3:3]/*mask_crypto_err*/ ); end endfunction @@ -1582,9 +1585,10 @@ foreach(mask_iccm_ecc_unc_bit_cg[bt]) this.mask_iccm_ecc_unc_bit_cg[bt].sample(mask_iccm_ecc_unc.get_mirrored_value() >> bt); foreach(mask_dccm_ecc_unc_bit_cg[bt]) this.mask_dccm_ecc_unc_bit_cg[bt].sample(mask_dccm_ecc_unc.get_mirrored_value() >> bt); foreach(mask_nmi_pin_bit_cg[bt]) this.mask_nmi_pin_bit_cg[bt].sample(mask_nmi_pin.get_mirrored_value() >> bt); + foreach(mask_crypto_err_bit_cg[bt]) this.mask_crypto_err_bit_cg[bt].sample(mask_crypto_err.get_mirrored_value() >> bt); end if (get_coverage(UVM_CVR_FIELD_VALS)) begin - this.fld_cg.sample( mask_iccm_ecc_unc.get_mirrored_value() , mask_dccm_ecc_unc.get_mirrored_value() , mask_nmi_pin.get_mirrored_value() ); + this.fld_cg.sample( mask_iccm_ecc_unc.get_mirrored_value() , mask_dccm_ecc_unc.get_mirrored_value() , mask_nmi_pin.get_mirrored_value() , mask_crypto_err.get_mirrored_value() ); end endfunction diff --git a/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv b/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv index 532510d46..91e2a2bdf 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +++ b/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv @@ -13,10 +13,12 @@ package soc_ifc_reg_uvm; soc_ifc_reg__CPTRA_HW_ERROR_FATAL_bit_cg iccm_ecc_unc_bit_cg[1]; soc_ifc_reg__CPTRA_HW_ERROR_FATAL_bit_cg dccm_ecc_unc_bit_cg[1]; soc_ifc_reg__CPTRA_HW_ERROR_FATAL_bit_cg nmi_pin_bit_cg[1]; + soc_ifc_reg__CPTRA_HW_ERROR_FATAL_bit_cg crypto_err_bit_cg[1]; soc_ifc_reg__CPTRA_HW_ERROR_FATAL_fld_cg fld_cg; rand uvm_reg_field iccm_ecc_unc; rand uvm_reg_field dccm_ecc_unc; rand uvm_reg_field nmi_pin; + rand uvm_reg_field crypto_err; function new(string name = "soc_ifc_reg__CPTRA_HW_ERROR_FATAL"); super.new(name, 32, build_coverage(UVM_CVR_ALL)); @@ -34,10 +36,13 @@ package soc_ifc_reg_uvm; this.dccm_ecc_unc.configure(this, 1, 1, "W1C", 1, 'h0, 1, 1, 0); this.nmi_pin = new("nmi_pin"); this.nmi_pin.configure(this, 1, 2, "W1C", 1, 'h0, 1, 1, 0); + this.crypto_err = new("crypto_err"); + this.crypto_err.configure(this, 1, 3, "W1C", 1, 'h0, 1, 1, 0); if (has_coverage(UVM_CVR_REG_BITS)) begin foreach(iccm_ecc_unc_bit_cg[bt]) iccm_ecc_unc_bit_cg[bt] = new(); foreach(dccm_ecc_unc_bit_cg[bt]) dccm_ecc_unc_bit_cg[bt] = new(); foreach(nmi_pin_bit_cg[bt]) nmi_pin_bit_cg[bt] = new(); + foreach(crypto_err_bit_cg[bt]) crypto_err_bit_cg[bt] = new(); end if (has_coverage(UVM_CVR_FIELD_VALS)) fld_cg = new(); @@ -1923,10 +1928,12 @@ package soc_ifc_reg_uvm; soc_ifc_reg__internal_hw_error_fatal_mask_bit_cg mask_iccm_ecc_unc_bit_cg[1]; soc_ifc_reg__internal_hw_error_fatal_mask_bit_cg mask_dccm_ecc_unc_bit_cg[1]; soc_ifc_reg__internal_hw_error_fatal_mask_bit_cg mask_nmi_pin_bit_cg[1]; + soc_ifc_reg__internal_hw_error_fatal_mask_bit_cg mask_crypto_err_bit_cg[1]; soc_ifc_reg__internal_hw_error_fatal_mask_fld_cg fld_cg; rand uvm_reg_field mask_iccm_ecc_unc; rand uvm_reg_field mask_dccm_ecc_unc; rand uvm_reg_field mask_nmi_pin; + rand uvm_reg_field mask_crypto_err; function new(string name = "soc_ifc_reg__internal_hw_error_fatal_mask"); super.new(name, 32, build_coverage(UVM_CVR_ALL)); @@ -1944,10 +1951,13 @@ package soc_ifc_reg_uvm; this.mask_dccm_ecc_unc.configure(this, 1, 1, "RW", 0, 'h0, 1, 1, 0); this.mask_nmi_pin = new("mask_nmi_pin"); this.mask_nmi_pin.configure(this, 1, 2, "RW", 0, 'h0, 1, 1, 0); + this.mask_crypto_err = new("mask_crypto_err"); + this.mask_crypto_err.configure(this, 1, 3, "RO", 0, 'h0, 1, 1, 0); if (has_coverage(UVM_CVR_REG_BITS)) begin foreach(mask_iccm_ecc_unc_bit_cg[bt]) mask_iccm_ecc_unc_bit_cg[bt] = new(); foreach(mask_dccm_ecc_unc_bit_cg[bt]) mask_dccm_ecc_unc_bit_cg[bt] = new(); foreach(mask_nmi_pin_bit_cg[bt]) mask_nmi_pin_bit_cg[bt] = new(); + foreach(mask_crypto_err_bit_cg[bt]) mask_crypto_err_bit_cg[bt] = new(); end if (has_coverage(UVM_CVR_FIELD_VALS)) fld_cg = new(); diff --git a/src/soc_ifc/rtl/soc_ifc_top.sv b/src/soc_ifc/rtl/soc_ifc_top.sv index d51cc0bb5..b83b51fe9 100644 --- a/src/soc_ifc/rtl/soc_ifc_top.sv +++ b/src/soc_ifc/rtl/soc_ifc_top.sv @@ -117,6 +117,8 @@ module soc_ifc_top output logic rdc_clk_dis, output logic fw_update_rst_window, + input logic crypto_error, + //caliptra uncore jtag ports input logic cptra_uncore_dmi_reg_en, input logic cptra_uncore_dmi_reg_wr_en, @@ -913,16 +915,19 @@ wdt i_wdt ( // Write-enables for CPTRA_HW_ERROR_FATAL and CPTRA_HW_ERROR_NON_FATAL // Also calculate whether or not an unmasked event is being set, so we can // trigger the SOC interrupt signal +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .we = crypto_error; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we = rv_ecc_sts.cptra_iccm_ecc_double_error & ~fw_update_rst_window; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.we = rv_ecc_sts.cptra_dccm_ecc_double_error & ~fw_update_rst_window; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .we = nmi_intr; // Using we+next instead of hwset allows us to encode the reserved fields in some fashion // other than bit-hot in the future, if needed (e.g. we need to encode > 32 FATAL events) +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .next = 1'b1; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next = 1'b1; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next = 1'b1; always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .next = 1'b1; // Flag the write even if the field being written to is already set to 1 - this is a new occurrence of the error and should trigger a new interrupt -always_comb unmasked_hw_error_fatal_write = (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next) || +always_comb unmasked_hw_error_fatal_write = (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .we && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next) || (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next) || (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_nmi_pin .value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .next); diff --git a/src/soc_ifc/tb/soc_ifc_tb.sv b/src/soc_ifc/tb/soc_ifc_tb.sv index 46cd5641a..ff7898568 100644 --- a/src/soc_ifc/tb/soc_ifc_tb.sv +++ b/src/soc_ifc/tb/soc_ifc_tb.sv @@ -273,6 +273,7 @@ module soc_ifc_tb .nmi_vector(), .nmi_intr(), + .crypto_error('0), .iccm_lock(), .iccm_axs_blocked(1'b0), // MH. Tie off here unless need control diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv index dbc11dfbd..0dc5f4b5b 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv @@ -209,6 +209,7 @@ import uvmf_base_pkg_hdl::*; // NMI Vector .nmi_vector(cptra_status_agent_bus.nmi_vector), .nmi_intr(cptra_status_agent_bus.nmi_intr), + .crypto_error('0), // ICCM Lock .iccm_lock(cptra_status_agent_bus.iccm_lock), .iccm_axs_blocked(cptra_ctrl_agent_bus.iccm_axs_blocked),