[Cryptech Tech] never do in software what can be done in hardware

Fredrik Thulin fredrik at thulin.net
Tue Sep 9 09:09:56 UTC 2014


On Tuesday, September 02, 2014 05:14:34 PM Benedikt Stockebrand wrote:
...
> > 2. Comparing the amplified noise from my design and Benedikts shows that
> > my
> > noise is... duller than Benedikts. See attached screenshot - my noise in
> > yellow and Benedikts in blue.
> 
> I've spent quite some time tweaking the various parameters with the
> generator core (Zener and first transistor); maybe you want to take a
> closer look at it?

I've made every attempt I can at replicating the noise source and amplifier 
(but with SMD components), and I can't quite get as high frequency on the 
noise as I observe on the ARRGH board - but I don't think it is really 
important at this stage.

...
> > That's when I realized there is a timer operation called "capture" which
> > seems ideal for this use case. When a state transition is observed on an
> > input pin (i.e. noise goes from low to high, high to low or both), the
> > MCU will actually "freeze" the 16 MHz counter value into a register in
> > hardware that I can busy- wait looking for.
> 
> That sounds rather good; only downside is that if we use these sorts of
> features it will be more difficult to diversify to different MCU
> architectures.

Yes, it sounded too good to be true. And it was.

This reply is so late because I've been slowly working my way through a brick 
wall of not-really-working using my forehead only.

It turns out that the counters the MSP430 I've been using are not "double 
buffered" (msp430f2132, Timer A), meaning that the counter values can actually 
be updated at the same time as I'm reading them. Decidedly not good.

> > I extracted 646k timer deltas, and they look plausibly good to me,
> > although
> > more data is needed to be conclusive. The X axis of the attached graph is
> > the delta between two consecutive transitions measured in 16 MHz steps.
>
> That's still rather slow---I have less than 50 clock cycles on average
> per noise bit read.

Yes, I optimized it and cleaned out some cruft so that I could actually enable 
inlining without overflowing the code segment and got it down to an average of 
29 clock cycles (at 16 MHz), with 95% being 60 cycles or less.

This accentuated the underlying issue with the timer I mentioned above, and 
produced the first timer delta graph attached (rev06_2N3904_15or12v_8MHz.png).
I'm now fairly certain that the knuckles on the left side of the peak (the 
highest frequencies) are caused by these partial read errors of the counter 
values.

If I slow things down with some strategically placed NOPs, so I actually miss 
(most of) the highest frequencies, the graph smooths out.

If I use 10v instead of 12 (or 15, as is available on my new rev06 board), the 
noise slows down and I get a very smooth graph (rev03_2N3904_10v.png), but 
also much slower operation.

I got myself an AVR ISP in order to be able to get timer deltas directly from 
an otherwise unmodified ARRGH board. Attached as ARRGH_10M_entrys.png.
The curve is rather smooth, and I guess the evenly spaced values (3 apart) are 
an effect of the polling loop.

I can get a pretty much identical graph by polling too, although I don't use 
the timer counter at all but rather just count the number of times I loop so 
there are fewer discrete values in the graph. See 
rev06_2N3904_15v_8MHz_count_loops.png.

I'm still experimenting to try and find the best way to extract entropy with 
this hardware. IMO the quality of the output has to be excellent, and then it 
doesn't hurt if I can get the speed up too.

/Fredrik



PS. This is the modification I made to ARRGH firmware:

inline uint8_t byte_generator_next_deltas(void)
{
  register uint8_t start, stop;

  wait_for_rising_edge(); // Ensure we have a defined starting point...
  start = TCNT0;
  wait_for_rising_edge();
  stop = TCNT0;
  if (stop < start) {
    /* 8 bit counter wrap around.
     * Example: start = 0xff, stop = 0x1. Delta is 2.
     */
    return (0xff - start) + stop + 1;
  }
  return (stop - start); /* Return delta between start time and now */
}

and then I call that instead of byte_generator_next() in the while-loop in 
main().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rev06_2N3904_15or12v_8MHz.png
Type: image/png
Size: 25861 bytes
Desc: not available
URL: <https://lists.cryptech.is/archives/tech/attachments/20140909/092ec1cc/attachment-0004.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rev03_2N3904_10v.png
Type: image/png
Size: 33944 bytes
Desc: not available
URL: <https://lists.cryptech.is/archives/tech/attachments/20140909/092ec1cc/attachment-0005.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ARRGH_10M_entrys.png
Type: image/png
Size: 19002 bytes
Desc: not available
URL: <https://lists.cryptech.is/archives/tech/attachments/20140909/092ec1cc/attachment-0006.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rev06_2N3904_15v_8MHz_count_loops.png
Type: image/png
Size: 21056 bytes
Desc: not available
URL: <https://lists.cryptech.is/archives/tech/attachments/20140909/092ec1cc/attachment-0007.png>


More information about the Tech mailing list