Improve entropy with PRG310 Hardware RNG on APU1D

10. Final investigations (hopefully :sweat_smile:):

After two weeks of experience I discovered that the PRG310 stops outputting random data every few days and stops working. This is actually on purpose (=feature).

The PRG310 constantly checks the entropy of the data it generates on a hardware level (generated by thermal distortion of Zener diodes). If the entropy does not match the specs it will stop working to prevent from getting less random data without a notice. This behavior might be useful if you do e.g. complex simulations based on random data.

In our case we want a constant random data output and an automated restart. To automatically restart the entropy generation you have to perform the built in selftest. So we need to constantly check the PRG310 and perform the selftest by a cron script.

11. Create cron script (e.g. under /root):

vi /root/p310ctrl.sh

Copy the content into the file:

#!/bin/bash
#PRG310 control script 
#Version 0.1

#Change if necessary
DEVICE="/dev/hwrngtty"

#Log function
logme () {
  logger -t ipfire p310:$1
  echo "$1"
}

#usage
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
        echo "Program to perform PRG310 selftest"
	echo "-h prints this information"
	echo "-v outputs also the PRG310 hardware version"
	echo "Current device is "$DEVICE
	exit 0
fi
logme "Starting PRG310 selftest"
#Check if device is there
if [ ! -L "$DEVICE" ]; then
    logme "$DEVICE does not exist"
    exit 1
fi
#stop rngd
/etc/init.d/rngd stop > /dev/null
ps auwx | grep [r]ngd > /dev/null
if [ $? = 1 ]; then
	logme "Stopping rngd ... OK"
else
	logme "ERROR stopping rngd"
fi
#stop p310
echo e > $DEVICE

#get version if -v
if [ "$1" = "-v" ];then
  #flush buffer
  read -t 1 BUFFER < $DEVICE
  VERSION=""
  (COUNT=0 
  while [ true ]; do 
      echo v > /dev/hwrngtty 
  done) & 
  PID=$!
  read -t 4 VERSION < $DEVICE
  sleep 1
  kill $!
  logme "Version: "$(echo $VERSION)
fi

#flush buffer
read -t 1 BUFFER < $DEVICE

#do selftest
echo t  > $DEVICE
TEST=$(timeout 5 head -c 1 < $DEVICE)
TRYS=$(timeout .1 head -c 1 < $DEVICE)
case "$TRYS" in
          $(echo 0x05 | xxd -r))
	       TRYS=1
	       ;;
	  $(echo 0x04 | xxd -r))
	       TRYS=2
	       ;;
	  $(echo 0x03 | xxd -r))
	       TRYS=3
	       ;;
	  $(echo 0x02 | xxd -r))
	       TRYS=4
	       ;;
	  $(echo 0x01 | xxd -r))
	       TRYS=5
	       ;;
	  *)
	       TRYS="ERROR"
               ;;
esac

if [ "$TEST" = $(echo  0x55 | xxd -r) ]; then
     logme "Selfest: result OK"
elif [ "$TEST" = $(echo 0xaa | xxd -r) ]; then 
     logme "Selftest result: ERROR quality of raw data not sufficiant. Number of tries: $TRYS"
     /bin/stty raw -echo -ixoff -F $DEVICE speed 921600 > /dev/null
else
     logme "Selftest result: ERROR failed"
     /bin/stty raw -echo -ixoff -F $DEVICE speed 921600 > /dev/null
fi
#flush data
read -t 1 BUFFER < $DEVICE
#start random number generation
echo 4b > $DEVICE
DATA=$(timeout 3 xxd -l 2 -p $DEVICE)
if [ "$DATA" != "" ]; then
   logme "Restart random number generation ... OK"
else
   logme "Restart random number generation ... ERROR"
fi
#start rngd
/etc/init.d/rngd start > /dev/null
ps auwx | grep [r]ngd > /dev/null

if [ $? = 0 ]; then
   logme "Starting rngd ... OK"
else
   logme "Starting rngd ... ERROR"
fi

logme "PRG310 selftest done."

make the script executable with:

chmod +x /root/p310ctrl.sh

Execute the script for a test run and check if it works as expected:

/root/p310ctrl.sh

remark: the script has also a -v option which displays the hardware version and a -h option to show some help

12. Add script to cron:

Edit crontab:

fcrontab -e

Add the following line to crontab to execute the script e.g. every 10 minutes and save the changes:

*/10 * * * *	/root/p310ctrl.sh &

13. Now really really enjoy :beers: :sunglasses:

Checking the entropy with β€œent” on a 1MB output of /dev/random gives the following result

Entropy = 7.999833 bits per byte (99.9979125 percent).

Optimum compression would reduce the size
of this 1048576 byte file by 0 percent.

Chi square distribution for 1048576 samples is 243.29, and randomly
would exceed this value 69.05 percent of the times.

Arithmetic mean value of data bytes is 127.4034 (127.5 = random).
Monte Carlo value for Pi is 3.143337797 (error 0.06 percent).
Serial correlation coefficient is 0.000221 (totally uncorrelated = 0.0).
1 Like