| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| { name: "KEYMGR", |
| clock_primary: "clk_i", |
| other_clock_list: [ "clk_edn_i" ] |
| reset_primary: "rst_ni", |
| other_reset_list: [ "rst_edn_ni" ] |
| bus_interfaces: [ |
| { protocol: "tlul", direction: "device" } |
| ], |
| interrupt_list: [ |
| { name: "op_done", desc: "Operation complete" }, |
| ], |
| alert_list: [ |
| { name: "fatal_fault_err", |
| desc: "Alert for key manager faults. These errors cannot be caused by software", |
| }, |
| { name: "recov_operation_err", |
| desc: ''' |
| Alert for key manager operation errors. These errors could have been caused by |
| software''' |
| } |
| ], |
| |
| // Define keymgr <-> kmac / aes / hmac struct packages |
| 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", // hmac_key_req_t |
| type: "uni", |
| name: "hmac_key", // hmac_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: "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" |
| }, |
| ], |
| |
| param_list: [ |
| // 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: "RndCnstHmacSeed", |
| desc: "Compile-time random bits for generation seed when hmac 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: "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" |
| }, |
| ], |
| |
| regwidth: "32", |
| registers: [ |
| { name: "CFG_REGWEN", |
| desc: "Key manager configuration enable", |
| swaccess: "ro", // this particular lock is meant to be fully 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. |
| |
| TBD |
| This should be enhanced to support multi-bit values in the future. Should be another script change. |
| ''' |
| }, |
| ] |
| }, |
| |
| { name: "CONTROL", |
| desc: "Key manager operation controls", |
| regwen: "CFG_REGWEN", |
| swaccess: "rw", |
| hwaccess: "hro", |
| fields: [ |
| { bits: "0", |
| hwaccess: "hrw", |
| name: "START", |
| 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"] |
| }, |
| |
| { 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: "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: "HMAC", |
| desc: ''' |
| HMAC selected |
| ''' |
| }, |
| { value: "3", |
| name: "KMAC", |
| desc: ''' |
| KMAC selected |
| ''' |
| }, |
| ] |
| }, |
| ], |
| }, |
| |
| { name: "SIDELOAD_CLEAR", |
| desc: "Clear all sideload keys", |
| swaccess: "rw", |
| hwaccess: "hro", |
| fields: [ |
| { bits: "0", |
| name: "VAL", |
| resval: "0" |
| desc: ''' |
| When 1, the sideload keys are continuously cleared with entropy. |
| When 0, the sideload keys are left as is. |
| ''' |
| }, |
| ] |
| }, |
| |
| { name: "RESEED_INTERVAL", |
| desc: "reseed interval for key manager entropy reseed", |
| 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. |
| ''' |
| }, |
| ] |
| tags: [// when it's set, it can't be modified until the next advance operation completes |
| "excl:CsrNonInitTests:CsrExclWrite"] |
| }, |
| |
| { multireg: { |
| cname: "KEYMGR", |
| name: "SW_BINDING", |
| regwen: "SW_BINDING_REGWEN", |
| desc: ''' |
| Software binding input to 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: ''' |
| Salt value |
| ''', |
| 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. |
| All values except for 2 are interpreted as configuration disable. |
| ''' |
| }, |
| ] |
| }, |
| |
| { name: "MAX_CREATOR_KEY_VER", |
| desc: "Max creator key version", |
| swaccess: "rw", |
| hwaccess: "hro", |
| 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. |
| All values except for 2 are interpreted as configuration disable. |
| ''' |
| }, |
| ] |
| }, |
| |
| { name: "MAX_OWNER_INT_KEY_VER", |
| desc: "Max owner intermediate key version", |
| swaccess: "rw", |
| hwaccess: "hro", |
| 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. |
| All values except for 2 are interpreted as configuration disable. |
| ''' |
| }, |
| ] |
| }, |
| |
| { name: "MAX_OWNER_KEY_VER", |
| desc: "Max owner key version", |
| swaccess: "rw", |
| hwaccess: "hro", |
| 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" |
| }, |
| ], |
| }, |
| }, |
| |
| { 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" |
| }, |
| ], |
| }, |
| }, |
| |
| { 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. |
| Software clears by writing back whatever it reads. |
| ''', |
| swaccess: "rw1c", |
| hwaccess: "hrw", |
| fields: [ |
| { bits: "0", |
| name: "INVALID_OP", |
| resval: "0x0" |
| desc: "Invalid operation issued to key manager", |
| }, |
| { bits: "1", |
| name: "INVALID_CMD", |
| resval: "0x0" |
| desc: "Invalid command issued from key manager to kmac interface", |
| }, |
| { bits: "2", |
| name: "INVALID_KMAC_INPUT", |
| resval: "0x0" |
| desc: "Invalid data issued to kmac interface", |
| }, |
| { bits: "3", |
| name: "INVALID_KMAC_DATA", |
| resval: "0x0" |
| desc: "Invalid data returned from kmac interface.", |
| }, |
| ] |
| }, |
| ], |
| } |