lowRISC / lowRISC/opentitan

[csrng] Return error status response for GEN commands with glen = 0

Open
#23,846 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Component:RTL Type:Enhancement Type:FutureRelease
Dominant language
SystemVerilog
Stars
3.6k
Forks
1.1k
Avg merge
2d 22h
Merged PRs (30d)
141

Description

### Description

When taking care of #18350, I found out that CSRNG treats Generate commands with a glen = 0 similarly to commands with a glen = 1, i.e., it generates one single 128-bit block of random data instead of nothing.

I don't think this is a bug really because the [CSRNG documentation](https://opentitan.org/book/hw/ip/csrng/doc/theory_of_operation.html#command-header) specifies:
> Generate Length: Only defined for the generate command, this field is the total number of cryptographic entropy blocks requested. Each unit represents 128 bits of entropy returned. This field allows values between 1 and 4095. A value of 1 returns 1 * 128 bits of entropy. A value of 4095 returns 4095 * 128 bits of entropy, which is less than the 219 bits allowed by NIST (referenced to as max_number_of_bit_per_request).

and further:
> The glen field defines how many 128-bit words are to be returned to the application interface. The glen field needs to be a minimum value of one.

In terms of the NIST spec, we are a bit in a gray area here. NIST SP 800-90Ar1 says
![Screenshot from 2024-06-28 15-32-01](https://github.com/lowRISC/opentitan/assets/20307557/a7587243-003d-4232-9bec-71fc51b0e77b)

What the `returned_bits` actually is if `requested_number_of_bits` = 0 isn't clear.

Right now, CSRNG produces one 128-bit block and also the following CTR_DRBG_Update is done and the reseed counter is incremented. I think this behavior is not intended from an RTL perspective. When receiving the Generate command in the command stage, there is just a check for `glen = 1`:
https://github.com/lowRISC/opentitan/blob/9cfd621ac24593a8f9cdd5482c933b39e8e13cf1/hw/ip/csrng/rtl/csrng_cmd_stage.sv#L378-L391

And then also the `u_prim_count_cmd_gen_cntr` output is compared against 1 again. But there is no check against 0. I think the current behavior is a coincidence.

Now that we have the capability to signal error status responses, it would probably be better to change the design to return an error response when receiving a Generate command with glen = 0.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in hw/ip/csrng/rtl/csrng_cmd_stage.sv at the command-stage checks around lines 378-391, and inspect the u_prim_count_cmd_gen_cntr comparison. Trace how a Generate command with glen = 0 currently produces data, performs CTR_DRBG_Update, and increments the reseed counter. Done means such a command returns an error status response without generating a block or performing those updates.

Written by the indexing model from the issue text.

Assessment

Domain
cryptography, embedded-iot, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.