Open BeataZdunczyk opened 1 year ago
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 https://github.com/Dasharo/twpm-firmware/pull/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.
https://github.com/Dasharo/zephyr/pull/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 https://github.com/Dasharo/zephyr/pull/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).
https://github.com/Dasharo/zephyr/pull/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 https://github.com/Dasharo/TwPM_toplevel/pull/30, but with cache disabled by setting XBUS_CACHE_EN => false
in fpga/neorv32_wrapper_orangecrab.vhd
.
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: