From 8df8b0cb74efac509c33381460c48d2d0b4c8e7e Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Wed, 17 Mar 2021 09:36:02 +0100 Subject: [PATCH 1/3] [aes] Doc clearing sequence upon reset and align STATUS reg reset value Upon reset, the AES module first performs a PRNG reseed and then clears key, IV and data registers with pseudo-random data. Only after that, the module becomes ready for software initialization. This commit explicitly documents this behavior and changes the reset value of the IDLE and INPUT_READY fields in the STATUS register. Both should be low (not idle, not ready to receive inputs) when coming out of reset. At the end of the clearing sequence, both bits will be high. This is related to lowRISC/OpenTitan#5646. Signed-off-by: Pirmin Vogel --- hw/ip/aes/data/aes.hjson | 30 +++++++++++++++++++----------- hw/ip/aes/doc/_index.md | 9 +++++++++ hw/ip/aes/rtl/aes_reg_top.sv | 4 ++-- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/hw/ip/aes/data/aes.hjson b/hw/ip/aes/data/aes.hjson index 4dc649628c04b..6049db552c6eb 100644 --- a/hw/ip/aes/data/aes.hjson +++ b/hw/ip/aes/data/aes.hjson @@ -192,6 +192,7 @@ The order in which the registers are updated does not matter. Can only be updated when the AES unit is idle. If the AES unit is non-idle, writes to these registers are ignored. + Upon reset, these registers are cleared with pseudo-random data. ''' count: "NumRegsKey", cname: "KEY_SHARE0", @@ -214,6 +215,7 @@ The order in which the registers are updated does not matter. Can only be updated when the AES unit is idle. If the AES unit is non-idle, writes to these registers are ignored. + Upon reset, these registers are cleared with pseudo-random data. ''' count: "NumRegsKey", cname: "KEY_SHARE1", @@ -240,6 +242,7 @@ Whenever starting a new message, the corresponding IV value must be provided by the processor. Once started, the AES unit automatically updates the contents of these registers. In ECB mode, the IV registers are not used and do not need to be configured. + Upon reset, these registers are cleared with pseudo-random data. ''' count: "NumRegsIv", cname: "IV", @@ -258,11 +261,12 @@ name: "DATA_IN", desc: ''' Input Data Registers. - If MANUAL_OPERATION=0 (see Control Register), the AES unit automatically starts encryption/decryption after these register have been written. + If MANUAL_OPERATION=0 (see Control Register), the AES unit automatically starts encryption/decryption after all Input Data registers have been written. Each register has to be written at least once. The order in which the registers are written does not matter. Loaded into the internal State register upon starting encryption/decryption of the next block. - After that, the processor can update the Input Data Register. + After that, the processor can update the Input Data registers (See INPUT_READY field of Status Register). + Upon reset, these registers are cleared with pseudo-random data. ''' count: "NumRegsData", cname: "DATA_IN", @@ -284,6 +288,7 @@ If MANUAL_OPERATION=0 (see Control Register), the AES unit is stalled when the previous output data has not yet been read and is about to be overwritten. Each register has to be read at least once. The order in which the registers are read does not matter. + Upon reset, these registers are cleared with pseudo-random data. ''' count: "NumRegsData", cname: "DATA_OUT", @@ -494,13 +499,13 @@ # Tag info (CSR test exclusions): # Updated by the HW. # Updates based on writes to other regs. - # -> Exclude all fields (except ALERT_FATAL) from init and write-read checks. - # Upon reset, internal operations are triggered that temporarily change the IDLE field. - # -> Exclude IDLE field from init and write-read checks (also in reset test). + # -> Exclude all fields (except ALERT_FATAL_FAULT) from init and write-read checks. + # Upon reset, internal operations are triggered at the end of which IDLE and INPUT_READY will be 1. + # -> Exclude IDLE and INPUT_READY field from init and write-read checks (also in reset test). fields: [ { bits: "0", name: "IDLE", - resval: "1", + resval: "0", desc: ''' The AES unit is idle (1) or busy (0). This flag is `0` if one of the following operations is currently running: i) encryption/decryption, ii) register clearing or iii) PRNG reseeding. @@ -510,6 +515,7 @@ } { bits: "1", name: "STALL", + resval: "0" desc: ''' The AES unit is not stalled (0) or stalled (1) because there is previous output data that must be read by the processor before the AES unit can @@ -520,6 +526,7 @@ } { bits: "2", name: "OUTPUT_LOST", + resval: "0" hwaccess: "hrw", desc: ''' All previous output data has been fully read by the processor (0) or at least one previous output data block has been lost (1). @@ -532,6 +539,7 @@ } { bits: "3", name: "OUTPUT_VALID", + resval: "0" desc: ''' The AES unit has no valid output (0) or has valid output data (1). ''' @@ -539,13 +547,13 @@ } { bits: "4", name: "INPUT_READY", - resval: "1", + resval: "0", desc: ''' - The AES unit is ready (1) to receive new data input via the DATA_IN registers or - the present values in the DATA_IN registers have not yet been loaded into the - module (0). + The AES unit is ready (1) or not ready (0) to receive new data input via the DATA_IN registers. + If the present values in the DATA_IN registers have not yet been loaded into the + module this flag is `0` (not ready). ''' - tags: ["excl:CsrNonInitTests:CsrExclCheck"] + tags: ["excl:CsrAllTests:CsrExclCheck"] } { bits: "5", name: "ALERT_RECOV_CTRL_UPDATE_ERR", diff --git a/hw/ip/aes/doc/_index.md b/hw/ip/aes/doc/_index.md index e787cc674d0b2..1c1f45018a5ae 100644 --- a/hw/ip/aes/doc/_index.md +++ b/hw/ip/aes/doc/_index.md @@ -328,6 +328,14 @@ Future versions of this AES unit thus might employ different means at architectu This section discusses how software can interface with the AES unit. +## Clear upon Reset + +Upon reset, the AES unit will first reseed the internal PRNG for register clearing via EDN, and then clear all key, IV and data registers with pseudo-random data. +Only after this sequence has finished, the unit becomes idle (indicated in {{< regref "STATUS.IDLE" >}}). +The AES unit is then ready for software initialization. +Note that at this point, the key, IV and data registers' values can no longer be expected to match the reset values. + + ## Initialization Before initialization, software must ensure that the AES unit is idle by checking {{< regref "STATUS.IDLE" >}}. @@ -364,6 +372,7 @@ It ensures that the AES unit: 1. Does not overwrite previous output data that has not yet been read by the processor. Then, software must: +1. Ensure that the INPUT_READY bit in {{< regref "STATUS" >}} is `1`. 1. Write Input Data Block `0` to the Input Data registers {{< regref "DATA_IN_0" >}} - {{< regref "DATA_IN_3" >}}. Each register must be written at least once. The order in which these registers are written does not matter. diff --git a/hw/ip/aes/rtl/aes_reg_top.sv b/hw/ip/aes/rtl/aes_reg_top.sv index 527cc7183cfd3..7a6b805b107a6 100644 --- a/hw/ip/aes/rtl/aes_reg_top.sv +++ b/hw/ip/aes/rtl/aes_reg_top.sv @@ -912,7 +912,7 @@ module aes_reg_top ( prim_subreg #( .DW (1), .SWACCESS("RO"), - .RESVAL (1'h1) + .RESVAL (1'h0) ) u_status_idle ( .clk_i (clk_i ), .rst_ni (rst_ni ), @@ -1012,7 +1012,7 @@ module aes_reg_top ( prim_subreg #( .DW (1), .SWACCESS("RO"), - .RESVAL (1'h1) + .RESVAL (1'h0) ) u_status_input_ready ( .clk_i (clk_i ), .rst_ni (rst_ni ), From 936d6f35e30ce484226afc5fe103216032ea99ae Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Wed, 17 Mar 2021 10:54:10 +0100 Subject: [PATCH 2/3] [aes] Specify missing reset values for shadowed control register Previously, some fields in the control register did not have a specified reset value. They were implicitly reset to 0. This commit 1) specifies these reset values and 2) uses the corresponding _RESVAL parameters exported by the regtool to define the reset value control register (hwext). Signed-off-by: Pirmin Vogel --- hw/ip/aes/aes.core | 2 +- hw/ip/aes/data/aes.hjson | 2 ++ hw/ip/aes/rtl/aes_pkg.sv | 10 +++++----- hw/ip/aes/rtl/aes_reg_pkg.sv | 2 ++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/hw/ip/aes/aes.core b/hw/ip/aes/aes.core index c0f50f050e32f..f2b7d8b4401e6 100644 --- a/hw/ip/aes/aes.core +++ b/hw/ip/aes/aes.core @@ -14,8 +14,8 @@ filesets: - lowrisc:ip:lc_ctrl_pkg - lowrisc:ip:edn_pkg files: - - rtl/aes_pkg.sv - rtl/aes_reg_pkg.sv + - rtl/aes_pkg.sv - rtl/aes_reg_top.sv - rtl/aes_core.sv - rtl/aes_ctr.sv diff --git a/hw/ip/aes/data/aes.hjson b/hw/ip/aes/data/aes.hjson index 6049db552c6eb..6277274e454e6 100644 --- a/hw/ip/aes/data/aes.hjson +++ b/hw/ip/aes/data/aes.hjson @@ -329,6 +329,7 @@ fields: [ { bits: "0", name: "OPERATION", + resval: "0", desc: ''' Select encryption(0) or decryption(1) operation of AES unit. ''' @@ -413,6 +414,7 @@ } { bits: "10", name: "MANUAL_OPERATION", + resval: "0" desc: ''' Controls whether the AES unit is operated in normal/automatic mode (0) or fully manual mode (1). In automatic mode (0), the AES unit automatically i) starts to encrypt/decrypt when it receives new input data, and ii) stalls during the last encryption/decryption cycle if the previous output data has not yet been read. diff --git a/hw/ip/aes/rtl/aes_pkg.sv b/hw/ip/aes/rtl/aes_pkg.sv index 245dbf1d6e798..a22977e566bf7 100644 --- a/hw/ip/aes/rtl/aes_pkg.sv +++ b/hw/ip/aes/rtl/aes_pkg.sv @@ -316,11 +316,11 @@ typedef struct packed { } ctrl_reg_t; parameter ctrl_reg_t CTRL_RESET = '{ - force_zero_masks: '0, - manual_operation: '0, - key_len: AES_128, - mode: AES_NONE, - operation: AES_ENC + force_zero_masks: aes_reg_pkg::AES_CTRL_SHADOWED_FORCE_ZERO_MASKS_RESVAL, + manual_operation: aes_reg_pkg::AES_CTRL_SHADOWED_MANUAL_OPERATION_RESVAL, + key_len: key_len_e'(aes_reg_pkg::AES_CTRL_SHADOWED_KEY_LEN_RESVAL), + mode: aes_mode_e'(aes_reg_pkg::AES_CTRL_SHADOWED_MODE_RESVAL), + operation: aes_op_e'(aes_reg_pkg::AES_CTRL_SHADOWED_OPERATION_RESVAL) }; // Multiplication by {02} (i.e. x) on GF(2^8) diff --git a/hw/ip/aes/rtl/aes_reg_pkg.sv b/hw/ip/aes/rtl/aes_reg_pkg.sv index f0e9d9fc76fe4..0673577711968 100644 --- a/hw/ip/aes/rtl/aes_reg_pkg.sv +++ b/hw/ip/aes/rtl/aes_reg_pkg.sv @@ -281,8 +281,10 @@ package aes_reg_pkg; parameter logic [31:0] AES_DATA_OUT_2_RESVAL = 32'h 0; parameter logic [31:0] AES_DATA_OUT_3_RESVAL = 32'h 0; parameter logic [11:0] AES_CTRL_SHADOWED_RESVAL = 12'h c0; + parameter logic [0:0] AES_CTRL_SHADOWED_OPERATION_RESVAL = 1'h 0; parameter logic [5:0] AES_CTRL_SHADOWED_MODE_RESVAL = 6'h 20; parameter logic [2:0] AES_CTRL_SHADOWED_KEY_LEN_RESVAL = 3'h 1; + parameter logic [0:0] AES_CTRL_SHADOWED_MANUAL_OPERATION_RESVAL = 1'h 0; parameter logic [0:0] AES_CTRL_SHADOWED_FORCE_ZERO_MASKS_RESVAL = 1'h 0; // Register index From 597d8d0dac6e797a10c9a8a35a3d7456c5eccdb8 Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Wed, 17 Mar 2021 11:03:52 +0100 Subject: [PATCH 3/3] [aes/doc] Add missing reset values for key, IV and data registers These registers are all reset to 0, but previously this wasn't visible from the documentation. Signed-off-by: Pirmin Vogel --- hw/ip/aes/data/aes.hjson | 5 +++++ hw/ip/aes/rtl/aes_reg_pkg.sv | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/hw/ip/aes/data/aes.hjson b/hw/ip/aes/data/aes.hjson index 6277274e454e6..b3f869c14cad8 100644 --- a/hw/ip/aes/data/aes.hjson +++ b/hw/ip/aes/data/aes.hjson @@ -184,6 +184,7 @@ # initial key registers { multireg: { name: "KEY_SHARE0", + resval: "0", desc: ''' Initial Key Registers Share 0. The actual initial key corresponds to Initial Key Registers Share 0 XORed with Initial Key Registers Share 1. @@ -207,6 +208,7 @@ }, { multireg: { name: "KEY_SHARE1", + resval: "0", desc: ''' Initial Key Registers Share 1. The actual initial key corresponds to Initial Key Registers Share 0 XORed with Initial Key Registers Share 1. @@ -232,6 +234,7 @@ # initialization vector registers { multireg: { name: "IV", + resval: "0", desc: ''' Initialization Vector Registers. The initialization vector (IV) or initial counter value must be written to these registers when starting a new message in CBC or CTR mode (see Control Register), respectively. @@ -259,6 +262,7 @@ # input data registers { multireg: { name: "DATA_IN", + resval: "0", desc: ''' Input Data Registers. If MANUAL_OPERATION=0 (see Control Register), the AES unit automatically starts encryption/decryption after all Input Data registers have been written. @@ -282,6 +286,7 @@ # output data registers { multireg: { name: "DATA_OUT", + resval: "0", desc: ''' Output Data Register. Holds the output data produced by the AES unit during the last encryption/decryption operation. diff --git a/hw/ip/aes/rtl/aes_reg_pkg.sv b/hw/ip/aes/rtl/aes_reg_pkg.sv index 0673577711968..e224240c463d0 100644 --- a/hw/ip/aes/rtl/aes_reg_pkg.sv +++ b/hw/ip/aes/rtl/aes_reg_pkg.sv @@ -257,29 +257,53 @@ package aes_reg_pkg; parameter logic [0:0] AES_ALERT_TEST_RECOV_CTRL_UPDATE_ERR_RESVAL = 1'h 0; parameter logic [0:0] AES_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; parameter logic [31:0] AES_KEY_SHARE0_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_0_KEY_SHARE0_0_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_1_KEY_SHARE0_1_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_2_KEY_SHARE0_2_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_3_KEY_SHARE0_3_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_4_KEY_SHARE0_4_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_5_KEY_SHARE0_5_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_6_KEY_SHARE0_6_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE0_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_7_KEY_SHARE0_7_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_0_KEY_SHARE1_0_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_1_KEY_SHARE1_1_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_2_KEY_SHARE1_2_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_3_KEY_SHARE1_3_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_4_KEY_SHARE1_4_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_5_KEY_SHARE1_5_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_6_KEY_SHARE1_6_RESVAL = 32'h 0; parameter logic [31:0] AES_KEY_SHARE1_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_7_KEY_SHARE1_7_RESVAL = 32'h 0; parameter logic [31:0] AES_IV_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_0_IV_0_RESVAL = 32'h 0; parameter logic [31:0] AES_IV_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_1_IV_1_RESVAL = 32'h 0; parameter logic [31:0] AES_IV_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_2_IV_2_RESVAL = 32'h 0; parameter logic [31:0] AES_IV_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_3_IV_3_RESVAL = 32'h 0; parameter logic [31:0] AES_DATA_OUT_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_0_DATA_OUT_0_RESVAL = 32'h 0; parameter logic [31:0] AES_DATA_OUT_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_1_DATA_OUT_1_RESVAL = 32'h 0; parameter logic [31:0] AES_DATA_OUT_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_2_DATA_OUT_2_RESVAL = 32'h 0; parameter logic [31:0] AES_DATA_OUT_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_3_DATA_OUT_3_RESVAL = 32'h 0; parameter logic [11:0] AES_CTRL_SHADOWED_RESVAL = 12'h c0; parameter logic [0:0] AES_CTRL_SHADOWED_OPERATION_RESVAL = 1'h 0; parameter logic [5:0] AES_CTRL_SHADOWED_MODE_RESVAL = 6'h 20;