From A Reader: R-Pi OTP/DRYAD True Hardware RNG How-To

Yet another way to use open source tech for great purposes. Good work TJ.

– NCS

 

I had been looking for a way to generate OTPs that would (in theory) be as secure as possible without the encumbrance and time involved by using dice, locked in a windowless basement with a Smith-Corona. I also wanted to be able to make them as small as possible. After a lot of digging that was only mildly fruitful, I decided to make one myself. I also wanted it so that I – and anyone else capable of following a recipe – could make more with a minimum of trouble.

“R-Pi OTP/DRYAD True Hardware RNG How-To”

There are only three ways that I know of to generate a truly random One Time Pad – for the “regular guy”: 1) The old-fashioned way with a set of dice (preferably 10-sided) and paper/pencil; 2) purchase one of AmRRON’s ADL-1 units from AmRRON.com (https://amrron.com/2018/03/18/amrron-dark-labs-otp); 3) The following method outlined in this how-to. Maybe there are others. I wanted to come up with a way for anybody to put one together with easily available components. So here it is. You shouldn’t need to procure any unobtainium to build it. (It was valid in May 2018 when I first put this together. It should be fine as Raspbian Stretch is still the current distribution.)

The script will print either numerical or alphabetic OTPs. Besides the standard OTP generating scripts, also included is a script for generating a DRYAD-type table (it does not have the formatting options of the OTP script) and a special, limited-use/audience OTP script for split keys and variants at the end of this how-to.

This how-to also includes a procedure for building an SD card from scratch purely for the production of secure OTPs. Prior to that is some helpful info for those who are interested. If you wanted to build a good OTP generator, then this is for you.

Keep in mind that this system is not “ultra-portable.” It is no more portable (at best) than hauling a laptop and printer around. (And that’s when using the Pi TFT.) It is not rugged. It is not turnkey or for people that need it right now without knowing what they’re doing. If you want that, get Number 2 (above.) This Pi system costs roughly: $35 for the Pi2b, $15 for the SD card, $65 for the TFT, $10 for keyboard, $5 for mouse, $30 for printer – see below, $5 for the USB cable that you may not have and the printer doesn’t come with, PLUS whatever power supply equipment you will need. Wall P/S if outlet is available, battery, inverter and proper wiring cables if going to the field, and what you’re going to carry this junk in.

It is slow, but not nearly as slow as Number 1. If you haven’t caught on yet, it is for the Raspberry Pi. The Raspberry Pi has a built-in True Random Number Generator (TRNG). The Pi 2b is recommended because it does not have Bluetooth or WiFi built in, therefore it can be truly air-gapped. While faster, newer models have both Bluetooth and WiFi built on-board, therefore they are less secure. the TRNG is not enabled by default, but is easily enabled by executing the following at the command line (in a terminal window – and restart rng services if not rebooting after installation) to have the hwrng start dumping its output to the “entropy bag”:

“sudo apt-get update”

“sudo apt-get install rng-tools”

“sudo service rng-tools restart”

You don’t have to use the HWRNG if you don’t actually want to.

You  choose what you want to use for the random number generator: /dev/random ,  /dev/urandom ,  or /dev/hwrng .

For the differences between these methods I found these two webpages to have practical and useful information.

hackaday.com/2017/11/02/what-is-entropy-and-how-do-i-get-more-of-it/#more-280214

www.2uo.de/myths-about-urandom

Basically: hwrng takes the numbers straight from the Pi’s Hardware RNG; random generates the numbers from a seed generated from the Pi’s store of entropy which is generated from the hwrng and other system entropy gathering processes and will stop and wait if the entropy store gets too low; urandom is generated the same as random but does not stop when system entropy gets low. (It’s really fast, but less secure and not truly random.)

When finished, the script will let you know how long it took to generate the tables. When first starting, test your system out by generating only one table so you have an idea just how long a full page of micro-printed tables will take.

For the scripts below to work, you will also need to install the xclip package in order to have the table sent directly to the clipboard.

”sudo apt-get xclip”

The OTP script is written in Bash as it is the easiest method for the average user to examine and make sure that there are no shenanigans going on behind the scenes. (I’m not a programmer as it is, so it was also the easiest for me to put together.) It is documented and easily editable if you want to change any parameters. It sets up a ramdisk to keep the table in memory instead of writing it to the card/drive. (It does not automatically unmount the ramdisk and wipe the filesystem in /dev/ram1 – I couldn’t get it to work. Shutting down the Pi does the trick though.)

When generation of the tables is complete, it copies it to the clipboard so that it can be pasted into whatever program you will print from. Leafpad works, but I prefer Libre Writer as you can change the color. I print one copy in red, and one in blue, for easier control of incoming and outgoing pads. When printing the OTPs use a monospace font, otherwise the pads will not print lined up properly. Some fonts work better than others when printing very small. Do your own testing.

The OTP script needs to be run as sudo so as to set up the ramdisk and to directly access the hwrng. The script also needs to be marked as executable once copied to your system.

”sudo chmod +x OTP.sh” (Same for DRYAD.sh and SplitOTP.sh.)

For printing the OTP tables, You can select what size table you want. It asks you how many columns of OTPs across the page, and how many rows of them you want.

5×10 is suitable for one page of 5-point font.

6×12 is suitable for 4-point font.

8×16 is suitable for 3-point font. (I need my reading glasses AND magnifying glass to not confuse some numbers on this one!)

Please don’t use your phone’s camera in magnification mode to read the tables! What’s the point of using an air-gapped system if you’re just going to put the friggin’ thing in front of a camera attached to a phone company, the internet, the NSA, fill-in-the-blank-with-any-body-not-you!?! Order the 5-piece loupe set from Harbor Freight. It’s $3.75 and includes a 10x loupe.

I have researched and experimented with different materials to print the tables on. While I have seen some people recommend cigarette paper, it fails for several reasons. In fact, it has only ONE redeeming quality – it burns with almost no residue. The same additive it is treated with to enable it to burn so clean also makes it burn slower – not what we want. Try to run it through a printer too. Let me know how that works for you.

Much better is tissue or tracing paper. A procedure for successfully printing on this medium was given to me by an acquaintance and is available here:

https://www.thesprucecrafts.com/print-tissue-paper-with-ink-jet-printer-2366553

Children’s tracing paper is much cheaper, and works a little better than professional or artist’s tracing paper. Sometimes it can even run through some printers without having to use the above procedure.

The best printer that I’ve found so far is the HP Deskjet 1112. It is USB only – NO WiFi or BT! Ideal for use with the Pi 2b which doesn’t have either of those, (and shouldn’t for this application!) It weighs under 4-1/2 pounds. It draws 10W max when printing. It costs under $30 delivered. It comes with two starter ink cartridges (Black, Color). Replacement cartridges will cost you more than the printer. It will feed the cheap children’s tracing paper, however, due to the difference in ink, black will smear if you haven’t tacked the tracing paper to a regular sheet first – then it’s ok. I haven’t had that issue with Color. (Maybe it was the other way. I don’t remember. I use the glue stick method always.) I haven’t yet taken the printer apart to see if I can bypass the internal power supply and power it via battery yet. That would help for portability.

For those that are concerned about the issue with many color inkjets secretly printing the tracking codes in yellow dots (do a google lookup) I offer the following suggestions:

1) Print out several sheets of yellow until you’re out of yellow. This won’t help if whatever printer you are using does not allow you to print when you’re out of a color. (Canons come to mind.)

