#!/usr/bin/python3

# CASE 1
# usage: /lib/secureboot/createOTP  "your own secret passphrase"

# with only one parameter this script creates a directory /dev/shm/ram and
# generates a file "securebootkey" which must be stored on a removable
# USB device. This file will be used to recover the passphrase on boot
# to unlock the encrypted filesystem. 

# CASE 2
# usage: /lib/secureboot/createOTP  "your_own_secret_passphrase" "a_system_generated_fingerprint"

# if you call this script with two parameters, the second parameter ist used to mask your own
# secret passphrase. The fingerprint must rely on the presence of additional USB devices and
# must be provided in hexadecimal form. 
# The output can be used in /lib/secureboot/secure.OTP to intialize the variable USBOTP.
# see readme.OTP for more information to set up USBOTP

import os,sys

#---------------------------------------------
def initramdisk():
    os.system("/bin/mkdir /dev/shm/ram 2> /dev/null")
    os.system("/bin/chmod 700  /dev/shm/ram")
    os.system("/bin/ls /dev/shm/ram")

#---------------------------------------------
def hexxor(a,b):
    res = ""
    i = 0
    X = Y = 0
    if len(a) > len(b):
         for (x,y) in zip (a[:len(b)] , b) :
              i = i + 1
              X = X*16 + int(x,16)
              Y = Y*16 + int(y,16)
              e = hex(X^Y)[2:]
              res += e	
              X = Y = 0
    else:
         for (x,y) in zip (a , b[:len(a)]) :
              i = i + 1
              X = X*16 + int(x,16)
              Y = Y*16 + int(y,16)
              e = hex(X^Y)[2:]
              res += e	     
              X = Y = 0
    return res

#---------------------------------------------
def convert_to_hex(s):
    import binascii
    B = bytearray()
    B.extend(s.encode())
    return binascii.hexlify( B ).decode()

#---------------------------------------------

print("Please read the documentation in /lib/secureboot/readme.OTP and secure.OTP")
print()

if len(sys.argv) == 3:
    # CASE 2: generating USBOTP
    print ("Creating a secret USBOTP to be stored in /lib/secureboot/secure.OTP")
    print ("Make sure that additional USB devices are already present in the system")
    print()
    KEY = convert_to_hex(sys.argv[1])
    RESULT = hexxor(KEY, sys.argv[2])
    print ("USBOTP=" + RESULT)
    print()
    print ("Please read /lib/secureboot/readme.OTP")

elif len(sys.argv) == 2:
    RND = ""
    try:
         initramdisk()
         os.system("dd if=/dev/random of=/dev/shm/ram/random bs=1 count=32")
         F = open("/dev/shm/ram/random","rb")
         RND = F.read()
         F.close()
         print ("Read " + str(len(RND)) + " bytes of random data")
         if int(len(RND)) >= 32:
               RANDOM = RND.hex()
               try:
                    F = open("/dev/shm/ram/securebootkey","w")
                    F.write(RANDOM)
                    F.close()
                    os.system("/bin/sha256sum /dev/shm/ram/securebootkey | /bin/cut -c-64 > /dev/shm/ram/securebootkey.sha256 ")
                    os.system("/bin/rm -f /dev/shm/ram/random")
               except:
                    print ("Error: Cannot write securebootkey file.")
                    os.system("/bin/rm /dev/shm/ram/random")
                    sys.exit(2)
         else:
               print ("Error: Not enough random data.")
               os.system("/bin/rm -f /dev/shm/ram/random")
               sys.exit(2)
    except:
         print ("Error:Cannot read random data")
         sys.exit(3)

    if RANDOM:
         print ()
         print ("Creating a secret OTP to be stored")
         KEY = convert_to_hex(sys.argv[1])
         RESULT = hexxor(KEY, RANDOM)
         print ("OTP="+RESULT)
         print ("Enter this information into the file  /usr/lib/secureboot/secure.OTP")
         print ()
         print ("There are two new files in the directory /dev/shm/ram")
         os.system("/bin/ls -l /dev/shm/ram/securebootkey*")
         print ()
         print ("Please copy the file /dev/shm/ram/securebootkey to a USB device and make sure you have a backup.")
         print ("Make sure that the script /usr/lib/secureboot/secureboot2 knows the correct device file for your USB device.")
         print ("The default is /dev/sha1. Change this entry if your USB device shows up differently.")
         print ("Copy the file /dev/shm/ram/securebootkey.sha256 to /usr/lib/secureboot")
         print ("Remove all traces of the file /dev/shm/ram/securebootkey from your system.")
         print ("Anyway, the file /dev/shm/ram/securebootkey is stored in a ramdisk and will disappear after the next reboot.")
    else:
         print ("Error: Cannot create a OTP.")
