About the Fobnail project
Fobnail is a project that aims to provide a reference architecture for building offline integrity measurement verifiers on the USB device (Fobnail Token) and attesters running in Dynamically Launched Measured Environments (DLME). It allows the Fobnail owner to verify the trustworthiness of the running system before performing any sensitive operation. This project was founded by NlNet Foundation. More information about the project can be found in the Fobnail documentation. Also, make sure to read other posts related to this project by visiting fobnail tag.
Scope of current phase
This phase focused on using Fobnail in a real-life use case, namely using it to access LUKS2 decryption key if and only if the PCR measurements are valid. In this post only high-level usage will be described, if you want to know what happens under the hood or want to modify it to your needs see documentation.
In this phase we completely switched the architecture around. Now the CoAP server is located on Fobnail Token, instead of each of PC applications. This way we could implement API endpoints, including Fobnail Token Services (FTS), which allows for more elaborate applications without having to re-flash Token firmware each time.
As of now, only storage services are fully defined in FTS. Few other endpoints
for working with cryptographic keys were listed, but they are yet to be
implemented. There is also an endpoint
/api/version which reports all versions
of API supported by Token - the version will be increased only when
backward-incompatible changes are done.
There are now two separate Attester applications - one with provisioning code, and one without. Former should be used just for initial provisioning, and the latter for normal use. We hope that by simplifying more frequently used form of Attester (that is, the application used just for attestation, not provisioning) we can reduce the surface of attack. It also helps with rare cases when users inadvertently plugged in unprovisioned Token - in that case Token would also lit all-good green LED in the end, making it indistinguishable from normal attestation. For the same reason we also gave up on the idea of unprovisioning the token by holding the button - neighboring USB device could potentially keep the button pressed
Speaking of LEDs, we now have to steer them in a non-blocking manner. Simple delay loops were good enough when the Token was CoAP client, but now it has to be able to respond to the clients without making them wait too long, especially for longer signals like attestation result. We took advantage of that forced change to expand and standardize blink codes produced by Fobnail Token.
Building and running
Building hasn’t change much since
There are some changes done to produce
along with non-provisioning version, but instructions for building didn’t
change. The process is now
part of Fobnail documentation.
Ubuntu LTS 22.04 and tools from official packages included in that distribution were used for writing and testing of this blog post. This includes building, flashing and use of all tools, as they were not performed on the same machine. The following revisions of components were used:
Despite changes in the architecture, applications are started mostly the same as
before. Main difference is that the applications don’t have to (and shouldn’t)
be already running when Fobnail Token is being plugged in. Attester changed a
bit more, it now can take arguments which use Fobnail Token Services.
Description of those can be obtained by starting Attester with
Preparing encrypted disk image for use with Fobnail
Some preparations have to be done during provisioning by administrator to make user’s life as easy as possible. Following steps were performed on Ubuntu 22.04 LTS, they may be slightly different for other versions and distributions.
Build by following Fobnail documentation
and perform Token provisioning. To do so, plug in the Token and make sure it has
properly assigned IP address. It can be added through
*.link file and
NetworkManager connection (see how it’s done for Attester below),
but since this is one-time operation it can also be assigned temporarily with:
enp0s26u1u1 to the interface name of the Token, it may depend on your
OS, its configuration, presence of other USB Ethernet adapters or even USB port
to which the Token is plugged in. To obtain it, run
sudo dmesg | grep cdc_eem.
In my case this was the result:
Note that sometimes interface isn’t renamed and two last lines aren’t printed,
in that case use
usb0 or whatever the original name was. With that out of the
way, start Platform Owner application, with the same arguments as in previous
phases of Fobnail project:
Refer to documentation for description and example OpenSSL configuration for Platform Owner certificate chain, if you haven’t prepared whole chain during the build process.
Now switch to target platform, but don’t connect Fobnail Token yet. To make
further steps easier, start by making the interface name persistent and assign
an IP address to it. Create file
This file can also be found in fobnail-attester repository. Now we can add persistent network configuration for new interface name:
Connect the Token and check if it gets its IP correctly, if it does, we can
finally provision the platform. Fobnail Token Services are available even for
Attester with provisioning functions, so encryption key can be written in the
same invocation as platform provisioning. The process of creating disk image,
encryption key, platform provisioning and writing the encryption key to the
Token can be automated with a script. Before it can be used,
Make sure the platform is in target configuration. This includes UEFI version, settings and hardware configuration - graphics cards, disks, network controllers etc. Note that with UEFI PCR values checked by Fobnail may change depending on drivers and applications started during booting, like UEFI setup or boot selection menu. If in doubt, reboot now and let the platform boot by itself.
Change paths and names in the following script to your expectations, save it and
Successful provisioning is reported by 3 short blinks of green LED. Right after that an attestation is performed to further test if the process can be reproduced later. Success of that and each next attestation is reported by green LED lit for few seconds. More details about meaning of blinks produced by Token can be found in the documentation.
Platform is now provisioned and encryption key can be read by calling
fobnail-attester --read-file luks_key:keyfile.bin. For better user experience
we can automate day-to-day use as well with set of relatively simple scripts and
configuration files from
fobnail-mount.serviceis to be installed in
/lib/systemd/systemor another directory searched by
systemd. It contains paths to files listed below, you can change it in the service file or use defaults.
fobnail.cfgby default is expected to be located in
/etcdirectory. It holds paths and filenames used by Attester, change those if required. Note that it should use the same values as were used during provisioning, unless any of files pointet to by configuration were manually moved.
umount.shshould be installed in
/usr/share/fobnailby default, create this directory if it doesn’t exist.
99-fobnail.rulesis the file that instructs
udev(which is now part of
systemd) to automatically start the service when Token is plugged in to the platform. Copy this file to
10-fobnail.linkwas already created before platform provisioning. This file doesn’t have configurable location, it always have to live in
/etc/systemd/networkdirectory. Note that key used in
systemdin version 243 or newer. If you want to use it with older
systemdyou have to use another key, otherwise this file will be matched by every link, even
loopbackinterface. This would most likely break your Internet connection. Refer to your version of
man systemd.linkfor alternative keys for
[Match]if you want to use it with older
To install all mentioned files in their default location with proper permissions
fobnail-attester/scripts directory and execute in terminal:
Now all that’s left is to restart services so changed configuration is actually used. This can be done by rebooting whole system or restarting them manually with:
Just plug in the Token, wait few seconds (up to few dozen) for green light and
voila! You should now have access to all your secrets, mounted in directory
pointed to by
When the Token is pulled out, the secure disk should be automatically unmounted.
Make sure that all applications using files on that disk are closed before
removing the Token - if the files are still in use at that point, unmounting
will fail and access to your secrets will still be possible. Keep in mind that
it also applies to terminals with
MNT_DIR or any of its sub-directories being
their current working directory.
Encryption keys bigger than 1KB are not supported. This is a side effect of making Token firmware use less RAM. We had to compromise between ability to provision platforms with real TPM and maximal size of files protected by Token, among other things. It should be possible to circumvent this problem by writing the key in multiple Token files and having it concatenated on read, but this approach was not tested yet.
Attester assumes full control over TPM while it’s running. This means that no
other application can use TPM together with Attester, including another instance
timeout is used to work around potential issue with Attester, for
example when it can’t access the Token and gets stuck.
If you think we can help in improving the security of your firmware or you are
looking for someone who can boost your product by leveraging advanced features
of used hardware platform, feel free to
book a call with us or
drop us email to
contact<at>3mdeb<dot>com. If you are interested in similar
content feel free to
sign up to our newsletter