2) Don’t worry about it. these are OTPs and DRYAD tables. Keep them secure. Burn when used. If they’ve been captured, you screwed up big-time and it doesn’t matter at that point anyway.

Some people like using thermal printers. I don’t because I want to print miniature tables, in color. I also hate thermal printer paper. It doesn’t last well, even when stored well. It’s up to you though. The advantages are that they are portable, you don’t need ink or toner, and there isn’t memory that might hold the OTP.

So here is the Raspberry Pi OTP Generating Card procedure:

While it can do more things, best practice (and I would argue the only proper one) would be to use the card for ONLY creation and printing of the tables. Requirements should be:

1. Only use a Pi2  or 2b. NEVER use a Pi3 or higher as they have integrated Wifi and BT which can only be “disabled” is software. The Pi2/b does not have that integrated. Therefore, you can be sure there is no connection to anyone as long as you have not plugged a Wifi or BT adapter in, or plugged in an ethernet cable. (Guaranteed air-gapping.) I would suggest to not even use such ever, even for the installation so as to minimize possible collection of hardware or network identifying information. I performed my installation by plugging into an ethernet router downstream of another router. Not perfect, but I think satisfactory.

2. If using a keyboard and/or mouse, use only USB ones.

3. Only use a printer that is USB-only.

4. Do not use a “smart tv” for a monitor.

