Encrypting without NTP

Hello!

We’re currently investigating the use of the Zymkey 4i for encrypting our Linux rootfs on an RPi CM3+. Previous investigations during Ubuntu 20.04 times showed it would be possible to just generate a locked key from within a special initramfs for easy first-bootup setup in a factory, resulting in an encrypted rootfs and bootup via the Zymkey.

With Ubuntu 22.04 though it shows that temporarily running zkifc for setting up /var/lib/zymbit doesn’t result in creation of the required salt file anymore, resulting in an incomplete state during key creation for LUKS to be prepared with a new key.

This is with a custom initramfs which just sets up the device after factory flash and deletes itself from storage after completion.

Have there been changes to the zk utilities that disallow setup without NTP? During factory setup the device wouldn’t have networking abilities, hence it would require a different way of setting up the environment.

Thanks.

@aneum - The short answer is no, nothing changed specifically. I’m not sure if something changed from 20.04 to 22.04. Can you outline the steps that left you without a salt file?

@Bob_of_Zymbit I would prefer not sharing the script publicly, but in a gist what happens is:

  • Create /run/zkstatus
  • Run /bin/zkifc -s /var/lib/zymbit &
  • sleep for 15 seconds until killing the zkifc process
  • zkgrifs 512 > /run/key.bin
  • zklockifs /run/key.bin > /run/key.bin.lock
  • cryptsetup luksAddKey /dev/mmcblk0p2 /run/key.bin
  • Put the /run/key.bin.lock in the rootfs

This is all in the first-boot initramfs without networking.

@Bob_of_Zymbit ping. We’re not going to be able to evaluate use of the Zymkey without help.

I know that @Bob_of_Zymbit is working on diagnosing this, but I wonder if you could further explain this part.

Are you saying that after 15 seconds your script kills the zkifc process?

dg

Yes. Previously it was 10 seconds as that was enough for zkifc to create the necessary salt file.

@aneum what are the permissions on your /var/lib/zymbit? Do you have a zymbit user? Can you show me ls -lR /var/lib/zymbit ?

zymbit@pi4:~$ ls -lR /var/lib/zymbit/
/var/lib/zymbit/:
total 12
drwx------ 2 zymbit zymbit    4096 Nov 13 14:07 254FFD9C0E50A13A02038D23A81BF747CA19F9F80FAA985288DEF700FE23DE44
-rw-r--r-- 1 root   root       251 Jan  9  2022 ntp_str.json
drwxrwxr-x 3 root   zk_pkcs11 4096 Nov 13 14:03 zk_pkcs11

/var/lib/zymbit/254FFD9C0E50A13A02038D23A81BF747CA19F9F80FAA985288DEF700FE23DE44:
total 8
-rw------- 1 zymbit zymbit  32 Nov 13 14:07 s1_fp_salt.bin
-rw------- 1 zymbit zymbit 600 Nov 13 14:07 state

/var/lib/zymbit/zk_pkcs11:
total 4
drwxrwxr-x 2 root zk_pkcs11 4096 Nov 13 14:03 tokens

/var/lib/zymbit/zk_pkcs11/tokens:
total 0

If the permissions are not an issue, can you try waiting after you kill zkifc? I tried something like this:

#!/bin/bash
set -x

rm -rf /var/lib/zymbit/*
rm /tmp/y
ls -lR /var/lib/zymbit

mkdir -p /run/zkstatus
/bin/zkifc -s /var/lib/zymbit &
sleep 5
ls -lR /var/lib/zymbit
killall zkifc
sleep 5
echo "Running standalone zkgrifs..."
zkgrifs 64 > /tmp/y
ls -l /tmp/y
echo "Done"

@Bob_of_Zymbit I won’t be able to copy-paste much of the contents from here, again the ZK utilities and key generation scripts are run inside of a custom initramfs which we boot into and remove/shred prior to shipping the device.

Additionally, it required a stub timedatectl script which returns a status output similar to regular timedatectl from systemd when invoked.

I could give adding a bit of sleep after killing zkifc a shot though, but all the hurdles in the way lead me to believe you are not very interested in running this without some NTP time synchronization guarantee.

Yes, zkifc wants an NTP sync, but your binding will take place without it. And your use case sounds like you don’t need zkifc once you get through your initial setup.

@Bob_of_Zymbit I’ve figured out a way to set up the Zymkey with our custom OS and factory process. We do the setup in the main rootfs via a systemd target and a well known “temporary” LUKS key. Boot into the systemd target with the known LUKS key, set it all up, and remove the well-known LUKS key afterwards.

We’ve had other people do similar things in their production stage. Glad you found a solution that works.