How can I use NeuG standalone device on my Debian box?

Q: I got FST-01 with NeuG, that is, the NeuG standalone device. How can I use it on my PC (with Debian installed)?

Description from NeuG doc

How to use NeuG

NeuG runs as USB CDC/ACM (Communication Device Class / Abstract Control Model) device.

No special driver is required on GNU/Linux. You can just access /dev/ttyACM? (e.g., /dev/ttyACM0) to get random byte stream.

The USB CDC/ACM (Communication Device Class / Abstract Control Model) is used primarily for modems. If you are using some control program for your modems, you need to configure it, so that it won't interfere NeuG device.

If you are not using modems with such a control program, you may simply remove modem management package from your system to avoid interference. For example, remove the package "modemmanager", when you are using Debian GNU/Linux.

UPDATE (2015-12-04): It seems that recent version of "modemmanager" only control registered devices. In this case, you don't need to remove the "modemmanager" package.

Alternatively, when you don't want to remove modemmanager, you can add the line:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0001", ENV{ID_MM_DEVICE_IGNORE}="1"

in your /etc/udev/rules.d/90-neug.rules, so that modemmanager won't try to control NeuG Device.

Configuration of tty line discipline

Don't forget to configure tty line disciple to get correct data. Between the device and application, there is "tty line discipline" which might interpret and translate the stream (newline, eof, etc.). This functionality should be disabled.

Using stty command, please configure the line discipline with no echo and raw mode.:

$ stty -F /dev/ttyACM0 -echo raw -parenb

You can select filter by parity settings.

  • Even parity (parenb -parodd) means: Raw ADC sample data

    $ stty -F /dev/ttyACM0 parenb -parodd
    
  • Odd parity (parenb parodd) means: Only CRC32 filter

    $ stty -F /dev/ttyACM0 parenb parodd
    
  • No parity (-parenb): CRC32 filter + SHA256 filter

    $ stty -F /dev/ttyACM0 -parenb
    

Example command to get random output

For example, you can get random bytes of 1MiB to the file "output" by typing:

$ dd bs=1024 if=/dev/ttyACM0 iflag=fullblock count=1024 of=output

Answers for rng-tools

Please note that following examples assumes Debian GNU/Linux, where the rng-tools in Debian is a kind of fork. The syntax such as --fill-watermark is different and it supports --feed-interval option.

Systemd 2014-01-12 15:13:54 +0900 -- gniibe

With systemd, here are settings for rng-tools. /etc/udev/rules.d/90-neug.rules:

# Given 60-persistent-serial.rules, this should be > 60.

KERNEL=="ttyACM[0-9]*", SUBSYSTEMS=="usb", ACTION=="add", \
ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0001", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd@%k.service"

and /etc/systemd/system/rngd@.service:

[Unit]
Description=rngd service on %I

[Service]
Type=simple
ExecStartPre=/bin/stty -F /dev/%I raw -echo -parenb
ExecStart=/usr/sbin/rngd -f --fill-watermark=90% --feed-interval=1 --rng-device=/dev/%I

Start on boot 2012-11-07 15:42:35 +0900 -- gniibe

You can use NeuG standalone device with rng-tools to feed entropy to kernel.

You can just

# apt-get install rng-tools

to install rng-tools on Debian.

Edit /etc/default/rng-tools so that it has a content like:

HRNGDEVICE=/dev/ttyACM0

if [ -c $HRNGDEVICE ]; then
   until stty -F $HRNGDEVICE -parenb raw echo; do
     sleep 5
     echo "Try another invocation of stty"
   done
else
    exit 0
fi

RNGDOPTIONS="--fill-watermark=90% --feed-interval=1"

Then, please invoke rng-tools:

# /etc/init.d/rng-tools start

It would be good that system supports plug-and-play for the device, though.

You can check the status of entropy pool by:

$ watch cat /proc/sys/kernel/random/entropy_avail

You will see the value of 3840 or something like that.

Plug-and-play 2012-11-08 11:56:01 +0900 -- gniibe

Alternatively (not by /etc/init.d/rng-tools), we could have settings for udev to invoke rng-tools.

I tested with /etc/udev/rules.d/90-neug.rules:

KERNEL=="ttyACM[0-9]*", SUBSYSTEMS=="usb", ACTION=="add", \
ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0001", \
RUN+="/etc/udev/ctrl_rng.sh"

KERNEL=="ttyACM[0-9]*", SUBSYSTEMS=="usb", ACTION=="remove", \
ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0001", \
RUN+="/etc/udev/ctrl_rng.sh"

And a script which control rng-tools as /etc/udev/ctrl_rng.sh:

#! /bin/sh

PIDFILE=/var/run/rngd.pid

case "$ACTION" in
add)
  stty -F $DEVNAME raw -echo -parenb
  /usr/sbin/rngd --fill-watermark=90% --feed-interval=1 --rng-device=$DEVNAME
  ;;
remove)
  # This will be called twice, since there are two interfaces for the device.
  # Called once for 10/0/0, another for 2/2/1.
  if [ x$INTERFACE = x"2/2/1" -a -f $PIDFILE ]; then
      kill -SIGTERM `cat $PIDFILE`
      rm -f $PIDFILE
  else
      exit 0
  fi
  ;;
esac

exit 0

With these settings, rngd automatically will be invoked upon plug-in of NeuG device, and it will be killed upon removal of the device.

It seems that rngd doesn't accept SIGTERM to shutdown cleanly (as written in the manual), but it will eventually finish anyway when there will be no /dev/ttyACM0.

-H option for rngd

You can add an option of -H n.n (or a floadint point number 0.0 betwen 1.0) to specify entropy per bit. For example, with -H 0.5, you need to put twice. This could be a safe factor.

Please see rngd(8) for detail.

Acknowledgment

Thanks to Arthur W. Green for the information of modem manager, its udev rules, and rng-tools on other distros.

Francois Berenger also informed me about rng-tools and suggested to invoke rng by rc.local script.

Answer for experimental GIGO

While this is early experimental stage, you can try to join Kun9be4, the random pool network, by running its program, named GIGO.

If you want to join the network to serve random byte stream to other machines, your host requires to open UDP port 10646. You need "port forwarding" setting if your host is behind firewall.

When UDP port is not available from the network, NeuG standalone device only feeds to /dev/random of your machine locally. It still works, but it would not be that interesting.