From 582fb605731050bec4a4606ff668759a2c049992 Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Fri, 9 Feb 2024 09:39:08 +0000 Subject: [PATCH] [hmac] Add *stop* and *continue* bits to `CMD` CSR Signed-off-by: Andreas Kurth --- hw/ip/hmac/data/hmac.hjson | 18 +++++++++++++++ hw/ip/hmac/doc/registers.md | 38 ++++++++++++++++++++++++------ hw/ip/hmac/rtl/hmac_reg_pkg.sv | 22 ++++++++++++------ hw/ip/hmac/rtl/hmac_reg_top.sv | 42 +++++++++++++++++++++++++++++++++- 4 files changed, 105 insertions(+), 15 deletions(-) diff --git a/hw/ip/hmac/data/hmac.hjson b/hw/ip/hmac/data/hmac.hjson index 6efd611e42bcf..d0820025c141a 100644 --- a/hw/ip/hmac/data/hmac.hjson +++ b/hw/ip/hmac/data/hmac.hjson @@ -210,6 +210,24 @@ based on currently received message. ''' } + { bits: "2", + name: "hash_stop", + desc: ''' + When 1 is written to this field, SHA or HMAC will afterwards set the `hmac_done` + interrupt as soon as the current block has been hashed. The hash can then be read + from the registers !!DIGEST_0 to !!DIGEST_7. Together with the message length in + !!MSG_LENGTH_LOWER and !!MSG_LENGTH_UPPER, this forms the information that has to be + saved before switching context. + ''' + } + { bits: "3", + name: "hash_continue", + desc: ''' + When 1 is written to this field, SHA or HMAC will continue hashing based on the + current hash in the digest registers and the message length, which both have to be + restored to switch context. + ''' + } ], } { name: "STATUS", diff --git a/hw/ip/hmac/doc/registers.md b/hw/ip/hmac/doc/registers.md index 96d576beb87fa..652e45a6f4e12 100644 --- a/hw/ip/hmac/doc/registers.md +++ b/hw/ip/hmac/doc/registers.md @@ -171,19 +171,43 @@ If this bit is 1, HMAC operates when `hash_start` toggles. HMAC command register - Offset: `0x14` - Reset default: `0x0` -- Reset mask: `0x3` +- Reset mask: `0xf` ### Fields ```wavejson -{"reg": [{"name": "hash_start", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "hash_process", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} +{"reg": [{"name": "hash_start", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "hash_process", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "hash_stop", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "hash_continue", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 150}} ``` -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:2 | | | | Reserved | -| 1 | r0w1c | x | hash_process | If writes 1 into this field, SHA256 or HMAC calculates the digest or signing based on currently received message. | -| 0 | r0w1c | x | hash_start | If writes 1 into this field, SHA256 or HMAC begins its operation. CPU should configure relative information first, such as message_length, secret_key. | +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------------------| +| 31:4 | | | Reserved | +| 3 | r0w1c | x | [hash_continue](#cmd--hash_continue) | +| 2 | r0w1c | x | [hash_stop](#cmd--hash_stop) | +| 1 | r0w1c | x | [hash_process](#cmd--hash_process) | +| 0 | r0w1c | x | [hash_start](#cmd--hash_start) | + +### CMD . hash_continue +When 1 is written to this field, SHA or HMAC will continue hashing based on the +current hash in the digest registers and the message length, which both have to be +restored to switch context. + +### CMD . hash_stop +When 1 is written to this field, SHA or HMAC will afterwards set the `hmac_done` +interrupt as soon as the current block has been hashed. The hash can then be read +from the registers [`DIGEST_0`](#digest_0) to [`DIGEST_7.`](#digest_7) Together with the message length in +[`MSG_LENGTH_LOWER`](#msg_length_lower) and [`MSG_LENGTH_UPPER`](#msg_length_upper), this forms the information that has to be +saved before switching context. + +### CMD . hash_process +If writes 1 into this field, SHA256 or HMAC calculates the digest or signing +based on currently received message. + +### CMD . hash_start +If writes 1 into this field, SHA256 or HMAC begins its operation. + +CPU should configure relative information first, such as message_length, +secret_key. ## STATUS HMAC Status register diff --git a/hw/ip/hmac/rtl/hmac_reg_pkg.sv b/hw/ip/hmac/rtl/hmac_reg_pkg.sv index a73bd3aee8434..a60859b1ebdc8 100644 --- a/hw/ip/hmac/rtl/hmac_reg_pkg.sv +++ b/hw/ip/hmac/rtl/hmac_reg_pkg.sv @@ -81,6 +81,14 @@ package hmac_reg_pkg; } hmac_reg2hw_cfg_reg_t; typedef struct packed { + struct packed { + logic q; + logic qe; + } hash_continue; + struct packed { + logic q; + logic qe; + } hash_stop; struct packed { logic q; logic qe; @@ -181,12 +189,12 @@ package hmac_reg_pkg; // Register -> HW type typedef struct packed { - hmac_reg2hw_intr_state_reg_t intr_state; // [652:650] - hmac_reg2hw_intr_enable_reg_t intr_enable; // [649:647] - hmac_reg2hw_intr_test_reg_t intr_test; // [646:641] - hmac_reg2hw_alert_test_reg_t alert_test; // [640:639] - hmac_reg2hw_cfg_reg_t cfg; // [638:631] - hmac_reg2hw_cmd_reg_t cmd; // [630:627] + hmac_reg2hw_intr_state_reg_t intr_state; // [656:654] + hmac_reg2hw_intr_enable_reg_t intr_enable; // [653:651] + hmac_reg2hw_intr_test_reg_t intr_test; // [650:645] + hmac_reg2hw_alert_test_reg_t alert_test; // [644:643] + hmac_reg2hw_cfg_reg_t cfg; // [642:635] + hmac_reg2hw_cmd_reg_t cmd; // [634:627] hmac_reg2hw_wipe_secret_reg_t wipe_secret; // [626:594] hmac_reg2hw_key_mreg_t [7:0] key; // [593:330] hmac_reg2hw_digest_mreg_t [7:0] digest; // [329:66] @@ -245,7 +253,7 @@ package hmac_reg_pkg; parameter logic [3:0] HMAC_CFG_RESVAL = 4'h 0; parameter logic [0:0] HMAC_CFG_ENDIAN_SWAP_RESVAL = 1'h 0; parameter logic [0:0] HMAC_CFG_DIGEST_SWAP_RESVAL = 1'h 0; - parameter logic [1:0] HMAC_CMD_RESVAL = 2'h 0; + parameter logic [3:0] HMAC_CMD_RESVAL = 4'h 0; parameter logic [8:0] HMAC_STATUS_RESVAL = 9'h 1; parameter logic [0:0] HMAC_STATUS_FIFO_EMPTY_RESVAL = 1'h 1; parameter logic [31:0] HMAC_WIPE_SECRET_RESVAL = 32'h 0; diff --git a/hw/ip/hmac/rtl/hmac_reg_top.sv b/hw/ip/hmac/rtl/hmac_reg_top.sv index 3442720fffd95..b66311e8ae3b7 100644 --- a/hw/ip/hmac/rtl/hmac_reg_top.sv +++ b/hw/ip/hmac/rtl/hmac_reg_top.sv @@ -203,6 +203,8 @@ module hmac_reg_top ( logic cmd_we; logic cmd_hash_start_wd; logic cmd_hash_process_wd; + logic cmd_hash_stop_wd; + logic cmd_hash_continue_wd; logic status_re; logic status_fifo_empty_qs; logic status_fifo_full_qs; @@ -578,7 +580,7 @@ module hmac_reg_top ( // R[cmd]: V(True) logic cmd_qe; - logic [1:0] cmd_flds_we; + logic [3:0] cmd_flds_we; assign cmd_qe = &cmd_flds_we; // F[hash_start]: 0:0 prim_subreg_ext #( @@ -612,6 +614,38 @@ module hmac_reg_top ( ); assign reg2hw.cmd.hash_process.qe = cmd_qe; + // F[hash_stop]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_cmd_hash_stop ( + .re (1'b0), + .we (cmd_we), + .wd (cmd_hash_stop_wd), + .d ('0), + .qre (), + .qe (cmd_flds_we[2]), + .q (reg2hw.cmd.hash_stop.q), + .ds (), + .qs () + ); + assign reg2hw.cmd.hash_stop.qe = cmd_qe; + + // F[hash_continue]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_cmd_hash_continue ( + .re (1'b0), + .we (cmd_we), + .wd (cmd_hash_continue_wd), + .d ('0), + .qre (), + .qe (cmd_flds_we[3]), + .q (reg2hw.cmd.hash_continue.q), + .ds (), + .qs () + ); + assign reg2hw.cmd.hash_continue.qe = cmd_qe; + // R[status]: V(True) // F[fifo_empty]: 0:0 @@ -1191,6 +1225,10 @@ module hmac_reg_top ( assign cmd_hash_start_wd = reg_wdata[0]; assign cmd_hash_process_wd = reg_wdata[1]; + + assign cmd_hash_stop_wd = reg_wdata[2]; + + assign cmd_hash_continue_wd = reg_wdata[3]; assign status_re = addr_hit[6] & reg_re & !reg_error; assign wipe_secret_we = addr_hit[8] & reg_we & !reg_error; @@ -1328,6 +1366,8 @@ module hmac_reg_top ( addr_hit[5]: begin reg_rdata_next[0] = '0; reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; end addr_hit[6]: begin