External hardware random number generator for the BeagleBone Black

The Hashlet software is scheduled for beta release on January 1st! It’s been a busy month preparing the software and hardware, but it’s finally coming together. I’m waiting until I have a releasable Beta before making the hardware available for purchase. The Hashlet is a secure authentication device that performs the SHA-256 algorithm in hardware. It also stores 256 bit keys in its EEPROM, which can’t be read once written. This enables a keyed hash ability with a Message Authentication Code (MAC), which provides message integrity and authenticity. In the rest of this post, I’ll walk you through how to personalize the device and how to use the hardware random number generator.

The Hashlet test bed.  I'm currently using the breakout board, but the production units are the bottom right with the I2C test points.
The Hashlet test bed. I’m currently using the breakout board, but the production units are the bottom right with the I2C test points.

The Hashlet ships in a factory state, meaning that unique keys haven’t yet been loaded. This is important because I do not know your keys!. You should verify that the Hashlet is in its factory state upon receipt with the following command.  This assumes you are using pins P19 and P20 on the P_9 header.  If you are new to the I2C protocol or using I2C in GNU/Linux on the BeagleBone Black, check out my I2C references.

./hashlet /dev/i2c-1 state
Factory

To personalize the device to you, you need to fill it with keys. The keys will be randomly generated by the on-chip hardware random number generator. The software will write your keys to ./hashlet, so don’t lose that file. The command to personalize the device is:

debian@arm:~/repos/hashlet$ ./hashlet /dev/i2c-1 personalize
debian@arm:~/repos/hashlet$ echo $?
0
debian@arm:~/repos/hashlet$ ./hashlet /dev/i2c-1 state
Personalized

Upon success, the command line interface is silent but returns a status code of 0. You can check the device’s state by running the state command.

Now let’s do something fun and pull some random data from the device:

debian@arm:~/repos/hashlet$ ./hashlet /dev/i2c-1 random
9763F9499B7545C7262AE39A4B1E10C17F716BD5BC08380A151A2F7F15549FC8
debian@arm:~/repos/hashlet$ ./hashlet /dev/i2c-1 random
9B0EB5CE000E691E146A03EF8601D8AC069771841FF6E59EE93ABCBCF62473F0
debian@arm:~/repos/hashlet$ ./hashlet /dev/i2c-1 random --update-seed
84F61D234A0BD86303FA7194DE60D6184052FF85725006407BD50F58A5A66E68

Using the –update-seed option will update the random seed on the device.

What’s the pedigree of this random data? Let’s use the rng-tools package to run some tests. rng-tools requires 20,000 bits of random data so we are going to need a helper script:

#!/bin/bash

result=""

while [[ ${#result} -lt 5000 ]]; do
 random=$(./hashlet /dev/i2c-1 random)
 result=$result$random
done

echo $result

20,000 bits is 2500 bytes, but each byte is printed as two ASCII characters, so we need to pull 5000 characters from the Hashlet.  The Hashlet software outputs ASCII, so we need some pipelines:

debian@arm:~/repos/hashlet$ ./src/tests/random.sh | sed 's/.{2}/& /g' | xxd -r -p | rngtest -c 1
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 20032
rngtest: FIPS 140-2 successes: 1
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=681.196; avg=681.196; max=681.196)Mibits/s
rngtest: FIPS tests speed: (min=2.680; avg=2.680; max=2.680)Mibits/s
rngtest: Program run time: 4400494 microseconds

Not bad! It passes the FIPS 140-2 test. I’ll have to measure the speed on the bus to confirm the speed results. It’s obviously slower on the I2C bus than /dev/urandom/ directly:

debian@arm:~/repos/hashlet$ cat /dev/urandom | rngtest -c 1
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 20032
rngtest: FIPS 140-2 successes: 1
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=657.706; avg=657.706; max=657.706)Mibits/s
rngtest: FIPS tests speed: (min=1.980; avg=1.980; max=1.980)Mibits/s
rngtest: Program run time: 76412 microseconds

In the next post, I’ll show how to perform and verify MACs with the Hashlet. Stay tuned and be sure to follow this blog for automatic updates!

3 thoughts on “External hardware random number generator for the BeagleBone Black

Comments are closed.