5. When finished creating and printing, shut down the Pi, remove the SD card, and physically secure it.

It can be setup from either the Full Raspbian image, or the Lite version.

The full version will be 4.3 Gig total, the Lite based version will be 2.3 Gig (zips down to about 1.3 Gig for a backup.)

For creating the card, I recommend building it from the Raspbian Lite version. This will not just minimize the overall size, but also keep a lot of superfluous software off the card and so minimizes potential attack surface.

The Secure OTP and DRYAD Table Generator Pi Card Creation Procedure:

Items in quotes are to be typed in at the command line (terminal window).

For either method, start with:

“ sudo apt-get update “

“ sudo apt-get upgrade “

“ sudo apt-get dist-upgrade “

“ sudo apt clean “

“ sudo apt autoremove “

“ sudo reboot “

If installing from Lite, do this first: (If Full Raspbian, jump to * below)

“ sudo apt install raspberrypi-ui-mods “

“ sudo reboot “

“ sudo apt-get install synaptic “

“ sudo apt-get install leafpad “ (Optional – you can use another editor.)

“ sudo apt-get install libgtk-3-dev “

“ sudo synaptic “

Search for “ firefox “

Select firefox-esr, mark for installation, then Apply to install

Search for “ python-pip “

Select, Mark, Apply

Search for “ libreoffice-writer “

Select, Mark, Apply

Search for “ python-gi-dev “

Select, Mark, Apply

*If installing from Full Pi Desktop, pick up the procedure here:

Note : You may (likely) have to go to “Preferences”->”Mouse and Keyboard Settings” and fix the keyboard layout.

Open file manager and delete the ~/oldconffiles folder if it exists.

(Optional)

“ sudo raspi-config “

– Go to advanced and set Memory Split to 256

– Go to Overclock and set to High

– Select Finish and then Reboot

(Optional – may improve speed) – Install zram boot-up script:

⁃ “ sudo wget -O /usr/bin/zram.sh raw.githubusercontent.com/novaspirit/rpi_zram/master/\zram.sh “

⁃ “ sudo chmod +x /usr/bin/zram.sh “

⁃ “ sudo leafpad “

⁃ edit /etc/rc.local – add “ /usr/bin/zram.sh & “ at end but before “exit 0”

Save and reboot.

(Optional – and for the RPi TFT) – install rpi_backlight

⁃ “ sudo pip install rpi_backlight “

⁃ “ sudo leafpad “

⁃ Open and edit /home/pi/.config/lxsession/LXDE-pi/autostart

⁃ at beginning use command line twice with different values

⁃ “ sudo rpi-backlight -b 50 “

⁃ “ sudo rpi-backlight -b 49 “

⁃ edit Autostart to place GUI version at end

⁃ “ sudo rpi-backlight-gui “

(Optional – adjust screen resolution for RPi TFT – necessary if using onscreen keyboard and no mouse)

⁃ “ sudo leafpad “

⁃ Open and edit /boot/config.txt

⁃ set resolution to 1280 x 760

Install Printer software (this is for the HP mentioned above.)

⁃ Install cups (and hp printer software for hp printers) – “ sudo apt-get install cups hplip “

⁃ “ sudo usermod -a -G lpadmin pi “

⁃ “ sudo /etc/init.d/cups restart “

⁃ (You can now access cups from web browser at localhost:631)

⁃ “ sudo hp-setup -i “ (with printer connected through USB)

⁃ Answer questions, make up names if you want, just don’t quit.

⁃ Note: the printer’s serial# is saved when added. Stored in /etc/cups/printers.conf.O and printers.conf . If you want to remove this identifying information you first have to delete the printer from the cups interface via a web browser, then stop cups (“ sudo /etc/init.d/cups stop “), then check both files. At least one of them ( the .O file ) will still have the SN#. Edit the # out, save and exit. Restart cups (“ sudo /etc/init.d/cups start “). You will not have to be connected to the Net to re-install the printer later through the web browser.

