diff --git a/.github/workflow_metadata/pr_hash b/.github/workflow_metadata/pr_hash index 5db49d192..f35bbcd6f 100644 --- a/.github/workflow_metadata/pr_hash +++ b/.github/workflow_metadata/pr_hash @@ -1 +1 @@ -4c8faff2f6d91d6196096aae143f7d81fc0b7dc5f38742cbe5398f2ecf7abd11327d51d29c1f95540503721dad790fd3 \ No newline at end of file +6c8e7c3d77cadcbbf3b13e4f0f6853df60f57395826819dfbfda73a1a14f4533e5ca20c786cbb1b2535b771c4ebfa2b4 \ No newline at end of file diff --git a/.github/workflow_metadata/pr_timestamp b/.github/workflow_metadata/pr_timestamp index 86776d79b..43814994f 100644 --- a/.github/workflow_metadata/pr_timestamp +++ b/.github/workflow_metadata/pr_timestamp @@ -1 +1 @@ -1730225605 \ No newline at end of file +1730243083 \ No newline at end of file diff --git a/src/integration/asserts/caliptra_top_sva.sv b/src/integration/asserts/caliptra_top_sva.sv index b8c0895ee..fde59d168 100644 --- a/src/integration/asserts/caliptra_top_sva.sv +++ b/src/integration/asserts/caliptra_top_sva.sv @@ -159,13 +159,6 @@ module caliptra_top_sva generate for(genvar dword = 0; dword < KV_NUM_DWORDS; dword++) begin - //sha512 block read - kv_sha512_block_r_flow: assert property ( - @(posedge `SVA_RDC_CLK) - $rose(`SHA512_PATH.kv_src_done & ~`SHA512_PATH.pcr_hash_extend_ip) && (dword < (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`SHA512_PATH.kv_read.read_entry].last_dword.value + 1)) |-> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`SHA512_PATH.kv_read.read_entry][dword].data.value == `SHA512_PATH.block_reg[dword]) - ) - else $display("SVA ERROR: SHA384 block mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`SHA512_PATH.kv_read.read_entry][dword].data.value, `SHA512_PATH.block_reg[dword]); - //sha512 digest write if (dword < SHA512_DIG_NUM_DWORDS) begin kv_sha512_digest_w_flow: assert property ( @@ -553,6 +546,13 @@ module caliptra_top_sva ) else $display("SVA ERROR: ECC VALID flag mismatch!"); + //SVA for SHA512 restore + sha512_restore_cmd: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA512_PATH.restore_reg |-> (`SHA512_PATH.next_reg && !`SHA512_PATH.init_reg) + ) + else $display("SVA ERROR: SHA512 restore is not valid!"); + //SVA for modular operations ecc_opa_input: assert property ( @(posedge `SVA_RDC_CLK) diff --git a/src/integration/rtl/caliptra_reg.h b/src/integration/rtl/caliptra_reg.h index 86e2cbb30..87ba5382a 100644 --- a/src/integration/rtl/caliptra_reg.h +++ b/src/integration/rtl/caliptra_reg.h @@ -3967,6 +3967,8 @@ #define SHA512_REG_SHA512_CTRL_ZEROIZE_MASK (0x10) #define SHA512_REG_SHA512_CTRL_LAST_LOW (5) #define SHA512_REG_SHA512_CTRL_LAST_MASK (0x20) +#define SHA512_REG_SHA512_CTRL_RESTORE_LOW (6) +#define SHA512_REG_SHA512_CTRL_RESTORE_MASK (0x40) #define CLP_SHA512_REG_SHA512_STATUS (0x10020018) #define SHA512_REG_SHA512_STATUS (0x18) #define SHA512_REG_SHA512_STATUS_READY_LOW (0) diff --git a/src/integration/rtl/caliptra_reg_defines.svh b/src/integration/rtl/caliptra_reg_defines.svh index 7bfdcc6cc..dfa60e88c 100644 --- a/src/integration/rtl/caliptra_reg_defines.svh +++ b/src/integration/rtl/caliptra_reg_defines.svh @@ -3967,6 +3967,8 @@ `define SHA512_REG_SHA512_CTRL_ZEROIZE_MASK (32'h10) `define SHA512_REG_SHA512_CTRL_LAST_LOW (5) `define SHA512_REG_SHA512_CTRL_LAST_MASK (32'h20) +`define SHA512_REG_SHA512_CTRL_RESTORE_LOW (6) +`define SHA512_REG_SHA512_CTRL_RESTORE_MASK (32'h40) `define CLP_SHA512_REG_SHA512_STATUS (32'h10020018) `define SHA512_REG_SHA512_STATUS (32'h18) `define SHA512_REG_SHA512_STATUS_READY_LOW (0) diff --git a/src/integration/rtl/caliptra_top.sv b/src/integration/rtl/caliptra_top.sv index 62d7b7949..6a7eac597 100755 --- a/src/integration/rtl/caliptra_top.sv +++ b/src/integration/rtl/caliptra_top.sv @@ -798,10 +798,6 @@ sha512_ctrl #( .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hresp), .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hreadyout), .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hrdata), - .kv_read (kv_read[2]), - .kv_write (kv_write[1]), - .kv_rd_resp (kv_rd_resp[2]), - .kv_wr_resp (kv_wr_resp[1]), .pv_read (pv_read), .pv_write (pv_write), .pv_rd_resp (pv_rd_resp), @@ -813,6 +809,9 @@ sha512_ctrl #( .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); +always_comb kv_read[2] = '0; +always_comb kv_write[1] = '0; + sha256_ctrl #( .AHB_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), .AHB_ADDR_WIDTH (`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA256)) diff --git a/src/integration/stimulus/L0_regression.yml b/src/integration/stimulus/L0_regression.yml index 8f933fc83..569105239 100644 --- a/src/integration/stimulus/L0_regression.yml +++ b/src/integration/stimulus/L0_regression.yml @@ -12,6 +12,7 @@ contents: - ../test_suites/smoke_test_mbox_byte_read/smoke_test_mbox_byte_read.yml - ../test_suites/smoke_test_mbox_cg/smoke_test_mbox_cg.yml - ../test_suites/smoke_test_sha512/smoke_test_sha512.yml + - ../test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.yml - ../test_suites/smoke_test_sha256/smoke_test_sha256.yml - ../test_suites/smoke_test_sha256_wntz/smoke_test_sha256_wntz.yml - ../test_suites/smoke_test_sha256_wntz_rand/smoke_test_sha256_wntz_rand.yml diff --git a/src/integration/test_suites/libs/sha512/sha512.c b/src/integration/test_suites/libs/sha512/sha512.c index ed6f07dd4..52f4e8bd4 100644 --- a/src/integration/test_suites/libs/sha512/sha512.c +++ b/src/integration/test_suites/libs/sha512/sha512.c @@ -190,4 +190,54 @@ void sha512_flow(sha512_io block, uint8_t mode, sha512_io digest){ offset++; } +} + +void sha512_restore_flow(sha512_io block, uint8_t mode, sha512_io restore_digest, sha512_io digest){ + volatile uint32_t * reg_ptr; + uint8_t offset; + uint8_t fail_cmd = 0x1; + uint32_t sha512_digest [16]; + + // wait for SHA to be ready + while((lsu_read_32(CLP_SHA512_REG_SHA512_STATUS) & SHA512_REG_SHA512_STATUS_READY_MASK) == 0); + + // Write SHA512 block + reg_ptr = (uint32_t*) CLP_SHA512_REG_SHA512_BLOCK_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_SHA512_REG_SHA512_BLOCK_31) { + *reg_ptr++ = block.data[offset++]; + } + + // Write SHA512 restore DIGEST + reg_ptr = (uint32_t*) CLP_SHA512_REG_SHA512_DIGEST_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_SHA512_REG_SHA512_DIGEST_15) { + *reg_ptr++ = restore_digest.data[offset++]; + } + + // Enable SHA512 core + VPRINTF(LOW, "Enable SHA512\n"); + lsu_write_32(CLP_SHA512_REG_SHA512_CTRL, SHA512_REG_SHA512_CTRL_NEXT_MASK | + SHA512_REG_SHA512_CTRL_RESTORE_MASK | + (mode << SHA512_REG_SHA512_CTRL_MODE_LOW) & SHA512_REG_SHA512_CTRL_MODE_MASK); + + // wait for SHA to be valid + wait_for_sha512_intr(); + + reg_ptr = (uint32_t *) CLP_SHA512_REG_SHA512_DIGEST_0; + printf("Load DIGEST data from SHA512\n"); + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_SHA512_REG_SHA512_DIGEST_15) { + sha512_digest[offset] = *reg_ptr; + if (sha512_digest[offset] != digest.data[offset]) { + printf("At offset [%d], sha_digest data mismatch!\n", offset); + printf("Actual data: 0x%x\n", sha512_digest[offset]); + printf("Expected data: 0x%x\n", digest.data[offset]); + printf("%c", fail_cmd); + while(1); + } + reg_ptr++; + offset++; + } + } \ No newline at end of file diff --git a/src/integration/test_suites/libs/sha512/sha512.h b/src/integration/test_suites/libs/sha512/sha512.h index c485f4222..1f9ffd26c 100644 --- a/src/integration/test_suites/libs/sha512/sha512.h +++ b/src/integration/test_suites/libs/sha512/sha512.h @@ -42,6 +42,7 @@ void sha_next_last(enum sha512_mode_e mode); void sha384_kvflow(uint8_t sha_kv_id, uint8_t store_to_kv, uint8_t digest_kv_id, uint32_t expected_digest[12]); void sha512_zeroize(); void sha512_flow(sha512_io block, uint8_t mode, sha512_io digest); +void sha512_restore_flow(sha512_io block, uint8_t mode, sha512_io restore_digest, sha512_io digest); //polls until sha512 is ready to be used inline void sha512_poll_ready() { diff --git a/src/integration/test_suites/smoke_test_sha512_restore/caliptra_isr.h b/src/integration/test_suites/smoke_test_sha512_restore/caliptra_isr.h new file mode 100644 index 000000000..0300e7ed7 --- /dev/null +++ b/src/integration/test_suites/smoke_test_sha512_restore/caliptra_isr.h @@ -0,0 +1,256 @@ +// 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; + uint32_t mldsa_error; + uint32_t mldsa_notif; + uint32_t axi_dma_error; + uint32_t axi_dma_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); + } +} + +inline void service_mldsa_error_intr() {return;} +inline void service_mldsa_notif_intr() {return;} +inline void service_axi_dma_error_intr() {return;} +inline void service_axi_dma_notif_intr() {return;} + + +#endif //CALIPTRA_ISR_H diff --git a/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.c b/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.c new file mode 100644 index 000000000..276326f14 --- /dev/null +++ b/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.c @@ -0,0 +1,263 @@ +// 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 +#include +#include "printf.h" +#include "sha512.h" + +#ifdef CPT_VERBOSITY + enum printf_verbosity verbosity_g = CPT_VERBOSITY; +#else + enum printf_verbosity verbosity_g = LOW; +#endif +volatile uint32_t* stdout = (uint32_t *)STDOUT; +volatile uint32_t intr_count = 0; + +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, + .sha512_error = 0, + .sha512_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, + .mldsa_error = 0, + .mldsa_notif = 0, + .axi_dma_error = 0, + .axi_dma_notif = 0, +}; + + +void main() { + + uint32_t block1_data[] = {0x61626364, + 0x65666768, + 0x62636465, + 0x66676869, + 0x63646566, + 0x6768696A, + 0x64656667, + 0x68696A6B, + 0x65666768, + 0x696A6B6C, + 0x66676869, + 0x6A6B6C6D, + 0x6768696A, + 0x6B6C6D6E, + 0x68696A6B, + 0x6C6D6E6F, + 0x696A6B6C, + 0x6D6E6F70, + 0x6A6B6C6D, + 0x6E6F7071, + 0x6B6C6D6E, + 0x6F707172, + 0x6C6D6E6F, + 0x70717273, + 0x6D6E6F70, + 0x71727374, + 0x6E6F7071, + 0x72737475, + 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, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000380 + }; + + uint32_t expected10_digest[] = {0x4319017A, + 0x2B706E69, + 0xCD4B0593, + 0x8BAE5E89, + 0x0186BF19, + 0x9F30AA95, + 0x6EF8B71D, + 0x2F810585, + 0xD787D676, + 0x4B20BDA2, + 0xA2601447, + 0x09736920, + 0x00EC057F, + 0x37D14B8E, + 0x06ADD5B5, + 0x0E671C72}; + + + uint32_t expected11_digest[] = {0x8E959B75, + 0xDAE313DA, + 0x8CF4F728, + 0x14FC143F, + 0x8F7779C6, + 0xEB9F7FA1, + 0x7299AEAD, + 0xB6889018, + 0x501D289E, + 0x4900F7E4, + 0x331B99DE, + 0xC4B5433A, + 0xC7D329EE, + 0xB6DD2654, + 0x5E96E55B, + 0x874BE909}; + + + + uint32_t block2_data[] = {0x61626380, + 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, + 0x00000018}; + + uint32_t expected2_digest[] = {0xDDAF35A1, + 0x93617ABA, + 0xCC417349, + 0xAE204131, + 0x12E6FA4E, + 0x89A97EA2, + 0x0A9EEEE6, + 0x4B55D39A, + 0x2192992A, + 0x274FC1A8, + 0x36BA3C23, + 0xA3FEEBBD, + 0x454D4423, + 0x643CE80E, + 0x2A9AC94F, + 0xA54CA49F}; + + // Entry message + VPRINTF(LOW, "----------------------------------\n"); + VPRINTF(LOW, " SHA512 Restore smoke test !!\n" ); + VPRINTF(LOW, "----------------------------------\n"); + + // Call interrupt init + init_interrupts(); + + sha512_io sha512_block; + sha512_io sha512_digest; + sha512_io sha512_intermediate_digest; + sha512_io sha512_final_digest; + + sha512_block.data_size = 32; + for (int i = 0; i < sha512_block.data_size; i++) + sha512_block.data[i] = block1_data[i]; + + sha512_intermediate_digest.data_size = 16; + for (int i = 0; i < sha512_intermediate_digest.data_size; i++) + sha512_intermediate_digest.data[i] = expected10_digest[i]; + + sha512_flow(sha512_block, SHA512_512_MODE, sha512_intermediate_digest); + sha512_zeroize(); + + + for (int i = 0; i < sha512_block.data_size; i++) + sha512_block.data[i] = block2_data[i]; + + sha512_digest.data_size = 16; + for (int i = 0; i < sha512_digest.data_size; i++) + sha512_digest.data[i] = expected2_digest[i]; + + sha512_flow(sha512_block, SHA512_512_MODE, sha512_digest); + sha512_zeroize(); + + for (int i = 0; i < sha512_block.data_size; i++) + sha512_block.data[i] = block1_data[32+i]; + + sha512_final_digest.data_size = 16; + for (int i = 0; i < sha512_final_digest.data_size; i++) + sha512_final_digest.data[i] = expected11_digest[i]; + + sha512_restore_flow(sha512_block, SHA512_512_MODE, sha512_intermediate_digest, sha512_final_digest); + + // Write 0xff to STDOUT for TB to terminate test. + SEND_STDOUT_CTRL( 0xff); + while(1); + +} diff --git a/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.yml b/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.yml new file mode 100755 index 000000000..0680d49f1 --- /dev/null +++ b/src/integration/test_suites/smoke_test_sha512_restore/smoke_test_sha512_restore.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_sha512_restore diff --git a/src/sha512/coverage/sha512_ctrl_cov_if.sv b/src/sha512/coverage/sha512_ctrl_cov_if.sv index 9484d5608..e9f969cac 100644 --- a/src/sha512/coverage/sha512_ctrl_cov_if.sv +++ b/src/sha512/coverage/sha512_ctrl_cov_if.sv @@ -26,6 +26,7 @@ interface sha512_ctrl_cov_if logic next; logic [1 : 0] mode; logic zeroize; + logic restore; logic ready; logic valid; @@ -39,6 +40,7 @@ interface sha512_ctrl_cov_if assign init = sha512_ctrl.sha512_inst.init_reg; assign next = sha512_ctrl.sha512_inst.next_reg; assign mode = sha512_ctrl.sha512_inst.mode_reg; + assign restore = sha512_ctrl.sha512_inst.restore_reg; assign zeroize = sha512_ctrl.sha512_inst.zeroize_reg; assign ready = sha512_ctrl.sha512_inst.ready_reg; assign valid = sha512_ctrl.sha512_inst.digest_valid_reg; @@ -57,6 +59,7 @@ interface sha512_ctrl_cov_if init_cp: coverpoint init; next_cp: coverpoint next; mode_cp: coverpoint mode; + restore_cp: coverpoint restore; zeroize_cp: coverpoint zeroize; ready_cp: coverpoint ready; valid_cp: coverpoint valid; @@ -78,6 +81,7 @@ interface sha512_ctrl_cov_if zeroize_pcr_cp: cross zeroize, gen_hash_start; zeroize_init_cp: cross zeroize, init; zeroize_next_cp: cross zeroize, next; + zeroize_restore_cp: cross zeroize, restore; endgroup diff --git a/src/sha512/rtl/sha512.sv b/src/sha512/rtl/sha512.sv index 4b68a835f..2f6af2b7a 100644 --- a/src/sha512/rtl/sha512.sv +++ b/src/sha512/rtl/sha512.sv @@ -63,12 +63,6 @@ module sha512 output wire [DATA_WIDTH-1 : 0] read_data, output wire err, - // KV interface - output kv_read_t kv_read, - output kv_write_t kv_write, - input kv_rd_resp_t kv_rd_resp, - input kv_wr_resp_t kv_wr_resp, - // PV interface output pv_read_t pv_read, output pv_write_t pv_write, @@ -87,6 +81,7 @@ module sha512 //---------------------------------------------------------------- reg init_reg; reg next_reg; + reg restore_reg; reg ready_reg; reg [1 : 0] mode_reg; logic zeroize_reg; @@ -107,7 +102,7 @@ module sha512 logic [KV_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] pcr_sign; logic pcr_sign_we; reg digest_valid_reg; - logic [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] get_mask; + logic digest_we; sha512_reg__in_t hwif_in; sha512_reg__out_t hwif_out; @@ -162,6 +157,7 @@ module sha512 wire [BLOCK_SIZE-1 : 0] core_block; wire [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] core_digest; wire core_digest_valid; + logic [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] restore_digest; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. @@ -193,9 +189,11 @@ module sha512 .init_cmd(init_reg), .next_cmd(next_reg), + .restore_cmd(restore_reg), .mode(mode_reg), .block_msg(core_block), + .restore_digest(restore_digest), .ready(core_ready), @@ -222,6 +220,7 @@ module sha512 pcr_hash_extend_ip <= '0; hash_extend_entry <= '0; kv_read_data_present <= '0; + digest_we <= '0; end else if (zeroize_reg) begin ready_reg <= '0; @@ -230,15 +229,20 @@ module sha512 kv_reg <= '0; pcr_sign_reg <= '0; kv_read_data_present <= '0; + digest_we <= '0; end else begin ready_reg <= core_ready; digest_valid_reg <= core_digest_valid; - if (core_digest_valid & ~digest_valid_reg & ~(dest_keyvault | kv_read_data_present)) - digest_reg <= core_digest & get_mask; + if (core_digest_valid & ~digest_valid_reg & ~(dest_keyvault | kv_read_data_present)) begin + digest_reg <= core_digest; + digest_we <= 1'b1; + end + else + digest_we <= '0; if (core_digest_valid & ~digest_valid_reg & (dest_keyvault | kv_read_data_present)) - kv_reg <= core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS] & get_mask[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS]; + kv_reg <= core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS]; if (pcr_sign_we) pcr_sign_reg <= pcr_sign; @@ -251,19 +255,9 @@ module sha512 end end // reg_update - always_comb begin - unique case (mode_reg) - 2'b00 : get_mask = {{7{32'hffffffff}}, {9{32'h00000000}}}; //SHA512/224 - 2'b01 : get_mask = {{8{32'hffffffff}}, {8{32'h00000000}}}; //SHA512/256 - 2'b10 : get_mask = {{12{32'hffffffff}}, {4{32'h00000000}}}; //SHA384 - default : get_mask = {16{32'hffffffff}}; //SHA512 - endcase - end - - always_comb begin pcr_sign_we = (dest_data_avail & gen_hash_ip); - pcr_sign = core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS] & get_mask[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS]; + pcr_sign = core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-KV_NUM_DWORDS]; end //register hw interface @@ -278,6 +272,7 @@ module sha512 //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); + restore_reg = gen_hash_ip ? '0 : (hwif_out.SHA512_CTRL.RESTORE.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; @@ -288,6 +283,8 @@ module sha512 //output comes in big endian for (int dword =0; dword < DIG_NUM_DWORDS; dword++) begin + restore_digest[dword] = hwif_out.SHA512_DIGEST[(DIG_NUM_DWORDS-1)-dword].DIGEST.value; + hwif_in.SHA512_DIGEST[dword].DIGEST.we = zeroize_reg? 0 : digest_we; hwif_in.SHA512_DIGEST[dword].DIGEST.next = digest_reg[(DIG_NUM_DWORDS-1)-dword]; hwif_in.SHA512_DIGEST[dword].DIGEST.hwclr = zeroize_reg; end @@ -390,7 +387,6 @@ 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 = '0; always_comb pv_read = gen_hash_ip ? gen_hash_pv_read : pcr_hash_extend_ip ? vault_read : '0; always_comb vault_rd_resp = pv_rd_resp; @@ -423,7 +419,6 @@ sha512_block_kv_read ); -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; diff --git a/src/sha512/rtl/sha512_core.v b/src/sha512/rtl/sha512_core.v index 2b174f355..c4553bb04 100644 --- a/src/sha512/rtl/sha512_core.v +++ b/src/sha512/rtl/sha512_core.v @@ -45,10 +45,12 @@ module sha512_core( // Control. input wire init_cmd, input wire next_cmd, + input wire restore_cmd, input wire [1 : 0] mode, // Data port. input wire [1023 : 0] block_msg, + input wire [511 : 0] restore_digest, output wire ready, output wire [511 : 0] digest, @@ -134,6 +136,7 @@ module sha512_core( reg state_update; reg first_block; + reg restore; reg [63 : 0] t1; reg [63 : 0] t2; @@ -327,6 +330,18 @@ module sha512_core( H7_new = H0_7; H_we = 1; end + else if (restore) + begin + H0_new = restore_digest[511 : 448]; + H1_new = restore_digest[447 : 384]; + H2_new = restore_digest[383 : 320]; + H3_new = restore_digest[319 : 256]; + H4_new = restore_digest[255 : 192]; + H5_new = restore_digest[191 : 128]; + H6_new = restore_digest[127 : 64]; + H7_new = restore_digest[63 : 0]; + H_we = 1; + end if (digest_update) begin @@ -415,6 +430,18 @@ module sha512_core( h_new = H0_7; a_h_we = 1; end + else if (restore) + begin + a_new = restore_digest[511 : 448]; + b_new = restore_digest[447 : 384]; + c_new = restore_digest[383 : 320]; + d_new = restore_digest[319 : 256]; + e_new = restore_digest[255 : 192]; + f_new = restore_digest[191 : 128]; + g_new = restore_digest[127 : 64]; + h_new = restore_digest[63 : 0]; + a_h_we = 1; + end else begin a_new = H0_reg; @@ -491,6 +518,7 @@ module sha512_core( ready_we = 1'b0; sha512_ctrl_new = CTRL_IDLE; sha512_ctrl_we = 1'b0; + restore = 1'b0; unique case (sha512_ctrl_reg) CTRL_IDLE: @@ -521,6 +549,7 @@ module sha512_core( digest_valid_we = 1; sha512_ctrl_new = CTRL_ROUNDS; sha512_ctrl_we = 1; + restore = restore_cmd; end end diff --git a/src/sha512/rtl/sha512_ctrl.sv b/src/sha512/rtl/sha512_ctrl.sv index 882549852..e21d3ba13 100644 --- a/src/sha512/rtl/sha512_ctrl.sv +++ b/src/sha512/rtl/sha512_ctrl.sv @@ -49,12 +49,6 @@ module sha512_ctrl output logic hreadyout_o, output logic [AHB_DATA_WIDTH-1:0] hrdata_o, - // kv interface - output kv_read_t kv_read, - output kv_write_t kv_write, - input kv_rd_resp_t kv_rd_resp, - input kv_wr_resp_t kv_wr_resp, - // pcr vault interface output pv_read_t pv_read, output pv_write_t pv_write, @@ -92,10 +86,6 @@ module sha512_ctrl .write_data(sha512_write_data), .read_data(sha512_read_data), .err(sha512_err), - .kv_read(kv_read), - .kv_write(kv_write), - .kv_rd_resp(kv_rd_resp), - .kv_wr_resp(kv_wr_resp), .pv_read(pv_read), .pv_write(pv_write), .pv_rd_resp(pv_rd_resp), diff --git a/src/sha512/rtl/sha512_reg.rdl b/src/sha512/rtl/sha512_reg.rdl index 8b18fe9bc..37de81bae 100644 --- a/src/sha512/rtl/sha512_reg.rdl +++ b/src/sha512/rtl/sha512_reg.rdl @@ -84,6 +84,10 @@ addrmap sha512_reg { hardware interface and then will be erased"; singlepulse;} ZEROIZE = 1'b0; field {desc = "Indicates last iteration for keyvault or hash extend function. Result of this INIT or NEXT cycle will be written back to the appropriate vault"; hwclr;} LAST = 1'b0; + field {desc = "Control restore command bit: Restore SHA512 core to use the given digest to continue the + processing for the remining padded message block. + [br] Software write generates only a single-cycle pulse on the + hardware interface and then will be erased"; singlepulse;} RESTORE = 1'b0; } SHA512_CTRL @0x00000010; @@ -122,8 +126,9 @@ addrmap sha512_reg { desc = "SHA512 component digest register type definition 16 32-bit registers storing the 512-bit digest output in big-endian representation."; - default sw = r; - default hw = w; + default sw = rw; + default hw = rw; + default we = true; default resetsignal = reset_b; field {desc = "Output digest field"; hwclr;} DIGEST[32] = 32'b0; diff --git a/src/sha512/rtl/sha512_reg.sv b/src/sha512/rtl/sha512_reg.sv index 3f893839f..3d7b4622a 100644 --- a/src/sha512/rtl/sha512_reg.sv +++ b/src/sha512/rtl/sha512_reg.sv @@ -187,6 +187,10 @@ module sha512_reg ( logic next; logic load_next; } LAST; + struct packed{ + logic next; + logic load_next; + } RESTORE; } SHA512_CTRL; struct packed{ struct packed{ @@ -484,6 +488,9 @@ module sha512_reg ( struct packed{ logic value; } LAST; + struct packed{ + logic value; + } RESTORE; } SHA512_CTRL; struct packed{ struct packed{ @@ -812,6 +819,30 @@ module sha512_reg ( end end assign hwif_out.SHA512_CTRL.LAST.value = field_storage.SHA512_CTRL.LAST.value; + // Field: sha512_reg.SHA512_CTRL.RESTORE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.RESTORE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA512_CTRL.RESTORE.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.RESTORE.next = next_c; + field_combo.SHA512_CTRL.RESTORE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.RESTORE.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.RESTORE.load_next) begin + field_storage.SHA512_CTRL.RESTORE.value <= field_combo.SHA512_CTRL.RESTORE.next; + end + end + assign hwif_out.SHA512_CTRL.RESTORE.value = field_storage.SHA512_CTRL.RESTORE.value; for(genvar i0=0; i0<32; i0++) begin // Field: sha512_reg.SHA512_BLOCK[].BLOCK always_comb begin @@ -848,12 +879,15 @@ module sha512_reg ( automatic logic load_next_c; next_c = field_storage.SHA512_DIGEST[i0].DIGEST.value; load_next_c = '0; - if(hwif_in.SHA512_DIGEST[i0].DIGEST.hwclr) begin // HW Clear - next_c = '0; + if(decoded_reg_strb.SHA512_DIGEST[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA512_DIGEST[i0].DIGEST.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); load_next_c = '1; - end else begin // HW Write + end else if(hwif_in.SHA512_DIGEST[i0].DIGEST.we) begin // HW Write - we next_c = hwif_in.SHA512_DIGEST[i0].DIGEST.next; load_next_c = '1; + end else if(hwif_in.SHA512_DIGEST[i0].DIGEST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; end field_combo.SHA512_DIGEST[i0].DIGEST.next = next_c; field_combo.SHA512_DIGEST[i0].DIGEST.load_next = load_next_c; @@ -865,6 +899,7 @@ module sha512_reg ( field_storage.SHA512_DIGEST[i0].DIGEST.value <= field_combo.SHA512_DIGEST[i0].DIGEST.next; end end + assign hwif_out.SHA512_DIGEST[i0].DIGEST.value = field_storage.SHA512_DIGEST[i0].DIGEST.value; end // Field: sha512_reg.SHA512_VAULT_RD_CTRL.read_en always_comb begin diff --git a/src/sha512/rtl/sha512_reg_pkg.sv b/src/sha512/rtl/sha512_reg_pkg.sv index d5a980dd8..af94a2b61 100644 --- a/src/sha512/rtl/sha512_reg_pkg.sv +++ b/src/sha512/rtl/sha512_reg_pkg.sv @@ -56,6 +56,7 @@ package sha512_reg_pkg; typedef struct packed{ logic [31:0] next; + logic we; logic hwclr; } sha512_reg__SHA512_DIGEST__DIGEST__in_t; @@ -195,12 +196,17 @@ package sha512_reg_pkg; logic value; } sha512_reg__SHA512_CTRL__LAST__out_t; + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__RESTORE__out_t; + typedef struct packed{ sha512_reg__SHA512_CTRL__INIT__out_t INIT; sha512_reg__SHA512_CTRL__NEXT__out_t NEXT; sha512_reg__SHA512_CTRL__MODE__out_t MODE; sha512_reg__SHA512_CTRL__ZEROIZE__out_t ZEROIZE; sha512_reg__SHA512_CTRL__LAST__out_t LAST; + sha512_reg__SHA512_CTRL__RESTORE__out_t RESTORE; } sha512_reg__SHA512_CTRL__out_t; typedef struct packed{ @@ -211,6 +217,14 @@ package sha512_reg_pkg; sha512_reg__SHA512_BLOCK__BLOCK__out_t BLOCK; } sha512_reg__SHA512_BLOCK__out_t; + typedef struct packed{ + logic [31:0] value; + } sha512_reg__SHA512_DIGEST__DIGEST__out_t; + + typedef struct packed{ + sha512_reg__SHA512_DIGEST__DIGEST__out_t DIGEST; + } sha512_reg__SHA512_DIGEST__out_t; + typedef struct packed{ logic value; } kv_read_ctrl_reg__read_en__out_t; @@ -319,6 +333,7 @@ package sha512_reg_pkg; typedef struct packed{ sha512_reg__SHA512_CTRL__out_t SHA512_CTRL; sha512_reg__SHA512_BLOCK__out_t [32-1:0]SHA512_BLOCK; + sha512_reg__SHA512_DIGEST__out_t [16-1:0]SHA512_DIGEST; kv_read_ctrl_reg__out_t SHA512_VAULT_RD_CTRL; kv_write_ctrl_reg__out_t SHA512_KV_WR_CTRL; sha512_reg__SHA512_GEN_PCR_HASH_NONCE__out_t [8-1:0]SHA512_GEN_PCR_HASH_NONCE; diff --git a/src/sha512/rtl/sha512_reg_uvm.sv b/src/sha512/rtl/sha512_reg_uvm.sv index 3e6d35748..e7317ea27 100644 --- a/src/sha512/rtl/sha512_reg_uvm.sv +++ b/src/sha512/rtl/sha512_reg_uvm.sv @@ -75,12 +75,14 @@ package sha512_reg_uvm; sha512_reg__SHA512_CTRL_bit_cg MODE_bit_cg[2]; sha512_reg__SHA512_CTRL_bit_cg ZEROIZE_bit_cg[1]; sha512_reg__SHA512_CTRL_bit_cg LAST_bit_cg[1]; + sha512_reg__SHA512_CTRL_bit_cg RESTORE_bit_cg[1]; sha512_reg__SHA512_CTRL_fld_cg fld_cg; rand uvm_reg_field INIT; rand uvm_reg_field NEXT; rand uvm_reg_field MODE; rand uvm_reg_field ZEROIZE; rand uvm_reg_field LAST; + rand uvm_reg_field RESTORE; function new(string name = "sha512_reg__SHA512_CTRL"); super.new(name, 32, build_coverage(UVM_CVR_ALL)); @@ -102,12 +104,15 @@ package sha512_reg_uvm; this.ZEROIZE.configure(this, 1, 4, "WO", 0, 'h0, 1, 1, 0); this.LAST = new("LAST"); this.LAST.configure(this, 1, 5, "WO", 1, 'h0, 1, 1, 0); + this.RESTORE = new("RESTORE"); + this.RESTORE.configure(this, 1, 6, "WO", 0, 'h0, 1, 1, 0); if (has_coverage(UVM_CVR_REG_BITS)) begin foreach(INIT_bit_cg[bt]) INIT_bit_cg[bt] = new(); foreach(NEXT_bit_cg[bt]) NEXT_bit_cg[bt] = new(); foreach(MODE_bit_cg[bt]) MODE_bit_cg[bt] = new(); foreach(ZEROIZE_bit_cg[bt]) ZEROIZE_bit_cg[bt] = new(); foreach(LAST_bit_cg[bt]) LAST_bit_cg[bt] = new(); + foreach(RESTORE_bit_cg[bt]) RESTORE_bit_cg[bt] = new(); end if (has_coverage(UVM_CVR_FIELD_VALS)) fld_cg = new(); @@ -200,7 +205,7 @@ package sha512_reg_uvm; virtual function void build(); this.DIGEST = new("DIGEST"); - this.DIGEST.configure(this, 32, 0, "RO", 1, 'h0, 1, 1, 0); + this.DIGEST.configure(this, 32, 0, "RW", 1, 'h0, 1, 1, 0); if (has_coverage(UVM_CVR_REG_BITS)) begin foreach(DIGEST_bit_cg[bt]) DIGEST_bit_cg[bt] = new(); end diff --git a/src/sha512/tb/sha512_ctrl_32bit_tb.sv b/src/sha512/tb/sha512_ctrl_32bit_tb.sv index adc8ddc1e..f49058ae5 100644 --- a/src/sha512/tb/sha512_ctrl_32bit_tb.sv +++ b/src/sha512/tb/sha512_ctrl_32bit_tb.sv @@ -21,6 +21,8 @@ // //====================================================================== +`include "caliptra_reg_defines.svh" + module sha512_ctrl_32bit_tb import kv_defines_pkg::*; import pv_defines_pkg::*; @@ -34,84 +36,15 @@ module sha512_ctrl_32bit_tb parameter CLK_HALF_PERIOD = 1; parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; - // The address map. - parameter BASE_ADDR = 32'h40000000; - - parameter ADDR_NAME0 = BASE_ADDR + 32'h00000000; - parameter ADDR_NAME1 = BASE_ADDR + 32'h00000004; - parameter ADDR_VERSION0 = BASE_ADDR + 32'h00000008; - parameter ADDR_VERSION1 = BASE_ADDR + 32'h0000000c; - - parameter ADDR_CTRL = BASE_ADDR + 32'h00000010; - parameter CTRL_INIT_BIT = 0; - parameter CTRL_NEXT_BIT = 1; - parameter CTRL_MODE_LOW_BIT = 2; - parameter CTRL_MODE_HIGH_BIT = 3; - parameter CTRL_WORK_FACTOR_BIT = 7; - - parameter ADDR_STATUS = BASE_ADDR + 32'h00000018; - parameter STATUS_READY_BIT = 0; - parameter STATUS_VALID_BIT = 1; - - parameter ADDR_WORK_FACTOR_NUM = BASE_ADDR + 32'h00000020; - - parameter ADDR_BLOCK0 = BASE_ADDR + 32'h00000080; - parameter ADDR_BLOCK1 = BASE_ADDR + 32'h00000084; - parameter ADDR_BLOCK2 = BASE_ADDR + 32'h00000088; - parameter ADDR_BLOCK3 = BASE_ADDR + 32'h0000008c; - parameter ADDR_BLOCK4 = BASE_ADDR + 32'h00000090; - parameter ADDR_BLOCK5 = BASE_ADDR + 32'h00000094; - parameter ADDR_BLOCK6 = BASE_ADDR + 32'h00000098; - parameter ADDR_BLOCK7 = BASE_ADDR + 32'h0000009c; - parameter ADDR_BLOCK8 = BASE_ADDR + 32'h000000a0; - parameter ADDR_BLOCK9 = BASE_ADDR + 32'h000000a4; - parameter ADDR_BLOCK10 = BASE_ADDR + 32'h000000a8; - parameter ADDR_BLOCK11 = BASE_ADDR + 32'h000000ac; - parameter ADDR_BLOCK12 = BASE_ADDR + 32'h000000b0; - parameter ADDR_BLOCK13 = BASE_ADDR + 32'h000000b4; - parameter ADDR_BLOCK14 = BASE_ADDR + 32'h000000b8; - parameter ADDR_BLOCK15 = BASE_ADDR + 32'h000000bc; - parameter ADDR_BLOCK16 = BASE_ADDR + 32'h000000c0; - parameter ADDR_BLOCK17 = BASE_ADDR + 32'h000000c4; - parameter ADDR_BLOCK18 = BASE_ADDR + 32'h000000c8; - parameter ADDR_BLOCK19 = BASE_ADDR + 32'h000000cc; - parameter ADDR_BLOCK20 = BASE_ADDR + 32'h000000d0; - parameter ADDR_BLOCK21 = BASE_ADDR + 32'h000000d4; - parameter ADDR_BLOCK22 = BASE_ADDR + 32'h000000d8; - parameter ADDR_BLOCK23 = BASE_ADDR + 32'h000000dc; - parameter ADDR_BLOCK24 = BASE_ADDR + 32'h000000e0; - parameter ADDR_BLOCK25 = BASE_ADDR + 32'h000000e4; - parameter ADDR_BLOCK26 = BASE_ADDR + 32'h000000e8; - parameter ADDR_BLOCK27 = BASE_ADDR + 32'h000000ec; - parameter ADDR_BLOCK28 = BASE_ADDR + 32'h000000f0; - parameter ADDR_BLOCK29 = BASE_ADDR + 32'h000000f4; - parameter ADDR_BLOCK30 = BASE_ADDR + 32'h000000f8; - parameter ADDR_BLOCK31 = BASE_ADDR + 32'h000000fc; - - parameter ADDR_DIGEST0 = BASE_ADDR + 32'h00000100; - parameter ADDR_DIGEST1 = BASE_ADDR + 32'h00000104; - parameter ADDR_DIGEST2 = BASE_ADDR + 32'h00000108; - parameter ADDR_DIGEST3 = BASE_ADDR + 32'h0000010c; - parameter ADDR_DIGEST4 = BASE_ADDR + 32'h00000110; - parameter ADDR_DIGEST5 = BASE_ADDR + 32'h00000114; - parameter ADDR_DIGEST6 = BASE_ADDR + 32'h00000118; - parameter ADDR_DIGEST7 = BASE_ADDR + 32'h0000011c; - parameter ADDR_DIGEST8 = BASE_ADDR + 32'h00000120; - parameter ADDR_DIGEST9 = BASE_ADDR + 32'h00000124; - parameter ADDR_DIGEST10 = BASE_ADDR + 32'h00000128; - parameter ADDR_DIGEST11 = BASE_ADDR + 32'h0000012c; - parameter ADDR_DIGEST12 = BASE_ADDR + 32'h00000130; - parameter ADDR_DIGEST13 = BASE_ADDR + 32'h00000134; - parameter ADDR_DIGEST14 = BASE_ADDR + 32'h00000138; - parameter ADDR_DIGEST15 = BASE_ADDR + 32'h0000013c; - parameter MODE_SHA_512_224 = 2'h0; parameter MODE_SHA_512_256 = 2'h1; parameter MODE_SHA_384 = 2'h2; parameter MODE_SHA_512 = 2'h3; - parameter CTRL_INIT_VALUE = 2'h1; - parameter CTRL_NEXT_VALUE = 2'h2; + parameter INIT_CMD = (1 << `SHA512_REG_SHA512_CTRL_INIT_LOW) & (`SHA512_REG_SHA512_CTRL_INIT_MASK); + parameter NEXT_CMD = (1 << `SHA512_REG_SHA512_CTRL_NEXT_LOW) & (`SHA512_REG_SHA512_CTRL_NEXT_MASK); + parameter RESTORE_CMD = (1 << `SHA512_REG_SHA512_CTRL_RESTORE_LOW) & (`SHA512_REG_SHA512_CTRL_RESTORE_MASK); + parameter ZEROIZE_CMD = (1 << `SHA512_REG_SHA512_CTRL_ZEROIZE_LOW) & (`SHA512_REG_SHA512_CTRL_ZEROIZE_MASK); parameter AHB_HTRANS_IDLE = 0; parameter AHB_HTRANS_BUSY = 1; @@ -312,7 +245,7 @@ module sha512_ctrl_32bit_tb while (read_data == 0) begin - read_single_word(ADDR_STATUS); + read_single_word(`SHA512_REG_SHA512_STATUS); end end endtask // wait_ready @@ -375,41 +308,51 @@ module sha512_ctrl_32bit_tb //---------------------------------------------------------------- task write_block(input [1023 : 0] block); begin - write_single_word(ADDR_BLOCK0, block[1023 : 992]); - write_single_word(ADDR_BLOCK1, block[991 : 960]); - write_single_word(ADDR_BLOCK2, block[959 : 928]); - write_single_word(ADDR_BLOCK3, block[927 : 896]); - write_single_word(ADDR_BLOCK4, block[895 : 864]); - write_single_word(ADDR_BLOCK5, block[863 : 832]); - write_single_word(ADDR_BLOCK6, block[831 : 800]); - write_single_word(ADDR_BLOCK7, block[799 : 768]); - write_single_word(ADDR_BLOCK8, block[767 : 736]); - write_single_word(ADDR_BLOCK9, block[735 : 704]); - write_single_word(ADDR_BLOCK10, block[703 : 672]); - write_single_word(ADDR_BLOCK11, block[671 : 640]); - write_single_word(ADDR_BLOCK12, block[639 : 608]); - write_single_word(ADDR_BLOCK13, block[607 : 576]); - write_single_word(ADDR_BLOCK14, block[575 : 544]); - write_single_word(ADDR_BLOCK15, block[543 : 512]); - write_single_word(ADDR_BLOCK16, block[511 : 480]); - write_single_word(ADDR_BLOCK17, block[479 : 448]); - write_single_word(ADDR_BLOCK18, block[447 : 416]); - write_single_word(ADDR_BLOCK19, block[415 : 384]); - write_single_word(ADDR_BLOCK20, block[383 : 352]); - write_single_word(ADDR_BLOCK21, block[351 : 320]); - write_single_word(ADDR_BLOCK22, block[319 : 288]); - write_single_word(ADDR_BLOCK23, block[287 : 256]); - write_single_word(ADDR_BLOCK24, block[255 : 224]); - write_single_word(ADDR_BLOCK25, block[223 : 192]); - write_single_word(ADDR_BLOCK26, block[191 : 160]); - write_single_word(ADDR_BLOCK27, block[159 : 128]); - write_single_word(ADDR_BLOCK28, block[127 : 96]); - write_single_word(ADDR_BLOCK29, block[95 : 64]); - write_single_word(ADDR_BLOCK30, block[63 : 32]); - write_single_word(ADDR_BLOCK31, block[31 : 0]); + write_single_word(`SHA512_REG_SHA512_BLOCK_0, block[1023 : 992]); + write_single_word(`SHA512_REG_SHA512_BLOCK_1, block[991 : 960]); + write_single_word(`SHA512_REG_SHA512_BLOCK_2, block[959 : 928]); + write_single_word(`SHA512_REG_SHA512_BLOCK_3, block[927 : 896]); + write_single_word(`SHA512_REG_SHA512_BLOCK_4, block[895 : 864]); + write_single_word(`SHA512_REG_SHA512_BLOCK_5, block[863 : 832]); + write_single_word(`SHA512_REG_SHA512_BLOCK_6, block[831 : 800]); + write_single_word(`SHA512_REG_SHA512_BLOCK_7, block[799 : 768]); + write_single_word(`SHA512_REG_SHA512_BLOCK_8, block[767 : 736]); + write_single_word(`SHA512_REG_SHA512_BLOCK_9, block[735 : 704]); + write_single_word(`SHA512_REG_SHA512_BLOCK_10, block[703 : 672]); + write_single_word(`SHA512_REG_SHA512_BLOCK_11, block[671 : 640]); + write_single_word(`SHA512_REG_SHA512_BLOCK_12, block[639 : 608]); + write_single_word(`SHA512_REG_SHA512_BLOCK_13, block[607 : 576]); + write_single_word(`SHA512_REG_SHA512_BLOCK_14, block[575 : 544]); + write_single_word(`SHA512_REG_SHA512_BLOCK_15, block[543 : 512]); + write_single_word(`SHA512_REG_SHA512_BLOCK_16, block[511 : 480]); + write_single_word(`SHA512_REG_SHA512_BLOCK_17, block[479 : 448]); + write_single_word(`SHA512_REG_SHA512_BLOCK_18, block[447 : 416]); + write_single_word(`SHA512_REG_SHA512_BLOCK_19, block[415 : 384]); + write_single_word(`SHA512_REG_SHA512_BLOCK_20, block[383 : 352]); + write_single_word(`SHA512_REG_SHA512_BLOCK_21, block[351 : 320]); + write_single_word(`SHA512_REG_SHA512_BLOCK_22, block[319 : 288]); + write_single_word(`SHA512_REG_SHA512_BLOCK_23, block[287 : 256]); + write_single_word(`SHA512_REG_SHA512_BLOCK_24, block[255 : 224]); + write_single_word(`SHA512_REG_SHA512_BLOCK_25, block[223 : 192]); + write_single_word(`SHA512_REG_SHA512_BLOCK_26, block[191 : 160]); + write_single_word(`SHA512_REG_SHA512_BLOCK_27, block[159 : 128]); + write_single_word(`SHA512_REG_SHA512_BLOCK_28, block[127 : 96]); + write_single_word(`SHA512_REG_SHA512_BLOCK_29, block[95 : 64]); + write_single_word(`SHA512_REG_SHA512_BLOCK_30, block[63 : 32]); + write_single_word(`SHA512_REG_SHA512_BLOCK_31, block[31 : 0]); end endtask // write_block + //---------------------------------------------------------------- + // mode_cmd() + // + // Create the mode_cmd needed for a given mode. + //---------------------------------------------------------------- + function [31 : 0] mode_cmd(input [1:0] mode); + begin + mode_cmd = (mode << `SHA512_REG_SHA512_CTRL_MODE_LOW) & `SHA512_REG_SHA512_CTRL_MODE_MASK; + end + endfunction //---------------------------------------------------------------- // get_mask() @@ -466,42 +409,68 @@ module sha512_ctrl_32bit_tb //---------------------------------------------------------------- task read_digest; begin - read_single_word(ADDR_DIGEST0); + read_single_word(`SHA512_REG_SHA512_DIGEST_0); digest_data[511 : 480] = read_data; - read_single_word(ADDR_DIGEST1); + read_single_word(`SHA512_REG_SHA512_DIGEST_1); digest_data[479 : 448] = read_data; - read_single_word(ADDR_DIGEST2); + read_single_word(`SHA512_REG_SHA512_DIGEST_2); digest_data[447 : 416] = read_data; - read_single_word(ADDR_DIGEST3); + read_single_word(`SHA512_REG_SHA512_DIGEST_3); digest_data[415 : 384] = read_data; - read_single_word(ADDR_DIGEST4); + read_single_word(`SHA512_REG_SHA512_DIGEST_4); digest_data[383 : 352] = read_data; - read_single_word(ADDR_DIGEST5); + read_single_word(`SHA512_REG_SHA512_DIGEST_5); digest_data[351 : 320] = read_data; - read_single_word(ADDR_DIGEST6); + read_single_word(`SHA512_REG_SHA512_DIGEST_6); digest_data[319 : 288] = read_data; - read_single_word(ADDR_DIGEST7); + read_single_word(`SHA512_REG_SHA512_DIGEST_7); digest_data[287 : 256] = read_data; - read_single_word(ADDR_DIGEST8); + read_single_word(`SHA512_REG_SHA512_DIGEST_8); digest_data[255 : 224] = read_data; - read_single_word(ADDR_DIGEST9); + read_single_word(`SHA512_REG_SHA512_DIGEST_9); digest_data[223 : 192] = read_data; - read_single_word(ADDR_DIGEST10); + read_single_word(`SHA512_REG_SHA512_DIGEST_10); digest_data[191 : 160] = read_data; - read_single_word(ADDR_DIGEST11); + read_single_word(`SHA512_REG_SHA512_DIGEST_11); digest_data[159 : 128] = read_data; - read_single_word(ADDR_DIGEST12); + read_single_word(`SHA512_REG_SHA512_DIGEST_12); digest_data[127 : 96] = read_data; - read_single_word(ADDR_DIGEST13); + read_single_word(`SHA512_REG_SHA512_DIGEST_13); digest_data[95 : 64] = read_data; - read_single_word(ADDR_DIGEST14); + read_single_word(`SHA512_REG_SHA512_DIGEST_14); digest_data[63 : 32] = read_data; - read_single_word(ADDR_DIGEST15); + read_single_word(`SHA512_REG_SHA512_DIGEST_15); digest_data[31 : 0] = read_data; end endtask // read_digest + //---------------------------------------------------------------- + // write_digest() + // + // Write the given digest to the dut. + //---------------------------------------------------------------- + task write_digest(input [511 : 0] digest); + begin + write_single_word(`SHA512_REG_SHA512_DIGEST_0, digest[511 : 480]); + write_single_word(`SHA512_REG_SHA512_DIGEST_1, digest[479 : 448]); + write_single_word(`SHA512_REG_SHA512_DIGEST_2, digest[447 : 416]); + write_single_word(`SHA512_REG_SHA512_DIGEST_3, digest[415 : 384]); + write_single_word(`SHA512_REG_SHA512_DIGEST_4, digest[383 : 352]); + write_single_word(`SHA512_REG_SHA512_DIGEST_5, digest[351 : 320]); + write_single_word(`SHA512_REG_SHA512_DIGEST_6, digest[319 : 288]); + write_single_word(`SHA512_REG_SHA512_DIGEST_7, digest[287 : 256]); + write_single_word(`SHA512_REG_SHA512_DIGEST_8, digest[255 : 224]); + write_single_word(`SHA512_REG_SHA512_DIGEST_9, digest[223 : 192]); + write_single_word(`SHA512_REG_SHA512_DIGEST_10, digest[191 : 160]); + write_single_word(`SHA512_REG_SHA512_DIGEST_11, digest[159 : 128]); + write_single_word(`SHA512_REG_SHA512_DIGEST_12, digest[127 : 96]); + write_single_word(`SHA512_REG_SHA512_DIGEST_13, digest[95 : 64]); + write_single_word(`SHA512_REG_SHA512_DIGEST_14, digest[63 : 32]); + write_single_word(`SHA512_REG_SHA512_DIGEST_15, digest[31 : 0]); + end + endtask // write_digest + //---------------------------------------------------------------- // check_name_version() // @@ -514,13 +483,13 @@ module sha512_ctrl_32bit_tb reg [31 : 0] version1; begin - read_single_word(ADDR_NAME0); + read_single_word(`SHA512_REG_SHA512_NAME_0); name0 = read_data; - read_single_word(ADDR_NAME1); + read_single_word(`SHA512_REG_SHA512_NAME_1); name1 = read_data; - read_single_word(ADDR_VERSION0); + read_single_word(`SHA512_REG_SHA512_VERSION_0); version0 = read_data; - read_single_word(ADDR_VERSION1); + read_single_word(`SHA512_REG_SHA512_VERSION_1); version1 = read_data; $display("DUT name: %c%c%c%c%c%c%c%c", @@ -548,7 +517,6 @@ module sha512_ctrl_32bit_tb input [511 : 0] expected); reg [511 : 0] mask; - reg [511 : 0] masked_data; reg [31 : 0] start_time; reg [31 : 0] end_time; begin @@ -556,7 +524,7 @@ module sha512_ctrl_32bit_tb start_time = cycle_ctr; write_block(block); - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); #CLK_PERIOD; @@ -568,17 +536,11 @@ module sha512_ctrl_32bit_tb end_time = cycle_ctr - start_time; $display("*** Single block test processing time = %01d cycles", end_time); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, 4'b0}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); //zeroize mask = get_mask(mode); - masked_data = digest_data & mask; - - if (DEBUG) - begin - $display("masked_data = 0x%0128x", masked_data); - end - if (masked_data == expected) + if ((digest_data & mask) == (expected & mask)) begin $display("TC%01d: OK.", tc_ctr); end @@ -586,7 +548,7 @@ module sha512_ctrl_32bit_tb begin $display("TC%01d: ERROR.", tc_ctr); $display("TC%01d: Expected: 0x%0128x", tc_ctr, expected); - $display("TC%01d: Got: 0x%0128x", tc_ctr, masked_data); + $display("TC%01d: Got: 0x%0128x", tc_ctr, digest_data); error_ctr = error_ctr + 1; end $display("*** TC%01d - Single block test done.", tc_ctr); @@ -610,19 +572,15 @@ module sha512_ctrl_32bit_tb input [511 : 0] expected1 ); reg [511 : 0] mask; - reg [511 : 0] masked_data0; - reg [511 : 0] masked_data1; reg [31 : 0] start_time; reg [31 : 0] end_time; begin $display("*** TC%01d - Double block test started.", tc_ctr); - mask = get_mask(mode); - // First block write_block(block0); - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); start_time = cycle_ctr; #CLK_PERIOD; hsel_i_tb = 0; @@ -631,8 +589,9 @@ module sha512_ctrl_32bit_tb wait_ready(); read_digest(); - masked_data0 = expected0 & mask; - if (digest_data == masked_data0) + mask = get_mask(mode); + + if ((digest_data & mask) == (expected0 & mask)) begin $display("TC%01d first block: OK.", tc_ctr); end @@ -647,7 +606,7 @@ module sha512_ctrl_32bit_tb // Final block write_block(block1); - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #CLK_PERIOD; hsel_i_tb = 0; @@ -657,11 +616,9 @@ module sha512_ctrl_32bit_tb $display("*** Double block test processing time = %01d cycles", end_time); read_digest(); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, 4'b0}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); //zeroize - masked_data1 = digest_data & mask; - - if (masked_data1 == expected1) + if ((digest_data & mask) == (expected1 & mask)) begin $display("TC%01d final block: OK.", tc_ctr); end @@ -669,7 +626,7 @@ module sha512_ctrl_32bit_tb begin $display("TC%01d: ERROR in final digest", tc_ctr); $display("TC%01d: Expected: 0x%0128x", tc_ctr, expected1); - $display("TC%01d: Got: 0x%0128x", tc_ctr, masked_data1); + $display("TC%01d: Got: 0x%0128x", tc_ctr, digest_data); error_ctr = error_ctr + 1; end @@ -693,7 +650,6 @@ module sha512_ctrl_32bit_tb input [511 : 0] expected ); reg [511 : 0] mask; - reg [511 : 0] masked_data; reg [31 : 0] start_time; reg [31 : 0] end_time; @@ -702,7 +658,7 @@ module sha512_ctrl_32bit_tb // First block write_block(block0); - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); start_time = cycle_ctr; #CLK_PERIOD; hsel_i_tb = 0; @@ -712,7 +668,7 @@ module sha512_ctrl_32bit_tb wait_ready(); // Final block - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #CLK_PERIOD; hsel_i_tb = 0; @@ -723,9 +679,8 @@ module sha512_ctrl_32bit_tb read_digest(); mask = get_mask(mode); - masked_data = digest_data & mask; - if (masked_data == expected) + if ((digest_data & mask) == (expected & mask)) begin $display("TC%01d final block: OK.", tc_ctr); end @@ -733,7 +688,7 @@ module sha512_ctrl_32bit_tb begin $display("TC%01d: ERROR in final digest", tc_ctr); $display("TC%01d: Expected: 0x%0128x", tc_ctr, expected); - $display("TC%01d: Got: 0x%0128x", tc_ctr, masked_data); + $display("TC%01d: Got: 0x%0128x", tc_ctr, digest_data); error_ctr = error_ctr + 1; end @@ -742,7 +697,84 @@ module sha512_ctrl_32bit_tb end endtask // double_block_test + //---------------------------------------------------------------- + // restore_test() + // + // + // Perform test of a double block digest with restore feature. + //---------------------------------------------------------------- + task restore_test(input [7 : 0] tc_number, + input [1 : 0] mode, + input [1023 : 0] block0, + input [1023 : 0] block1, + input [511 : 0] expected0, + input [511 : 0] expected1 + ); + reg [511 : 0] mask; + + begin + $display("*** TC%01d - Restore block test started.", tc_ctr); + + // First block + write_block(block0); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); + #CLK_PERIOD; + hsel_i_tb = 0; + + #(CLK_PERIOD); + wait_ready(); + read_digest(); + + mask = get_mask(mode); + + if ((digest_data & mask) == (expected0 & mask)) + begin + $display("TC%01d first block: OK.", tc_ctr); + end + else + begin + $display("TC%01d: ERROR in first digest", tc_ctr); + $display("TC%01d: Expected: 0x%064x", tc_ctr, expected0); + $display("TC%01d: Got: 0x%064x", tc_ctr, digest_data); + error_ctr = error_ctr + 1; + end + + + //zeroize core to test restore + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); + + + // Final block + write_block(block1); + write_digest(digest_data); + write_single_word(`SHA512_REG_SHA512_CTRL, RESTORE_CMD | NEXT_CMD | mode_cmd(mode)); + #CLK_PERIOD; + hsel_i_tb = 0; + + #(CLK_PERIOD); + wait_ready(); + + read_digest(); + + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); //zeroize + + if ((digest_data & mask) == (expected1 & mask)) + begin + $display("TC%01d final block: OK.", tc_ctr); + end + else + begin + $display("TC%01d: ERROR in final digest", tc_ctr); + $display("TC%01d: Expected: 0x%0128x", tc_ctr, expected1); + $display("TC%01d: Got: 0x%0128x", tc_ctr, digest_data); + error_ctr = error_ctr + 1; + end + $display("*** TC%01d - Double block test done.", tc_ctr); + tc_ctr = tc_ctr + 1; + end + endtask // double_block_test + //---------------------------------------------------------------- // continuous_cmd_test() // @@ -756,7 +788,6 @@ module sha512_ctrl_32bit_tb input [511 : 0] expected ); reg [511 : 0] mask; - reg [511 : 0] masked_data; reg [31 : 0] start_time; reg [31 : 0] end_time; @@ -765,7 +796,7 @@ module sha512_ctrl_32bit_tb // First block write_block(block0); - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); start_time = cycle_ctr; #CLK_PERIOD; hsel_i_tb = 0; @@ -774,9 +805,9 @@ module sha512_ctrl_32bit_tb for (int i=0; i<10; i++) begin - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); #CLK_PERIOD; - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #CLK_PERIOD; end @@ -785,7 +816,7 @@ module sha512_ctrl_32bit_tb write_block(block1); // Final block - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #CLK_PERIOD; hsel_i_tb = 0; @@ -793,9 +824,9 @@ module sha512_ctrl_32bit_tb for (int i=0; i<10; i++) begin - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); #CLK_PERIOD; - write_single_word(ADDR_CTRL, {28'h0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #CLK_PERIOD; end @@ -806,9 +837,8 @@ module sha512_ctrl_32bit_tb read_digest(); mask = get_mask(mode); - masked_data = digest_data & mask; - if (masked_data == expected) + if ((digest_data & mask) == (expected & mask)) begin $display("TC%01d final block: OK.", tc_ctr); end @@ -816,7 +846,7 @@ module sha512_ctrl_32bit_tb begin $display("TC%01d: ERROR in final digest", tc_ctr); $display("TC%01d: Expected: 0x%0128x", tc_ctr, expected); - $display("TC%01d: Got: 0x%0128x", tc_ctr, masked_data); + $display("TC%01d: Got: 0x%0128x", tc_ctr, digest_data); error_ctr = error_ctr + 1; end @@ -843,10 +873,10 @@ module sha512_ctrl_32bit_tb // First test: assert zeroize when engine is working write_block(block0); - write_single_word(ADDR_CTRL, {27'h0, 1'b0, mode, CTRL_INIT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode)); #(10 * CLK_PERIOD); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, 4'b0}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); //zeroize #CLK_PERIOD; hsel_i_tb = 0; @@ -868,7 +898,7 @@ module sha512_ctrl_32bit_tb // Second test: assert zeroize with INIT write_block(block0); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, mode, CTRL_INIT_VALUE}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, INIT_CMD | mode_cmd(mode) | ZEROIZE_CMD); //zeroize #CLK_PERIOD; hsel_i_tb = 0; #(CLK_PERIOD); @@ -891,7 +921,7 @@ module sha512_ctrl_32bit_tb // Third test: assert zeroize with NEXT write_block(block0); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, mode, CTRL_NEXT_VALUE}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode) | ZEROIZE_CMD); //zeroize #CLK_PERIOD; hsel_i_tb = 0; #(CLK_PERIOD); @@ -914,10 +944,10 @@ module sha512_ctrl_32bit_tb // Forth test: assert zeroize after NEXT write_block(block0); - write_single_word(ADDR_CTRL, {27'h0, 1'b0, mode, CTRL_NEXT_VALUE}); + write_single_word(`SHA512_REG_SHA512_CTRL, NEXT_CMD | mode_cmd(mode)); #(10 * CLK_PERIOD); - write_single_word(ADDR_CTRL, {27'h0, 1'b1, 4'b0}); //zeroize + write_single_word(`SHA512_REG_SHA512_CTRL, ZEROIZE_CMD); //zeroize #CLK_PERIOD; hsel_i_tb = 0; @@ -1023,6 +1053,15 @@ module sha512_ctrl_32bit_tb zeroize_test(8'h0b, MODE_SHA_384, double_block_one, double_block_two, tc12_expected); + // SHA-512 restore test. + restore_test(8'h0c, MODE_SHA_512, double_block_one, double_block_two, tc5_expected, tc6_expected); + + restore_test(8'h0d, MODE_SHA_512_224, double_block_one, double_block_two, tc7_expected, tc8_expected); + + restore_test(8'h0e, MODE_SHA_512_256, double_block_one, double_block_two, tc9_expected, tc10_expected); + + restore_test(8'h0f, MODE_SHA_384, double_block_one, double_block_two, tc11_expected, tc12_expected); + display_test_result(); $display(" -- Testbench for sha512 done. --"); diff --git a/src/soc_ifc/rtl/sha512_acc_top.sv b/src/soc_ifc/rtl/sha512_acc_top.sv index 810fcc5c4..27438136b 100644 --- a/src/soc_ifc/rtl/sha512_acc_top.sv +++ b/src/soc_ifc/rtl/sha512_acc_top.sv @@ -134,9 +134,11 @@ module sha512_acc_top .init_cmd(init_reg), .next_cmd(next_reg), + .restore_cmd(1'b0), .mode(sha_mode), .block_msg(block_reg), + .restore_digest('0), .ready(core_ready),