| // Copyright lowRISC contributors. | 
 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
 | // SPDX-License-Identifier: Apache-2.0 | 
 | { | 
 |   name:               "hmac", | 
 |   human_name:         "HMAC Accelerator", | 
 |   one_line_desc:      "Accelerator for SHA-256-based keyed hash message authentication code and the SHA-256 hash function", | 
 |   one_paragraph_desc: ''' | 
 |   HMAC Accelerator is a keyed hash based message authentication code generator using [SHA-256][nist-fips-180-4] to check the integrity of an incoming message and optionally a signature signed with the same secret key. | 
 |   This HMAC implementation is not hardened against side-channel analysis (SCA) or fault injection (FI) attacks; it is meant purely for hashing acceleration. | 
 |   If hardened MAC operations are required, either KMAC Accelerator or a software implementation should be used. | 
 |  | 
 |   [nist-fips-180-4]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | 
 |   ''' | 
 |   design_spec:        "../doc", | 
 |   dv_doc:             "../doc/dv", | 
 |   hw_checklist:       "../doc/checklist", | 
 |   sw_checklist:       "/sw/device/lib/dif/dif_hmac", | 
 |   revisions: [ | 
 |     { | 
 |       version:            "0.5", | 
 |       life_stage:         "L2", | 
 |       design_stage:       "D3", | 
 |       verification_stage: "V3", | 
 |       commit_id:          "635afdb8dedbb50c235bd772b36002925c499884", | 
 |       notes:              "" | 
 |     } | 
 |     { | 
 |       version:            "1.0", | 
 |       life_stage:         "L1", | 
 |       design_stage:       "D3", | 
 |       verification_stage: "V2", | 
 |       dif_stage:          "S2", | 
 |       notes:              "", | 
 |     } | 
 |   ] | 
 |   clocking: [{clock: "clk_i", reset: "rst_ni", idle: "idle_o"}], | 
 |   bus_interfaces: [ | 
 |     { protocol: "tlul", direction: "device" } | 
 |   ], | 
 |   interrupt_list: [ | 
 |     { name: "hmac_done", | 
 |       desc: "HMAC-256 completes a message with key" | 
 |     } | 
 |     { name: "fifo_empty", | 
 |       desc: "Message FIFO empty condition" | 
 |     } | 
 |     { name: "hmac_err", | 
 |       desc: "HMAC error occurred. ERR_CODE register shows which error occurred" | 
 |     } | 
 |   ], | 
 |   alert_list: [ | 
 |     { name: "fatal_fault", | 
 |       desc: ''' | 
 |       This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. | 
 |       ''' | 
 |     } | 
 |   ], | 
 |   inter_signal_list: [ | 
 |     { name:    "idle", | 
 |       type:    "uni", | 
 |       act:     "req", | 
 |       package: "prim_mubi_pkg", | 
 |       struct:  "mubi4", | 
 |       width:   "1" | 
 |     } | 
 |   ], | 
 |   param_list: [ | 
 |     { name:    "NumWords", | 
 |       type:    "int", | 
 |       default: "8", | 
 |       desc:    "Number of words for digest/ key", | 
 |       local:   "true" | 
 |     } | 
 |   ], | 
 |   countermeasures: [ | 
 |     { name: "BUS.INTEGRITY", | 
 |       desc: "End-to-end bus integrity scheme." | 
 |     } | 
 |   ] | 
 |   regwidth: "32", | 
 |   registers: [ | 
 |     { name: "CFG", | 
 |       desc: '''HMAC Configuration register. | 
 |  | 
 |             The register is updated when the engine is in Idle. | 
 |             If the software updates the register while the engine computes the hash, | 
 |             the updated value is discarded. | 
 |             ''', | 
 |       hwext:    "true", | 
 |       hwqe:     "true", | 
 |       swaccess: "rw", | 
 |       hwaccess: "hrw", | 
 |       fields: [ | 
 |         { bits: "0", | 
 |           name: "hmac_en", | 
 |           desc: '''HMAC datapath enable. | 
 |  | 
 |                 If this bit is 1, HMAC operates when `hash_start` toggles. | 
 |                 ''', | 
 |           tags: [// don't enable hmac and sha data paths - we will do that in functional tests | 
 |                  "excl:CsrNonInitTests:CsrExclWrite"] | 
 |         } | 
 |         { bits: "1", | 
 |           name: "sha_en", | 
 |           desc: '''SHA256 enable. If 0, SHA engine won't initiate compression, | 
 |                 this is used to stop operation of the SHA engine until configuration | 
 |                 has been done. When the SHA engine is disabled the digest is cleared.''' | 
 |           tags: [// don't enable hmac and sha data paths - we will do that in functional tests | 
 |                  "excl:CsrNonInitTests:CsrExclWrite"] | 
 |         } | 
 |         { bits: "2", | 
 |           name: "endian_swap", | 
 |           desc: '''Endian swap. | 
 |  | 
 |                 If 0, each value will be added to the message in little-endian | 
 |                 byte order. The value is written to MSG_FIFO same to the SW writes. | 
 |  | 
 |                 If 1, then each individual multi-byte value, regardless of its | 
 |                 alignment, written to !!MSG_FIFO will be added to the message | 
 |                 in big-endian byte order. | 
 |  | 
 |                 A message written to !!MSG_FIFO one byte at a time will not be | 
 |                 affected by this setting. | 
 |  | 
 |                 From a hardware perspective byte swaps are performed on a TL-UL | 
 |                 word granularity. | 
 |                 ''', | 
 |           resval: "0", | 
 |         } | 
 |         { bits: "3", | 
 |           name: "digest_swap", | 
 |           desc: '''Digest register byte swap. | 
 |  | 
 |                 If 1 the value contained in each digest output register is | 
 |                 converted to big-endian byte order. | 
 |                 This setting does not affect the order of the digest output | 
 |                 registers, !!DIGEST_0 still contains the first 4 bytes of | 
 |                 the digest. | 
 |                 ''', | 
 |           resval: "0", | 
 |         } | 
 |       ] | 
 |     } | 
 |     { name: "CMD", | 
 |       desc: "HMAC command register", | 
 |       swaccess: "r0w1c", | 
 |       hwaccess: "hro", | 
 |       hwext: "true", | 
 |       hwqe:  "true", | 
 |       tags: [// design assertion : after hash_start sets, can only wr msg or set hash_process | 
 |              // design assertion : hash_process can be set only after hash_start is set | 
 |              "excl:CsrAllTests:CsrExclWrite"] | 
 |       fields: [ | 
 |         { bits: "0", | 
 |           name: "hash_start", | 
 |           desc: '''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: "1", | 
 |           name: "hash_process", | 
 |           desc: '''If writes 1 into this field, SHA256 or HMAC calculates the digest or signing | 
 |                 based on currently received message. | 
 |                 ''' | 
 |         } | 
 |       ], | 
 |     } | 
 |     { name: "STATUS", | 
 |       desc: "HMAC Status register", | 
 |       swaccess: "ro", | 
 |       hwaccess: "hwo", | 
 |       hwext: "true", | 
 |       fields: [ | 
 |         { bits: "0", | 
 |           name: "fifo_empty", | 
 |           desc: "FIFO empty", | 
 |           resval: "1" | 
 |         } | 
 |         { bits: "1", | 
 |           name: "fifo_full", | 
 |           desc: "FIFO full. Data written to the FIFO whilst it is full will cause back-pressure on the interconnect" | 
 |         } | 
 |         { bits: "8:4", | 
 |           name: "fifo_depth", | 
 |           desc: "FIFO entry count." | 
 |         } | 
 |       ] | 
 |     } | 
 |     { name: "ERR_CODE", | 
 |       desc: "HMAC Error Code", | 
 |       swaccess: "ro", | 
 |       hwaccess: "hwo", | 
 |       fields: [ | 
 |         { bits: "31:0", | 
 |           name: "err_code", | 
 |           desc: '''If error interrupt occurs, this register has information of error cause. | 
 |                 Please take a look at `hw/ip/hmac/rtl/hmac_pkg.sv:err_code_e enum type. | 
 |                 ''' | 
 |           tags: [// Randomly write mem will cause this reg updated by design | 
 |                  "excl:CsrNonInitTests:CsrExclCheck"] | 
 |         } | 
 |       ] | 
 |     } | 
 |     { name: "WIPE_SECRET", | 
 |       desc: '''Randomize internal secret registers. | 
 |  | 
 |             If CPU writes value into the register, the value is used to randomize internal | 
 |             variables such as secret key, internal state machine, or hash value. | 
 |             ''', | 
 |       swaccess: "wo", | 
 |       hwaccess: "hro", | 
 |       hwext: "true", | 
 |       hwqe: "true", | 
 |       fields: [ | 
 |         { bits: "31:0", name:"secret", desc: "Secret value" } | 
 |       ] | 
 |     } | 
 |     { multireg: { | 
 |         name: "KEY", | 
 |         desc: '''HMAC Secret Key | 
 |  | 
 |               SHA256 assumes secret key is hashed 256bit key. | 
 |               Order of the secret key is: | 
 |               key[255:0] = {KEY0, KEY1, KEY2, ... , KEY7}; | 
 |  | 
 |               The registers are allowed to be updated when the engine is in Idle state. | 
 |               If the engine computes the hash, it discards any attempts to update the secret keys | 
 |               and report an error. | 
 |               ''', | 
 |         count: "NumWords", | 
 |         cname: "HMAC", | 
 |         hwext: "true", | 
 |         hwqe : "true", | 
 |         swaccess: "wo", | 
 |         hwaccess: "hrw", | 
 |         fields: [ | 
 |           { bits: "31:0", name: "key", desc: "32-bit chunk of 256-bit Secret Key" } | 
 |         ], | 
 |       } | 
 |     } | 
 |     { multireg: { | 
 |         name: "DIGEST", | 
 |         desc: '''Digest output. If HMAC is disabled, the register shows result of SHA256 | 
 |  | 
 |                Order of the digest is: | 
 |                digest[255:0] = {DIGEST0, DIGEST1, DIGEST2, ... , DIGEST7}; | 
 |                ''', | 
 |         count: "NumWords", | 
 |         cname: "HMAC", | 
 |         swaccess: "ro", | 
 |         hwaccess: "hwo", | 
 |         hwext: "true", | 
 |         fields: [ | 
 |           { bits: "31:0", name: "digest", desc: "32-bit chunk of 256-bit Digest" } | 
 |         ] | 
 |       } | 
 |     } | 
 |     { name: "MSG_LENGTH_LOWER", | 
 |       desc: '''Received Message Length calculated by the HMAC in bits [31:0] | 
 |  | 
 |             Message is byte granularity. | 
 |             lower 3bits [2:0] are ignored.''', | 
 |       swaccess: "ro", | 
 |       hwaccess: "hwo", | 
 |       fields: [ | 
 |         { bits: "31:0", name: "v", desc: "Message Length [31:0]" } | 
 |       ] | 
 |     } | 
 |     { name: "MSG_LENGTH_UPPER", | 
 |       desc: "Received Message Length calculated by the HMAC in bits [63:32]", | 
 |       swaccess: "ro", | 
 |       hwaccess: "hwo", | 
 |       fields: [ | 
 |         { bits: "31:0", name: "v", desc: "Message Length [63:32]" } | 
 |       ] | 
 |     } | 
 |     { skipto: "0x800" } | 
 |     { window: { | 
 |         name: "MSG_FIFO" | 
 |         items: "512"      // 2kB | 
 |         swaccess: "wo", | 
 |         byte-write: "true", | 
 |         desc: '''Message FIFO. Any write to this window will be appended to the FIFO. Only the lower [1:0] bits of the address matter to writes within the window (for correctly dealing with non 32-bit writes) | 
 |               ''' | 
 |       } | 
 |     } | 
 |   ], | 
 | } |