Install HWRNG software package

⁃ “ sudo apt-get install rng-tools “

Install command line X clipboard access

⁃ “ sudo apt-get install xclip “

Install xscreensaver (not needed if you started with Raspbian Lite as the installation of X above puts this in.)

⁃ goto “Preferences” -> “Add/Remove Software”

⁃ search xscreensaver

⁃ select xscreensaver-x.xx-x

⁃ select screensaver-data-x.xx-x

⁃ click “apply” and install (default password is “raspberry”)

⁃ remember to configure the screensaver in “Preferences” -> “Screensaver”

⁃ Note: EXTREMELY important if using only TFT and onscreen keyboard as you won’t be able to get the screen back if it blanks.

Disconnect from the Net. Never connect again.

If you used a Wifi card to do updates/installs, edit /etc/wpa_supplicant/wpa_supplicant.conf to remove network name and password.

Copy over OTP.sh and DRYAD.sh (and SplitOTP.sh and sort-tri.awk and trigrams and if want this extra option) to the desktop from a USB stick.

“ sudo chmod +x (each file) “

These scripts must be run with sudo to access the hwrng.

“ sudo ~/Desktop/OTP.sh “

“ sudo ~/Desktop/DRYAD.sh “

“ sudo ~/Desktop/SplitOTP.sh “

There – that’s all there is to it.

And now the OTP.sh scrip and DRYAD.sh script.

This is the text of the script. Copy and paste it into a text editor like Leafpad and save it with the correct filename. Do this for each file.

The first line of the script is the first one starting with #!/bin/bash

OTP.sh:

———————————————————————————————

#!/bin/bash

#

# One Time Pad Table Generator Programs

#

# This determines how many characters per group in the OTPs

blocksize=5

# This determines how many groups per line of the OTPs

blockrow=5

# This determines how many OTPs across the page to print

read -p “How many pads across the paper? ” tablerow

# This determines how many lines of characters in each OTP

rowcount=10

# This determines how many rows of OTPs to print down the page

read -p “How many rows of pads? ” pagecount

#numbers or letters in the OTP?

read -p “OTP of numbers 0-9 (n) or letters A-Z (l)? default = n ” NorL

if [ $NorL == l ]

then

TYPE=’A-Z’

else

TYPE=’0-9′

fi

# Have user pick algorithm to use for picking numbers or letters

read -p “Which RNG Device? random-(1), urandom-(2) or hwrng-(3). Default is 1 ” DEVICE

case $DEVICE in

3)

RNGAlg=hwrng

;;

2)

RNGAlg=urandom

;;

*)

RNGAlg=random

;;

esac

# where to generate the page of OTPs – putting it in a ramdisk

otpath=’/ramdisk/otp.txt’

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

mkfs -q /dev/ram1 1024

mkdir -p /ramdisk

mount /dev/ram1 /ramdisk

echo

echo “$RNGAlg it is…”

echo

echo “Generating a Table of $tablerow by $pagecount of ($TYPE – type) OTPs.”

echo

echo ”                 grinding away…”

echo

# Reset BASH time counter

SECONDS=0

# Generate a row of OTPs

for ((x=1; x<=$pagecount; x++))

do

# Generate a full line of characters for eact OTP in the current row of OTPs

#  echo “” >> $otpath;

for ((i=1; i<=$rowcount; i++))

do

# Generate a row of groups for the current OTP in the current row of OTPs

for ((k=1; k<=$tablerow; k++))

do

# Generate the groups for the current line of groups in the current OTP

for ((j=1; j<=$blockrow; j++))

do

# Generate the current group of characters using the selected atributes

#    NOTE: using this if-then-else here instead of earlier in the script with two

#    longer generating branches results in an extra 2-seconds per OTP to generate with

#    hwrng, while reducing script length

if [ $NorL == l ]

then

randnum=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

else

randnum=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

fi

echo -n $randnum >> $otpath;

echo -n ” ” >> $otpath;

done

echo -n ”   ” >> $otpath;

done

echo “” >> $otpath;

done

echo “” >> $otpath

echo “” >> $otpath

done

# Send the table to X’s clipboard

xclip -i /ramdisk/otp.txt -sel clip

echo

echo “The OTP table is now in X’s clipboard.”

echo

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to generate the OTP Table was $ELAPSED”

echo

# Prepare to erase the table from the ramdisk

read -p “Press (return) to delete the OTP table from the ramdisk…” dumpit

rm $otpath

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

———————————————————————————————

And now DRYAD.sh:

———————————————————————————————

#!/bin/bash

#

# DRYAD Authentication Table Generator

#

# where to generate the DRYAD Tables – putting it in a ramdisk

dryadpath=’/ramdisk/dryad.txt’

# Create a ramdisk to put the table in to keep it in memory and not write to SD card

mkfs -q /dev/ram1 1024

mkdir -p /ramdisk

mount /dev/ram1 /ramdisk

# This determines how many Tables to print

read -p “How many DRYAD Tables to generate? ” tables

# Generate the Tables

for ((k=1; k<=$tables; k++))

do

rows=’A B C D E F G H I J K L M N O P Q R S T U V W X Y Z’

echo “FOR OFFICIAL USE ONLY     UID:” >> $dryadpath

echo “” >> $dryadpath

echo “Start DTG:                End DTG:” >> $dryadpath

echo “Distribution:” >> $dryadpath

echo “” >> $dryadpath

for row in $rows

do

if [ $row == ‘A’ ] || [ $row == ‘F’ ] || [ $row == ‘K’ ] || [ $row == ‘P’ ] || [ $row == ‘U’ ]

then

echo “” >> $dryadpath

echo ”   ABCD   EFG   HIJ   KL   MN   OPQ   RS   TUV   WX   YZ” >> $dryadpath

echo ”     0     1     2    3    4     5    6     7    8    9″ >> $dryadpath

fi

echo -n $row >> $dryadpath

dryad=$( echo ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’ | sed ‘s/./&\n/g’ | shuf –random-source=/dev/hwrng  | tr -d “\n” )

A=”${dryad:0:4}’   ‘${dryad:4:3}’   ‘${dryad:7:3}’   ‘${dryad:10:2}’   ‘${dryad:12:2}’   ‘${dryad:14:3}’   ‘${dryad:17:2}’   ‘${dryad:19:3}’   ‘${dryad:22:2}’   ‘${dryad:24:2}”

echo ” ‘”$A”‘” >> $dryadpath

done

echo “” >> $dryadpath

echo “” >> $dryadpath

done

# Send the Tables to X’s clipboard

xclip -i /ramdisk/dryad.txt -sel clip

echo

echo “The DRYAD Tables are now in X’s clipboard.”

echo

# Prepare to erase the Tables from the ramdisk

read -p “Press (return) to delete the Tables from the ramdisk…” dumpit

rm $dryadpath

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

———————————————————————————————

For those interested, here follows a split-OTP procedure and script. It provides for more complicated options for the handler or other leader-type.

Following a reading of Dirk Rijmenants’ webpage athttp://users.telenet.be/d.rijmenants/en/onetimepad.htm, specifically the section near the bottom on Secret Splitting, along with his paper “Secret Splitting: A Practical and Secure Way to Delegate Keys”, (c)2009 linked from the same page, it occurred to me that more can be done with this concept. In addition, as creation of a split key is very much more tedious than the creation of the “parent” key, I also decided to write a script for the Raspberry Pi (with it’s built-in hardware random number generator) to handle the problem. (I’ve mentioned elsewhere for a few reasons that you should use the model 2B and not a 3 or higher so as to ensure air-gappage.)

First, I’ll suggest a couple uses for the split keys. Admittedly, there will be a very small “market” for the utilization of split OTPs, but if you ever do need it, maybe this will make it more reasonably accessible (well, more than before.) These are just examples:

1) A Will (or other sensitive document with instructions in it) can be encrypted, then the key split and divided between siblings so that it requires cooperation between them. Or siblings and the lawyer, or trustee, and that new trophy wife grandpa married that nobody is getting along with.

2)A “team,” where the team leader might have the primary decryption key, but also a couple team members may have split-keys just in case something happens to TL. (This would increase resiliency while maintaining security.)

3)Keys can also be used for authentication: two people with their keys can authenticate a third person. For example, three people are to meet up, at least one is unknown to the others. The keys are combined to check the validity of each other, and also used to decrypt the original message which would list the “handles” of each participant along with a codeword unique to each participant. This way, even if a key should fall into the wrong hands, the imposter would still need to know (and provide) the handle or whatever information that will be disclosed from decryption of the original cleartext message.

As Rijmenants wrote, splitting the key (and destruction of the original) increases security, but that method also increase the risk of loss – one person loses their half, and it’s ALL lost. By applying a principle similar to the old Raid5 backup systems for computers years ago, more options open up. With Raid5, data would be split into two equal parts, then XOR’d together to create a third part. Each of the three parts would reside on a different hard drive which results in the ability to recreate the original data even upon the failure of one drive. This then required less total hard drive space than the typical mirror backup drive where both drives contain all the data.

Rijmenants described creation of split OTPs from both number based, and standard alphabet based (modulo-26 type Vigenere) OTPs. (Splitting reciprocal alphabet OTPs is just reversing the process you would use to decrypt a message.) You MUST understand the difference between the reciprocal and modulo-26 alphabetic systems! They are NOT interchangeable.

However, due to the way the reciprocal type is created, there is no way to create another split key for reconstruction (like was used in the Raid5 systems) that would be different from the primary key! That would defeat the purpose in that the Delta and Alpha keys would be identical.

Creation of the “alternative” split key is accomplished in the same way you would encrypt a message, except that instead of subtracting the “main” key from the unencrypted/plaintext message, you subtract one split key from the other. For the example, I will refer to the keys as follows:

Alpha: Original key used to encrypt the plaintext message.

Beta: First split key – randomly generated.

Gamma: Second split key – produced by subtracting Beta from Alpha.

Delta: Reconstruction key – produced by subtracting Gamma from Beta.

With three people in possession of keys Beta, Gamma and Delta, reconstruction of Alpha can be accomplished by any two of the three. If one person is compromised, the other two can still get at the message. This option provides enhanced security over the use of just a single OTP as two people are still required to decrypt the message, but reduces the risk of using two split OTPs (or more, if created the “normal” way) because loss of one of the three keys does not result in permanent loss of the message.

All three parts, Beta, Gamma, Delta are distributed – each recipient must know identity of his part, whether Beta, Gamma or Delta.

Any two can reconstruct the Alpha key:

Use OTP procedures to combine Beta and Gamma to get Alpha.

Combine Delta with (Gamma or Beta) to get (Beta or Gamma) in accordance with the formulas below to get Alpha. (Actually, any two keys of the four can reconstruct the other two.)

Example using numeric OTP:

Cleartext Message     16438

Alpha                 62477

Encrypted msg.       54061

Beta                  83258

Gamma                 89229

Delta                 04039

Alpha and Beta are each randomly generated

Alpha – Beta = Gamma

Beta – Gamma = Delta

Any 2 of Beta, Gamma, Delta can be used to determine Alpha

Beta – Delta = Gamma

Alpha = Gamma + Beta

Alpha = 2xGamma + Delta

Alpha = 2xBeta – Delta

Reconstruction of a Vigenere split key is obviously tedious, but need not be done by converting to numbers and then a modulo-26 arithmetic operation. It can be done with the Vigenere table, but requires a lot of care. Ensure you are using the correct column and row, in the right order.

Use of the SplitOTP.sh script is the same as regular OTP.sh script. It will print out the four keys (3 if reciprocal is chosen) labeled as above.

The files “sort-tri.awk” and “trigrams” are required only if you wish to create reciprocal split keys. The SplitOTP.sh script will access them as needed. They should be in the same directory as SplitOTP.sh. SplitOTP uses the mawk version of awk which comes with Raspbian. The trigrams file lists the combinations of letters produced by the reciprocal OTP chart.

Note that the SplitOTP script also makes the first group of each key identical. This is for identification purposes, so that the proper split keys can be matched appropriately. This is not needed in the regular OTP generation script as each table is independent of the others. Also, while the original OTP generation script gets numbers/letters 5 at a time, the SplitOTP script only grabs them 1 at a time, to make it easier to facilitate the derivation of the Gamma and Delta tables. This will contribute to a little bit more time to generate a table in addition to the additional computations, but should not be very noticeable.

The files:

SplitOTP.sh:

———————————————————————————————

#!/bin/bash

# One Time Pad Split Key Generator

# This determines how many characters per group in the OTPs

# held-over from OTP.sh – runs quicker there with the ‘head’ command ‘5’

blocksize=1

# This is the characters in a block

position=5

# This determines how many groups per line of the OTPs

blockrow=5

# This determines how many OTPs across the page to print

read -p “How many pads across the paper? ” tablerow

# This determines how many lines of characters in each OTP

rowcount=10

# This determines how many rows of OTPs to print down the page

read -p “How many rows of pads? ” pagecount

#numbers or letters in the OTP? Keeping in case of updating later.

read -p “OTP of numbers 0-9 (n), Vigenere A-Z (v) or Reciprocal A-Z (r)? default = n ” NorL

if [ $NorL == v ] || [ $NorL == r ]

then

TYPE=’A-Z’

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25)

# declare -A RVRSLTTR

# RVRSLTTR=([Z]=0 [Y]=1 [X]=2 [W]=3 [V]=4 [U]=5 [T]=6 [S]=7 [R]=8 [Q]=9 [P]=10 [O]=11 [N]=12 [M]=13 [L]=14 [K]=15 [J]=16 [I]=17 [H]=18 [G]=19 [F]=20 [E]=21 [D]=22 [C]=23 [B]=24 [A]=25)

RVRSLTTR=( Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

else

TYPE=’0-9′

fi

# Have user pick algorithm to use for picking numbers or letters

read -p “Which RNG Device? hwrng-(1), urandom-(2) or random-(3). Default is 1 ” DEVICE

case $DEVICE in

3)

RNGAlg=random

;;

2)

RNGAlg=urandom

;;

*)

RNGAlg=hwrng

;;

esac

# where to generate the page of OTPs – putting them in a ramdisk

K1path=’/ramdisk/K1.txt’

K2path=’/ramdisk/K2.txt’

K3path=’/ramdisk/K3.txt’

K4path=’/ramdisk/K4.txt’

OTPath=’/ramdisk/OTP.txt’

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

mkfs -q /dev/ram1 1024

mkdir -p /ramdisk

mount /dev/ram1 /ramdisk

echo

echo “$RNGAlg it is…”

echo

echo “Generating a Table of $tablerow by $pagecount of ($TYPE – type) OTPs.”

echo

echo ”                 grinding away…”

echo

# Reset BASH time counter

SECONDS=0

#K1 and K2 generated randomly, K3 and K4 derived from K1 & K2.

# Generate a row of OTPs

for ((x=1; x<=$pagecount; x++))

do

# Generate a full line of characters for each OTP in the current row of OTPs.

echo -n “” >> $K1path;

echo -n “” >> $K2path;

echo -n “” >> $K3path;

echo -n “” >> $K4path;

for ((i=1; i<=$rowcount; i++))

do

# Generate a row of groups for the current OTP in the current row of OTPs

for ((k=1; k<=$tablerow; k++))

do

# Generate the groups for the current line of groups in the current OTP

for ((j=1; j<=$blockrow; j++))

do

# Generate the groups for the current line of groups in the current OTP

for ((z=1; z<=$position; z++))

do

# Generate a single character

case $NorL in

r)

randK1=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

randK2=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

drvdK3=”$(mawk -v f1=”$randK1″ -v s2=”$randK2″ -f sort-tri.awk trigrams)”

drvdK4=””

# There is no “Delta” for reverse-letter OTP – it would be identical to “Alpha”

;;

v)

randK1=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum1=${LTR2NUM[$randK1]}

randK2=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum2=${LTR2NUM[$randK2]}

VigNum3=$( expr $VigNum1 – $VigNum2 )

if [ $VigNum3 -lt 0 ]

then

(( VigNum3 += 26 ))

fi

drvdK3=${NUM2LTR[$VigNum3]}

VigNum4=$( expr $VigNum2 – $VigNum3 )

if [ $VigNum4 -lt 0 ]

then

(( VigNum4 += 26 ))

fi

drvdK4=${NUM2LTR[$VigNum4]}

;;

*)

randK1=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

randK2=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

drvdK3=$( expr $randK1 – $randK2 )

if [ $drvdK3 -lt 0 ]

then

(( drvdK3 += 10 ))

fi

drvdK4=$( expr $randK2 – $drvdK3 )

if [ $drvdK4 -lt 0 ]

then

(( drvdK4 += 10 ))

fi

;;

esac

# Set first 5-character block of all 4 associated pads equal for use as a serial number

if [ $i = 1 ] && [ $j = 1 ]

then

randK2=$randK1

drvdK3=$randK1

drvdK4=$randK1

fi

echo -n $randK1 >> $K1path;

echo -n $randK2 >> $K2path;

echo -n $drvdK3 >> $K3path;

echo -n $drvdK4 >> $K4path;

done

echo -n ” ” >> $K1path;

echo -n ” ” >> $K2path;

echo -n ” ” >> $K3path;

echo -n ” ” >> $K4path;

done

echo -n ”   ” >> $K1path;

echo -n ”   ” >> $K2path;

echo -n ”   ” >> $K3path;

echo -n ”   ” >> $K4path;

done

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

done

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

done

# Send OTPs to X’s clipboard

echo “Alpha” >> $OTPath

cat $K1path >> $OTPath

echo “Beta” >> $OTPath

cat $K2path >> $OTPath

echo “Gamma” >> $OTPath

cat $K3path >> $OTPath

if [ $NorL == r ]

then

echo “no Delta table for Reciprocal OTPs”

else

echo “Delta” >> $OTPath

cat $K4path >> $OTPath

fi

xclip -i /ramdisk/OTP.txt -sel clip

echo

#echo “The OTP table is now in X’s clipboard.”

echo

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to generate the OTP Table was $ELAPSED”

echo

# Prepare to erase the table from the ramdisk

read -p “Press (return) to delete the OTP table from the ramdisk…” dumpit

rm $K1path

rm $K2path

rm $K3path

rm $K4path

rm $OTPath

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

———————————————————————————————-

sort-tri.awk:

First line starts with #! /usr/bin/mawk -f

———————————————————————————————-

#! /usr/bin/mawk -f

# call with VARIABLE=”$(mawk -v f1=”$randK1″ -v s2=”$randK2″ -f sort-tri.awk trigrams)”

BEGIN {

FS = “”

t3 = “”

}

{ if ( t3 == “” ); {

if ( $1 == f1 && $2 == s2 )  t3 = $3

if ( $1 == s2 && $2 == f1 )  t3 = $3

if ( $2 == f1 && $3 == s2 )  t3 = $1

if ( $2 == s2 && $3 == f1 )  t3 = $1

if ( $1 == f1 && $3 == s2 )  t3 = $2

if ( $1 == s2 && $3 == f1 )  t3 = $2

}

}

END {

print t3

}

——————————————————————————————-

trigrams:

First line starts with AAZ

——————————————————————————————-

AAZ

ABY

ACX

ADW

AEV

AFU

AGT

AHS

AIR

AJQ

AKP

ALO

AMN

BBX

BCW

BDV

BEU

BFT

BGS

BHR

BIQ

BJP

BKO

BLN

BMM

BZZ

CCV

CDU

CET

CFS

CGR

CHQ

CIP

CJO

CKN

CLM

CYZ

DDT

DES

DFR

DGQ

DHP

DIO

DJN

DKM

DLL

DXZ

DYY

EER

EFQ

EGP

EHO

EIN

EJM

EKL

EWZ

EXY

FFP

FGO

FHN

FIM

FJL

FKK

FVZ

FWY

FXX

GGN

GHM

GIL

GJK

GUZ

GVY

GWX

HHL

HIK

HJJ

HTZ

HUY

HVX

HWW

IIJ

ISZ

ITY

IUX

IVW

JRZ

JSY

JTX

JUW

JVV

KQZ

KRY

KSX

KTW

KUV

LPZ

LQY

LRX

LSW

LTV

LUU

MOZ

MPY

MQX

MRW

MSV

MTU

NNZ

NOY

NPX

NQW

NRV

NSU

NTT

OOX

OPW

OQV

ORU

OST

PPV

PQU

PRT

PSS

QQT

QRS

RRR

———————————————————————————————

3 thoughts on “From A Reader: R-Pi OTP/DRYAD True Hardware RNG How-To

  1. Pingback: Brushbeater: True Random Numbers How-To – Lower Valley Assembly

Comments are closed.