views:

77

answers:

4

I have an embedded system. What I would like for it to do when it powers up or otherwise resets, is to generate a unique ID, so that on different restarts a different unique ID is generated with high probability.

It does not have access to a real-time clock, but it does have access to an ADC and a UART. I am wondering if there is a decent way to gather entropy from these sources to generate a unique ID. I am vaguely familiar with Yarrow. Is there a good way to use this?

Unfortunately I do not have any noise sources of predictable characteristics; the ADC is connected to a number of relatively-low-noise inputs, so I suppose I could just use the least-significant bits of the ADC as inputs.

edit: for what it's worth, this is the TI TMS320F28335 processor.

+6  A: 

I've used:

  • the lowest bit of a floating ADC input, but you touched on that

  • an extremely high-resolution timer (~10ns), and taken the lowest "n" bits when timing between user keypresses. If you accept that user keypresses (at the highest timing resolution) are effectively random in their timing, it works pretty well.

You could also time things like time between network packets, etc. but those can be a lot more deterministic/predictable than what a lot of people thing. Electrical noise and user interaction are better sources of entropy.

By the way, on the "timings between keypresses" stuff, I tend to store those on an embedded system starting at power-on, in a circular buffer of the last 8 or so, because you never know when you're going to need them. (IN other words: Don't wait until you need the random bits, and then force the user to press buttons 3 times!)

Dan
A: 

Minor addition to Dan's answer above... If your system includes some sort of radio you can take an RSSI reading.

Mike D.
+1  A: 

It depends:

  • What degree of uniqueness do you want?
  • Is there any non-volatile storage?
  • How soon do you need an answer?

If you have flash/NVRAM/disk, read your random seed, increment it, and write it back. The seed can be a simple counter if you don't require uniqueness between devices/reflashing/NVRAM battery running out. If you want uniqueness, then once you've gathered "enough" entropy, rewrite the seed.

(Obviously you might want to do something else if you're using flash and your flash controller doesn't have wear-levelling, or implement your own wear-levelling.)

If you don't, then collect entropy from all the sources you can, and only generate the UUID after you have enough entropy. Zvi Gutterman (2006) notes that OpenWRT's only source of entropy is network access, which is easily observed.

Using ADC output seems sensible, with some simple guidelines:

  • Use all the bits (or at least more bits than your entropy estimate), but increase your entropy estimate conservatively.
  • ADC output has zero entropy when clipped (and possibly low entopy when nearly clipped).

Measure the amount of noise on the input. I suspect you'll get at least one bit per sample. Then hash your bits and generate a version 4 UUID.

tc.
A: 

I have done something similar to Dan's answer. I had a buffer in non volatile memory with the timer difference using a high resolution timer (20ns) between user keystrokes containing the last 256 keystrokes times. I then compute a 32 bit CRC to get a unique number each time the system is power on. Some versions without user interaction measured the time between message received on the serial ports

These unique numbers was used as node identifiers on a network and there has never been any problems with duplicates.

This was later augmented with a DS2401 that provided a persistent but unique ID but this would only work for you if you can change the hardware.

Gerhard