|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | { name: "KEYMGR", | 
|  | clocking: [ | 
|  | {clock: "clk_i", reset: "rst_ni", primary: true}, | 
|  | {clock: "clk_edn_i", reset: "rst_edn_ni"} | 
|  | ] | 
|  | bus_interfaces: [ | 
|  | { protocol: "tlul", direction: "device" } | 
|  | ], | 
|  | interrupt_list: [ | 
|  | { name: "op_done",   desc: "Operation complete" }, | 
|  | ], | 
|  | alert_list: [ | 
|  | { name: "recov_operation_err", | 
|  | desc: ''' | 
|  | Alert for key manager operation errors.  These errors could have been caused by | 
|  | software''' | 
|  | }, | 
|  | { name: "fatal_fault_err", | 
|  | desc: "Alert for key manager faults.  These errors cannot be caused by software", | 
|  | }, | 
|  |  | 
|  | ], | 
|  |  | 
|  | inter_signal_list: [ | 
|  | { struct:  "edn", | 
|  | type:    "req_rsp", | 
|  | name:    "edn", | 
|  | act:     "req", | 
|  | package: "edn_pkg", | 
|  | }, | 
|  | { struct:  "hw_key_req",  // aes_key_req_t | 
|  | type:    "uni", | 
|  | name:    "aes_key",     // aes_key_o (req) | 
|  | act:     "req", | 
|  | package: "keymgr_pkg",  // Origin package (only needs for the requester) | 
|  | }, | 
|  | { struct:  "hw_key_req",  // kmac_key_req_t | 
|  | type:    "uni", | 
|  | name:    "kmac_key",    // kmac_key_o (req) | 
|  | act:     "req", | 
|  | package: "keymgr_pkg",  // Origin package (only needs for the requester) | 
|  | }, | 
|  | { struct:  "otbn_key_req", | 
|  | type:    "uni", | 
|  | name:    "otbn_key", | 
|  | act:     "req", | 
|  | package: "keymgr_pkg", | 
|  | }, | 
|  | { struct:  "app",   // kmac_pkg::app_req_t, kmac_pkg::app_rsp_t | 
|  | type:    "req_rsp", | 
|  | name:    "kmac_data",   // kmac_data_o (req), kmac_data_i (rsp) | 
|  | act:     "req", | 
|  | package: "kmac_pkg",  // Origin package (only needs for the requester) | 
|  | }, | 
|  | { struct:  "otp_keymgr_key", | 
|  | type:    "uni", | 
|  | name:    "otp_key", | 
|  | act:     "rcv", | 
|  | package: "otp_ctrl_pkg", | 
|  | }, | 
|  | { struct:  "otp_device_id", | 
|  | type:    "uni", | 
|  | name:    "otp_device_id", | 
|  | act:     "rcv", | 
|  | package: "otp_ctrl_pkg", | 
|  | }, | 
|  | { struct:  "keymgr_flash", | 
|  | type:    "uni", | 
|  | name:    "flash", | 
|  | act:     "rcv", | 
|  | package: "flash_ctrl_pkg", | 
|  | }, | 
|  | { struct:  "lc_tx", | 
|  | type:    "uni", | 
|  | name:    "lc_keymgr_en", | 
|  | act:     "rcv", | 
|  | package: "lc_ctrl_pkg", | 
|  | default: "lc_ctrl_pkg::On", | 
|  | }, | 
|  | { struct:  "lc_keymgr_div", | 
|  | type:    "uni", | 
|  | name:    "lc_keymgr_div", | 
|  | act:     "rcv", | 
|  | package: "lc_ctrl_pkg", | 
|  | }, | 
|  | { struct:  "keymgr_data" | 
|  | type:    "uni" | 
|  | name:    "rom_digest" | 
|  | act:     "rcv" | 
|  | package: "rom_ctrl_pkg" | 
|  | }, | 
|  | { struct:  "logic" | 
|  | type:    "uni" | 
|  | name:    "kmac_en_masking" | 
|  | act:     "rcv" | 
|  | }, | 
|  | ], | 
|  |  | 
|  | param_list: [ | 
|  | { name:      "KmacEnMasking", | 
|  | desc:      "Flag indicating with kmac masking is enabled", | 
|  | type:      "bit", | 
|  | default:   "1", | 
|  | local:     "false", | 
|  | expose:    "true", | 
|  | } | 
|  | // Random netlist constants | 
|  | { name:      "RndCnstLfsrSeed", | 
|  | desc:      "Compile-time random bits for initial LFSR seed", | 
|  | type:      "keymgr_pkg::lfsr_seed_t" | 
|  | randcount: "64", | 
|  | randtype:  "data", | 
|  | } | 
|  | { name:      "RndCnstLfsrPerm", | 
|  | desc:      "Compile-time random permutation for LFSR output", | 
|  | type:      "keymgr_pkg::lfsr_perm_t" | 
|  | randcount: "64", | 
|  | randtype:  "perm", | 
|  | }, | 
|  | { name:      "RndCnstRandPerm", | 
|  | desc:      "Compile-time random permutation for entropy used in share overriding", | 
|  | type:      "keymgr_pkg::rand_perm_t" | 
|  | randcount: "32", | 
|  | randtype:  "perm", | 
|  | } | 
|  | { name:      "RndCnstRevisionSeed", | 
|  | desc:      "Compile-time random bits for revision seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstCreatorIdentitySeed", | 
|  | desc:      "Compile-time random bits for creator identity seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstOwnerIntIdentitySeed", | 
|  | desc:      "Compile-time random bits for owner intermediate identity seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstOwnerIdentitySeed", | 
|  | desc:      "Compile-time random bits for owner identity seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstSoftOutputSeed", | 
|  | desc:      "Compile-time random bits for software generation seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstHardOutputSeed", | 
|  | desc:      "Compile-time random bits for hardware generation seed", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstAesSeed", | 
|  | desc:      "Compile-time random bits for generation seed when aes destination selected", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstKmacSeed", | 
|  | desc:      "Compile-time random bits for generation seed when kmac destination selected", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstOtbnSeed", | 
|  | desc:      "Compile-time random bits for generation seed when otbn destination selected", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstCdi", | 
|  | desc:      "Compile-time random bits for generation seed when no CDI is selected", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  |  | 
|  | { name:      "RndCnstNoneSeed", | 
|  | desc:      "Compile-time random bits for generation seed when no destination selected", | 
|  | type:      "keymgr_pkg::seed_t" | 
|  | randcount: "256", | 
|  | randtype:  "data", | 
|  | }, | 
|  | { name: "NumSaltReg", | 
|  | desc: "Number of Registers for SW inputs (Salt)", | 
|  | type: "int", | 
|  | default: "8", | 
|  | local: "true" | 
|  | }, | 
|  | { name: "NumSwBindingReg", | 
|  | desc: "Number of Registers for SW inputs (SW binding)", | 
|  | type: "int", | 
|  | default: "8", | 
|  | local: "true" | 
|  | }, | 
|  | { name: "NumOutReg", | 
|  | desc: "Number of Registers for SW outputs", | 
|  | type: "int", | 
|  | default: "8", | 
|  | local: "true" | 
|  | }, | 
|  | { name: "NumKeyVersion", | 
|  | desc: "Number of Registers for key version", | 
|  | type: "int", | 
|  | default: "1", | 
|  | local: "true" | 
|  | }, | 
|  | ], | 
|  | countermeasures: [ | 
|  | { name: "BUS.INTEGRITY", | 
|  | desc: "End-to-end bus integrity scheme." | 
|  | } | 
|  | { name: "CONFIG.SHADOW", | 
|  | desc: ''' | 
|  | Various critical registers are shadowed: including operation control, reseed interval, | 
|  | and key max version (creator, owner intermediate, owner). | 
|  | ''' | 
|  | } | 
|  | { name: "OP.CONFIG.REGWEN", | 
|  | desc: ''' | 
|  | Various controls locked during the duration of an operation: including operation start, | 
|  | operation control, sideload clear, salt and key version. | 
|  | ''' | 
|  | } | 
|  | { name: "RESEED.CONFIG.REGWEN", | 
|  | desc: ''' | 
|  | Reseed interval is software lockable. | 
|  | ''' | 
|  | } | 
|  | { name: "SW_BINDING.CONFIG.REGWEN", | 
|  | desc: ''' | 
|  | Software binding is lockable by software in each stage. When keymgr successfully advances, | 
|  | the lock is released to allow the next stage the freedom to program. | 
|  | ''' | 
|  | } | 
|  | { name: "MAX_KEY_VER.CONFIG.REGWEN", | 
|  | desc: ''' | 
|  | Max key version is software lockable. | 
|  | ''' | 
|  | } | 
|  | { name: "LC_CTRL.INTERSIG.MUBI", | 
|  | desc: ''' | 
|  | Life cycle control signal is multibit | 
|  | ''' | 
|  | } | 
|  | { name: "CONSTANTS.CONSISTENCY", | 
|  | desc: ''' | 
|  | Basic consistency checks (all 0's or all 1's) for keymgr diversification constants | 
|  | ''' | 
|  | } | 
|  | { name: "INTERSIG.CONSISTENCY", | 
|  | desc: ''' | 
|  | Basic consistency checks (all 0's or all 1's) for otp diversification inputs | 
|  | ''' | 
|  | } | 
|  | { name: "HW.KEY.SW_NOACCESS", | 
|  | desc: ''' | 
|  | Sideload keys are not directly accessible by software. | 
|  | ''' | 
|  | } | 
|  | { name: "OUTPUT_KEYS.CTRL.REDUN", | 
|  | desc: ''' | 
|  | Software and sideload keys are redundantly controlled. One valid controls the write enable, | 
|  | the other controls the input data (muxed to random). | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.FSM.SPARSE", | 
|  | desc: ''' | 
|  | Main control fsm is sparsely encoded. | 
|  | ''' | 
|  | } | 
|  | { name: "DATA.FSM.SPARSE", | 
|  | desc: ''' | 
|  | Control data fsm (for redundant data control) is sparsely encoded. | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.FSM.LOCAL_ESC", | 
|  | desc: ''' | 
|  | Main control fsm locally escalates based on any detected fault in keymgr. | 
|  | When a fault is detected (sync or async) the fsm transitions to invalid state to prevent | 
|  | further legal operations from executing. | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.FSM.CONSISTENCY", | 
|  | desc: ''' | 
|  | Main and operational fsm transitions are consistent with software commands. | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.FSM.GLOBAL_ESC", | 
|  | desc: ''' | 
|  | When the system globally escalates, the main control fsm also transitions to invalid state | 
|  | to prevent further legal operations from executing. | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.CTR.REDUN", | 
|  | desc: ''' | 
|  | Primary count is duplicated. | 
|  | ''' | 
|  | } | 
|  | { name: "KMAC_IF.FSM.SPARSE", | 
|  | desc: ''' | 
|  | kmac interface fsm is sparsely encoded. | 
|  | ''' | 
|  | } | 
|  | { name: "KMAC_IF.CTR.REDUN", | 
|  | desc: ''' | 
|  | Primary count uses cross count. | 
|  | ''' | 
|  | } | 
|  | { name: "KMAC_IF_CMD.CTRL.CONSISTENCY", | 
|  | desc: ''' | 
|  | One hot check for kmac interface commands. | 
|  | ''' | 
|  | } | 
|  | { name: "KMAC_IF_DONE.CTRL.CONSISTENCY", | 
|  | desc: ''' | 
|  | Spurious kmac done check. | 
|  | ''' | 
|  | } | 
|  | { name: "RESEED.CTR.REDUN", | 
|  | desc: ''' | 
|  | Primary count is duplicated. | 
|  | ''' | 
|  | } | 
|  | { name: "SIDE_LOAD_SEL.CTRL.CONSISTENCY", | 
|  | desc: ''' | 
|  | Sideload key slot select is checked for consistency against original software command. | 
|  | ''' | 
|  | } | 
|  | { name: "CTRL.KEY.INTEGRITY", | 
|  | desc: ''' | 
|  | Internal secret key is protected with ECC. | 
|  | ''' | 
|  | } | 
|  | ] | 
|  |  | 
|  | regwidth: "32", | 
|  | registers: [ | 
|  | { name: "CFG_REGWEN", | 
|  | desc: "Key manager configuration enable", | 
|  | swaccess: "ro",  // this lock is HW managed | 
|  | hwaccess: "hwo", | 
|  | hwext: "true", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | key manager configuration enable. | 
|  | When key manager operation is started (see CONTROL), registers protected by this EN are no longer | 
|  | modifiable until the operation completes. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "START", | 
|  | desc: "Key manager operation start", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hrw", | 
|  | regwen: "CFG_REGWEN", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | hwaccess: "hrw", | 
|  | name: "EN", | 
|  | desc: "Start key manager operations", | 
|  | resval: "0" | 
|  | enum: [ | 
|  | { value: "1", | 
|  | name: "Valid state", | 
|  | desc: ''' | 
|  | To trigger a start, this value must be programmed.  All other values are considered no operation start. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | tags: [// bit self clears, handle in directed test | 
|  | "excl:CsrNonInitTests:CsrExclWrite"] | 
|  | } | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "CONTROL_SHADOWED", | 
|  | desc: "Key manager operation controls", | 
|  | regwen: "CFG_REGWEN", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | shadowed: "true", | 
|  | update_err_alert: "recov_operation_err", | 
|  | storage_err_alert: "fatal_fault_err", | 
|  | fields: [ | 
|  | { bits: "6:4", | 
|  | name: "OPERATION", | 
|  | desc: "Key manager operation selection. All values not enumerated below behave the same as disable", | 
|  | resval: "1", | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "Advance", | 
|  | desc: ''' | 
|  | Advance key manager state. | 
|  |  | 
|  | Advances key manager to the next stage. | 
|  | If key manager is already at last functional state, the advance operation is equivalent to the | 
|  | disable operation. | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "Generate ID", | 
|  | desc: ''' | 
|  | Generates an identity seed from the current state. | 
|  | ''' | 
|  | }, | 
|  | { value: "2", | 
|  | name: "Generate SW Output", | 
|  | desc: ''' | 
|  | Generates a key manager output that is visible to software from the current state. | 
|  | ''' | 
|  | }, | 
|  | { value: "3", | 
|  | name: "Generate HW Output", | 
|  | desc: ''' | 
|  | Generates a key manager output that is visible only to hardware crypto blocks. | 
|  | ''' | 
|  | }, | 
|  | { value: "4", | 
|  | name: "Disable", | 
|  | desc: ''' | 
|  | Disables key manager operation and moves it to the disabled state. | 
|  |  | 
|  | Note the disabled state is terminal and cannot be recovered without a reset. | 
|  | ''' | 
|  | }, | 
|  | ], | 
|  | }, | 
|  |  | 
|  | { bits: "7", | 
|  | name: "CDI_SEL", | 
|  | desc: ''' | 
|  | When the OPERATION field is programmed to generate output, this field selects | 
|  | the appropriate CDI to use. | 
|  |  | 
|  | This field should be programmed for both hw / sw generation. | 
|  | ''', | 
|  | resval: "0" | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "Sealing CDI", | 
|  | desc: ''' | 
|  | Sealing CDI is selected | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "Attestation CDI", | 
|  | desc: ''' | 
|  | Attestation CDI is selected | 
|  | ''' | 
|  | }, | 
|  | ], | 
|  | }, | 
|  |  | 
|  | { bits: "13:12", | 
|  | name: "DEST_SEL", | 
|  | desc: ''' | 
|  | When the OPERATION field is programmed to generate output, this field selects | 
|  | the appropriate crypto cipher target. | 
|  |  | 
|  | This field should be programmed for both hw / sw generation, as this helps diverisifies the output. | 
|  | ''', | 
|  | resval: "0" | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "None", | 
|  | desc: ''' | 
|  | No target selected | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "AES", | 
|  | desc: ''' | 
|  | AES selected | 
|  | ''' | 
|  | }, | 
|  | { value: "2", | 
|  | name: "KMAC", | 
|  | desc: ''' | 
|  | KMAC selected | 
|  | ''' | 
|  | }, | 
|  | { value: "3", | 
|  | name: "OTBN", | 
|  | desc: ''' | 
|  | OTBN selected.  Note for OTBN hardware operations, the generated output is 384-bits, while for all | 
|  | other operations (including OTBN software), it is 256-bits. | 
|  |  | 
|  | Generating a hardware 384-bit seed directly for OTBN sideload reduces some of the OTBN code burden for entropy expansion. | 
|  | When generating for software, this is not a concern. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  | ], | 
|  | }, | 
|  |  | 
|  | { name: "SIDELOAD_CLEAR", | 
|  | desc: "sideload key slots clear" | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | regwen: "CFG_REGWEN", | 
|  | fields: [ | 
|  | { bits: "2:0", | 
|  | name: "VAL", | 
|  | resval: "0" | 
|  | desc: ''' | 
|  | Depending on the value programmed, a different side load key slot is cleared. | 
|  | If the value programmed is not one of the enumerated values below, ALL side | 
|  | load key slots are continuously cleared. | 
|  | ''', | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "None", | 
|  | desc: ''' | 
|  | No sideload keys cleared. | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "AES", | 
|  | desc: ''' | 
|  | The AES sideload key is continuously cleared with entropy. | 
|  | ''' | 
|  | }, | 
|  | { value: "2", | 
|  | name: "KMAC", | 
|  | desc: ''' | 
|  | The KMAC sideload key is continuously cleared with entropy. | 
|  | ''' | 
|  | }, | 
|  | { value: "3", | 
|  | name: "OTBN", | 
|  | desc: ''' | 
|  | The OTBN sideload key is continuously cleared with entropy. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  |  | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "RESEED_INTERVAL_REGWEN", | 
|  | desc: "regwen for reseed interval", | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "none", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | Configuration enable for reseed interval | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "RESEED_INTERVAL_SHADOWED", | 
|  | desc: "Reseed interval for key manager entropy reseed", | 
|  | shadowed: "true", | 
|  | update_err_alert: "recov_operation_err", | 
|  | storage_err_alert: "fatal_fault_err", | 
|  | regwen: "RESEED_INTERVAL_REGWEN", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "15:0", | 
|  | name: "VAL", | 
|  | resval: "0x100" | 
|  | desc: ''' | 
|  | Number of key manager cycles before the entropy is reseeded | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | // The following can potentially be replaced by a RAM if it gets too large | 
|  | // Currently there are 32b * NumSaltReg  bits for salt inputs | 
|  | //                     32b * NumSwBindingReg bits for software binding inputs | 
|  | //                     32b * NumOutReg * 2 (if key shares desired) for outputs | 
|  | //                     32b * NumOutReg * NumCryptos * 2 (if key shares desired) for hidden key bus | 
|  | // This totals to over 2kb of storage | 
|  | { name: "SW_BINDING_REGWEN", | 
|  | desc: "Register write enable for SOFTWARE_BINDING", | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "hrw", | 
|  | hwext: "true", | 
|  | hwqe: "true", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | Software binding register write enable. | 
|  | This is locked by software and unlocked by hardware upon a successful advance call. | 
|  |  | 
|  | Software binding resets to 1, and its value cannot be altered by software until advancement to Init state. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "SEALING_SW_BINDING", | 
|  | regwen: "SW_BINDING_REGWEN", | 
|  | desc: ''' | 
|  | Software binding input to sealing portion of the key manager. | 
|  | This register is lockable and shared between key manager stages. | 
|  | This binding value is not considered secret, however its integrity is very important. | 
|  |  | 
|  | The software binding is locked by software and unlocked by hardware upon a successful advance operation. | 
|  | ''', | 
|  | count: "NumSwBindingReg", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Software binding value | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "ATTEST_SW_BINDING", | 
|  | regwen: "SW_BINDING_REGWEN", | 
|  | desc: ''' | 
|  | Software binding input to the attestation portion of the key manager. | 
|  | This register is lockable and shared between key manager stages. | 
|  | This binding value is not considered secret, however its integrity is very important. | 
|  |  | 
|  | The software binding is locked by software and unlocked by hardware upon a successful advance operation. | 
|  | ''', | 
|  | count: "NumSwBindingReg", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Software binding value | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "Salt", | 
|  | regwen: "CFG_REGWEN", | 
|  | desc: ''' | 
|  | Salt value used as part of output generation | 
|  | ''', | 
|  | count: "NumSaltReg", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Salt value | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "KEY_VERSION", | 
|  | regwen: "CFG_REGWEN", | 
|  | desc: ''' | 
|  | Version used as part of output generation | 
|  | ''', | 
|  | count: "NumKeyVersion", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Key version | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | }, | 
|  | }, | 
|  |  | 
|  | // since there is not a good way to define a separate enable register per multireg | 
|  | // the following version registers are manually separated | 
|  | // further, it should be possible to reduce the number of max_versions held | 
|  | // as long as clearly specify the boot sequence relative to when keys are generated. | 
|  | // should check with the security team. | 
|  | // | 
|  | // The following storage is also huge, should consider switching to RAMs after examining | 
|  | // the security implications | 
|  |  | 
|  | { name: "MAX_CREATOR_KEY_VER_REGWEN", | 
|  | desc: "Register write enable for MAX_CREATOR_KEY_VERSION", | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "none", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | MAX_CREATOR_KEY_VERSION configure enable. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "MAX_CREATOR_KEY_VER_SHADOWED", | 
|  | desc: "Max creator key version", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | shadowed: "true", | 
|  | update_err_alert: "recov_operation_err", | 
|  | storage_err_alert: "fatal_fault_err", | 
|  | regwen: "MAX_CREATOR_KEY_VER_REGWEN", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | resval: "0x0" | 
|  | desc: ''' | 
|  | Max key version. | 
|  |  | 
|  | Any key version up to the value specificed in this register is valid. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "MAX_OWNER_INT_KEY_VER_REGWEN", | 
|  | desc: "Register write enable for MAX_OWNER_INT_KEY_VERSION", | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "none", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | MAX_OWNER_INTERMEDIATE_KEY configure enable. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "MAX_OWNER_INT_KEY_VER_SHADOWED", | 
|  | desc: "Max owner intermediate key version", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | shadowed: "true", | 
|  | update_err_alert: "recov_operation_err", | 
|  | storage_err_alert: "fatal_fault_err", | 
|  | regwen: "MAX_OWNER_INT_KEY_VER_REGWEN", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | Max key version. | 
|  |  | 
|  | Any key version up to the value specificed in this register is valid. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "MAX_OWNER_KEY_VER_REGWEN", | 
|  | desc: "Register write enable for MAX_OWNER_KEY_VERSION", | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "none", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "EN", | 
|  | resval: "1" | 
|  | desc: ''' | 
|  | MAX_OWNER_KEY configure enable. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "MAX_OWNER_KEY_VER_SHADOWED", | 
|  | desc: "Max owner key version", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | shadowed: "true", | 
|  | update_err_alert: "recov_operation_err", | 
|  | storage_err_alert: "fatal_fault_err", | 
|  | regwen: "MAX_OWNER_KEY_VER_REGWEN", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | resval: "0x0" | 
|  | desc: ''' | 
|  | Max key version. | 
|  |  | 
|  | Any key version up to the value specificed in this register is valid. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "SW_SHARE0_OUTPUT", | 
|  | desc: ''' | 
|  | Key manager software output. | 
|  |  | 
|  | When a software output operation is selected, the results of the operation are placed | 
|  | here. | 
|  | ''', | 
|  | count: "NumOutReg", | 
|  | swaccess: "rc", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Software output value | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | tags: [// HW-update reg | 
|  | // When a fault happens (e.g. when we test TL integrity error), this CSR will be | 
|  | // wiped with random value. | 
|  | "excl:CsrNonInitTests:CsrExclCheck"] | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { multireg: { | 
|  | cname: "KEYMGR", | 
|  | name: "SW_SHARE1_OUTPUT", | 
|  | desc: ''' | 
|  | Key manager software output. | 
|  |  | 
|  | When a software output operation is selected, the results of the operation are placed | 
|  | here. | 
|  | ''', | 
|  | count: "NumOutReg", | 
|  | swaccess: "rc", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "VAL", | 
|  | desc: ''' | 
|  | Software output value | 
|  | ''', | 
|  | resval: "0" | 
|  | }, | 
|  | ], | 
|  | tags: [// HW-update reg | 
|  | // When a fault happens (e.g. when we test TL integrity error), this CSR will be | 
|  | // wiped with random value. | 
|  | "excl:CsrNonInitTests:CsrExclCheck"] | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { name: "WORKING_STATE", | 
|  | desc: ''' | 
|  | Key manager working state. | 
|  |  | 
|  | This is a readout of the current key manager working state | 
|  | ''', | 
|  | swaccess: "ro", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "2:0", | 
|  | name: "STATE", | 
|  | resval: "0x0" | 
|  | desc: "Key manager control state", | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "Reset", | 
|  | desc: ''' | 
|  | Key manager control is still in reset.  Please wait for initialization complete | 
|  | before issuing operations | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "Init", | 
|  | desc: ''' | 
|  | Key manager control has finished initialization and will now accept | 
|  | software commands. | 
|  | ''' | 
|  | }, | 
|  | { value: "2", | 
|  | name: "Creator Root Key", | 
|  | desc: ''' | 
|  | Key manager control currently contains the creator root key. | 
|  | ''' | 
|  | }, | 
|  | { value: "3", | 
|  | name: "Owner Intermediate Key", | 
|  | desc: ''' | 
|  | Key manager control currently contains the owner intermediate key. | 
|  | ''' | 
|  | }, | 
|  | { value: "4", | 
|  | name: "Owner Key", | 
|  | desc: ''' | 
|  | Key manager control currently contains the owner key. | 
|  | ''' | 
|  | }, | 
|  | { value: "5", | 
|  | name: "Disabled", | 
|  | desc: ''' | 
|  | Key manager currently disabled. Please reset the key manager. | 
|  | Sideload keys are still valid. | 
|  | ''' | 
|  | }, | 
|  | { value: "6", | 
|  | name: "Invalid", | 
|  | desc: ''' | 
|  | Key manager currently invalid. Please reset the key manager. | 
|  | Sideload keys are no longer valid. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | } | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "OP_STATUS", | 
|  | desc: ''' | 
|  | Key manager status. | 
|  |  | 
|  | Hardware sets the status based on software initiated operations. | 
|  | This register must be explicitly cleared by software. | 
|  | Software clears by writing back whatever it reads. | 
|  | ''', | 
|  | swaccess: "rw1c", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "1:0", | 
|  | name: "STATUS", | 
|  | resval: "0x0" | 
|  | desc: "Operation status.", | 
|  | enum: [ | 
|  | { value: "0", | 
|  | name: "Idle", | 
|  | desc: ''' | 
|  | Key manager is idle | 
|  | ''' | 
|  | }, | 
|  | { value: "1", | 
|  | name: "WIP", | 
|  | desc: ''' | 
|  | Work in progress. | 
|  | A key manager operation has been started and is ongoing | 
|  | ''' | 
|  | }, | 
|  | { value: "2", | 
|  | name: "DONE_SUCCESS", | 
|  | desc: ''' | 
|  | Operation finished without errors | 
|  | ''' | 
|  | }, | 
|  | { value: "3", | 
|  | name: "DONE_ERROR", | 
|  | desc: ''' | 
|  | Operation finished with errors, please see ERR_CODE register. | 
|  | ''' | 
|  | }, | 
|  | ] | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "ERR_CODE", | 
|  | desc: ''' | 
|  | Key manager error code. | 
|  | This register must be explicitly cleared by software. | 
|  |  | 
|  | This register represents both synchronous and asynchronous recoverable | 
|  | errors. | 
|  |  | 
|  | Synchronous errors refer to those that only happen when a keymgr operation is | 
|  | invoked, while asynchronous refers to errors that can happen at any time. | 
|  | ''', | 
|  | swaccess: "rw1c", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "INVALID_OP", | 
|  | resval: "0x0" | 
|  | desc: "Invalid operation issued to key manager, synchronous error", | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "INVALID_KMAC_INPUT", | 
|  | resval: "0x0" | 
|  | desc: "Invalid data issued to kmac interface, synchronous error", | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "INVALID_SHADOW_UPDATE", | 
|  | resval: "0x0" | 
|  | desc: "An error observed during shadow register updates, asynchronous error", | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "FAULT_STATUS", | 
|  | desc: ''' | 
|  | This register represents both synchronous and asynchronous fatal faults. | 
|  |  | 
|  | Synchronous faults refer to those that only happen when a keymgr operation is | 
|  | invoked, while asynchronous refers to faults that can happen at any time. | 
|  |  | 
|  | ''', | 
|  | swaccess: "ro", | 
|  | hwaccess: "hrw", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "CMD", | 
|  | resval: "0x0" | 
|  | desc: "A non-onehot command was seen in kmac, asynchronous fault.", | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "KMAC_FSM", | 
|  | resval: "0x0" | 
|  | desc: "The kmac transfer interface FSM is in an invalid state, asynchronous fault.", | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "KMAC_DONE", | 
|  | resval: "0x0" | 
|  | desc: "The kmac transfer interface encountered an unexpected done, asynchronous fault.", | 
|  | }, | 
|  | { bits: "3", | 
|  | name: "KMAC_OP", | 
|  | resval: "0x0" | 
|  | desc: "KMAC reported an error during keymgr usage, this should never happen - synchronous fault.", | 
|  | }, | 
|  | { bits: "4", | 
|  | name: "KMAC_OUT", | 
|  | resval: "0x0" | 
|  | desc: "KMAC data returned as all 0's or all 1's - synchronous fault", | 
|  | }, | 
|  | { bits: "5", | 
|  | name: "REGFILE_INTG", | 
|  | resval: "0x0" | 
|  | desc: "Register file integrity error, asynchronous fault", | 
|  | }, | 
|  | { bits: "6", | 
|  | name: "SHADOW", | 
|  | resval: "0x0" | 
|  | desc: "Shadow copy storage error, asynchronous fault", | 
|  | }, | 
|  | { bits: "7", | 
|  | name: "CTRL_FSM_INTG", | 
|  | resval: "0x0" | 
|  | desc: "Control FSM integrity error, asynchronous fault", | 
|  | }, | 
|  | { bits: "8", | 
|  | name: "CTRL_FSM_CHK", | 
|  | resval: "0x0" | 
|  | desc: "Control FSM cross check error, asynchronous fault", | 
|  | }, | 
|  | { bits: "9", | 
|  | name: "CTRL_FSM_CNT", | 
|  | resval: "0x0" | 
|  | desc: "Control FSM counter integrity error, asynchronous fault", | 
|  | }, | 
|  | { bits: "10", | 
|  | name: "RESEED_CNT", | 
|  | resval: "0x0" | 
|  | desc: "Reseed counter integrity error, asynchronous fault", | 
|  | }, | 
|  | { bits: "11", | 
|  | name: "SIDE_CTRL_FSM", | 
|  | resval: "0x0" | 
|  | desc: "Sideload control FSM integrity error, asynchronous fault", | 
|  | }, | 
|  | { bits: "12", | 
|  | name: "SIDE_CTRL_SEL", | 
|  | resval: "0x0" | 
|  | desc: "Sideload control key select error, synchronous fault", | 
|  | }, | 
|  | { bits: "13", | 
|  | name: "KEY_ECC", | 
|  | resval: "0x0" | 
|  | desc: "Secret key ecc error, asynchronous fault", | 
|  | }, | 
|  | ] | 
|  | }, | 
|  |  | 
|  | { name: "DEBUG", | 
|  | desc: ''' | 
|  | The register holds some debug information that may be convenient if keymgr | 
|  | misbehaves. | 
|  | ''', | 
|  | swaccess: "rw0c", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "0", | 
|  | name: "INVALID_CREATOR_SEED", | 
|  | resval: "0x0" | 
|  | desc: "Creator seed failed input checks during operation", | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "INVALID_OWNER_SEED", | 
|  | resval: "0x0" | 
|  | desc: "Owner seed failed input checks during operation", | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "INVALID_DEV_ID", | 
|  | resval: "0x0" | 
|  | desc: "Device ID failed input checks during operation", | 
|  | }, | 
|  | { bits: "3", | 
|  | name: "INVALID_HEALTH_STATE", | 
|  | resval: "0x0" | 
|  | desc: "Health state failed input checks during operation", | 
|  | }, | 
|  | { bits: "4", | 
|  | name: "INVALID_KEY_VERSION", | 
|  | resval: "0x0" | 
|  | desc: "Key version failed input checks during operation", | 
|  | }, | 
|  | { bits: "5", | 
|  | name: "INVALID_KEY", | 
|  | resval: "0x0" | 
|  | desc: "Key fed to kmac failed input checks during operation", | 
|  | }, | 
|  | { bits: "6", | 
|  | name: "INVALID_DIGEST", | 
|  | resval: "0x0" | 
|  | desc: "ROM digest failed input checks during operation", | 
|  | }, | 
|  |  | 
|  | ] | 
|  | }, | 
|  |  | 
|  | ], | 
|  | } |