Band Conditions

06 May 2019

Guest Post: R-Pi OTP/DRYAD True Hardware RNG How-To




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

by Jefferson.Thomas <jefferson.thomas@protonmail.com>



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.



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.

5x10 is suitable for one page of 5-point font.
6x12 is suitable for 4-point font.
8x16 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:


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 at http://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


2 comments:

  1. Thank you, Thank you, Thank you, Thank you! I have a on of RasPi's and never knew they had TRNG in them. Don't know how I missed that in the docs!

    ReplyDelete
  2. Thank you for the good writeup. It in fact was a amusement account
    it. Look advanced to more added agreeable from you! However, how can we
    communicate? I've been browsing online more than 4 hours
    today, yet I never found any interesting article like yours.
    It is pretty worth enough for me. In my opinion, if all webmasters and bloggers made good content as you did, the internet will be
    much more useful than ever before. I all the time emailed this
    blog post page to all my contacts, since if like
    to read it afterward my links will too. http://Alienware.com

    ReplyDelete