Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10. Unique identification and randomness source #25

Open
4 tasks
BeataZdunczyk opened this issue Aug 17, 2023 · 2 comments
Open
4 tasks

10. Unique identification and randomness source #25

BeataZdunczyk opened this issue Aug 17, 2023 · 2 comments

Comments

@BeataZdunczyk
Copy link
Member

Each TPM has to be uniquely identifiable. This uniqueness is used e.g. to create primary seeds which are used to derive primary keys for various hierarchies. Random number generator is also included in this task - unique registers (with e.g. serial numbers) and RNG engines are usually specific to the given hardware. FPGA can also be used if any of those isn't available or doesn't have enough entropy on MCU.

Milestones:

  • find and obtain enough bits of unique data identifying the platform
  • find and obtain enough bits of entropy for seeding PRNG
  • test suite: Windows HLK
  • review and update existing documentation, add entry to changelog
@arturkow2
Copy link
Contributor

arturkow2 commented Mar 14, 2024

Due to problems with implementation unique identification, we have to postpone the point find and obtain enough bits of unique data identifying the platform.
For now I created Dasharo/twpm-firmware#7 which allows to set unique value in the firmware, this is a temporary workaround.

Most of information from the attempt is described here, but I'm going to summarize what we tried and what we might do in the future.

We tried to implement PUF (Physically Uncloneable Function), details of PUF implementation are described in the link I provided above. Unfortunately, PUF turned out to be unstable, making it impossible to obtain unique ID. Future plans may involve locating the cause for PUF instability and fixing it, evaluating other PUF techniques, or evaluating other methods. One of methods discussed before was usage of the encrypted bitstream feature, so that unique ID could be hidden in the bitstream itself. However, this requires the bitstream encryption key to be programmed into OTP which is an irreversible operation. Open-source toolchain currently does not support OTP programming, so reliance on encrypted bitstream would require users to use Diamond and one of Diamond-supported JTAG probes. Lattice provides documentation which could be used to implement OTP programming, however doing that requires massive effort. If OTP becomes supported by Trellis, encrypted bitstream method could re-evaluated.

arturkow2 pushed a commit to Dasharo/twpm-firmware that referenced this issue Mar 14, 2024
Allow to set constant unique value through Kconfig, the value will be
contained in binary and will be the same for all devices. This is
intented as testing or for platform bringup, where unique data cannot be
obtained through HWINFO or other interfaces.

Enable this by default on OrangeCrab as we don't support generating
per-platform unique-ID yet.

See Dasharo/twpm-docs#25 (comment)
for details.
@arturkow2
Copy link
Contributor

arturkow2 commented Apr 2, 2024

Dasharo/zephyr#2 brings TRNG support. With TRNG we have proper entropy source and we no longer depend on cryptographically-unsafe PRNG. On Orangecrab TRNG is enabled by default. We also updated to latest Zephyr in Dasharo/zephyr#2, and fixed a long-standing bug - sysinfo driver which is used for detecting what peripherals are present, had wrong bitfield definitions (for a very old version of Neorv32).

Dasharo/zephyr#2 adds code for dumping random data, which can be enabled using CONFIG_TWPM_RNG_TEST Kconfig option. This was initially implemented as Zephyr shell command, but due to broken UART after Zephyr update, it is currently executed at boot when CONFIG_TWPM_RNG_TEST is enabled instead of executing normal TwPM flow.

I collected 4 MiB of random data over two runs and as a simple test I used rngtest over that data:

rngtest: starting FIPS tests...
rngtest: entropy source drained
rngtest: bits received from input: 16777216
rngtest: FIPS 140-2 successes: 838
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=706.425; avg=21805.705; max=19073.486)Mibits/s
rngtest: FIPS tests speed: (min=81.511; avg=193.230; max=235.475)Mibits/s
rngtest: Program run time: 84128 microseconds

rngtest: starting FIPS tests...
rngtest: entropy source drained
rngtest: bits received from input: 16777216
rngtest: FIPS 140-2 successes: 838
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=1.693; avg=22.491; max=18.626)Gibits/s
rngtest: FIPS tests speed: (min=111.541; avg=209.844; max=235.475)Mibits/s
rngtest: Program run time: 77648 microseconds

And both tests succedeed without failures. However, please note those were simple tests, we have not tested TRNG against temperature/voltage variations etc.

I attach the data for further evaluation, if ever needed
neotrng_.zip

TRNG was tested on updated neorv32 from Dasharo/TwPM_toplevel#30, but with cache disabled by setting XBUS_CACHE_EN => false in fpga/neorv32_wrapper_orangecrab.vhd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants