Full disk encryption

Ubuntu Core uses full disk encryption (FDE) whenever the hardware allows, protecting both the confidentiality and integrity of a device’s data when there’s physical access to a device, or after a device has been lost or stolen.

Built-in FDE support requires both UEFI Secure Boot and TPM 2.0 (Trusted Platform Module) support, but its implementation in Ubuntu Core is generic and widely compatible to help support a range of hardware. External I2C/SPI-based TPM modules are not currently supported.

TPM-based FDE seals the FDE secret key to the full EFI state, including the kernel command line, which is subsequently unsealed by the initrd code in the secure-boot protected kernel.efi at boot time.

The following factors affect how a device is encrypted:

For a non-standard (non-UEFI+TPM platform) FDE platform, such as a Raspberry Pi or other ARM devices, implementation is board-specific and will typically involve creating custom gadget and kernel snaps. UC20/UC22, however, do provide a helper mechanism, via a hook interface, to ensure the integrity of any subsequently executed or accessed data. See the full-disk-encryption hook interface for further details.


Storage layouts

The layout of the generated image used to install Ubuntu Core, and the resultant storage on the device, is described by the gadget snap and its associated gadget.yaml.

On first boot, Ubuntu Core will create and populate the following storage partitions:

  • ubuntu-seed (role: system-seed; read-only, ext4 or typically vfat)
  • ubuntu-boot (role: system-boot; read-only, ext4 or vfat):
  • ubuntu-save (role: system-save; writable, ext4, encrypted)
  • ubuntu-data (role: system-data; writable, ext4, encrypted)

ubuntu-save is mandatory on an encrypted system. The initramfs bootstrapped from ubuntu-boot is responsible for decrypting both the ubuntu-save and ubuntu-data partitions.

The system boot process:

  1. verifies the bootloaders and kernel signatures
  2. measures the above and the kernel command line with the TPM
  3. on-top of the above trusted set, the snapd initrd code measures the snap device model
  4. snapd then separately verifies other snaps with their assertions as needed

When run normally, the snap content comes from snaps in the encrypted data partition, with the exception of the kernel image which is loaded from the system boot partition via secure boot. In any case the unsealing of the disk encryption key(s) is tied to the correct TPM boot measurements.

If an encrypted drive is detected, but the TPM does not contain a valid key, the Ubuntu Core boot process will prompt for a recovery key. See Using recovery keys for further details.

For more information on how Ubuntu Core uses these partitions, what they contain, and how they boot, see Storage layout.

Disabling encryption

It is sometimes desirable to install Ubuntu Core without encryption, even when the device hardware supports it.

This option is provided by the “storage-safety” setting in the model assertion used to build the installable image. It can be set to one of the following:

  • encrypted: ensure encryption is used and fail if the device does not support it.
  • prefer-encrypted: do encrypt if the hardware supports it.
  • prefer-unencrypted: do not encrypt by default, even if the device supports encryption.

See Creating a bespoke image for further details on building an image from a model assertion.

Model grade

The grade option in the model assertion is used to set the constraints for the device. It can be one of the following:

  • dangerous: relax some of the constraints here (mandatory snap id for example), and should allow for the use of unasserted snaps, devmode snaps, or the presence of extra snaps in the recovery system. These relaxations are meant for development and not for production system use as they weaken the system security.
  • signed (default): no unasserted (unsigned) snaps or snaps not mentioned in the model can appear or be used in the recovery system.
  • secured: same properties as signed plus it is mandatory for the device to use full disk encryption and secure boot.

The snap model command can be used to view the currently running model declaration, including its grade and storage-safety values:

snap model --verbose
brand-id:      bJzr2XzZg6Qv6Z53HIeziXyxtn1XItIq
model:         ubuntu-core-20-amd64
grade:         signed
serial:        0fb187ff-a037-42ca-b0d6-1a802245e799
architecture:  amd64
base:          core20
timestamp:     today at 08:54 UTC

The values of both a model’s grade and the storage-safety option influence whether a device is encrypted, unencrypted, or generates an error, as shown in the tables below:

With hardware support

grade ↓ / safety → unset encrypted prefer-encrypted prefer-unencrypted
dangerous encrypted encrypted encrypted unencrypted
signed encrypted encrypted encrypted unencrypted
secured encrypted encrypted encrypted invalid

Without hardware support

grade ↓ / safety → unset encrypted prefer-encrypted prefer-unencrypted
dangerous unencrypted error output unencrypted unencrypted
signed unencrypted error output unencrypted unencrypted
secured error output error output error output invalid
Note :

grade:secured is the same as grade:signed and storage-safety:encrypted.
storage-safety:prefer-encrypted is the same as unset

1 Like

A couple of comments and suggestions:

writable should be in italics here too

s/DIsabling/Disabling/

Perhaps it should be ... weaken the system security ?

In the table, under prefer-unencrypted, the rows should be:

|-------------|
| unencrypted |
|-------------|
| unencrypted |
|-------------|
| invalid     | 
|-------------|
1 Like

Thanks for the fixes and suggestions! I’m incorporated them all into the above doc.

Are both TPM 1.2 & 2.0 versions supported?

Sorry for the delay in replying, but I believe it’s just TPM 2.0. I’ll update the doc to make this clearer.

Toward the bottom of this page, there is a reference to the “storage-safety” setting, but the example shown does not list that setting.

Unfortunately /boot is still unecyprted which leaves the PC in the risk of compromising the kernel or initramfs files with a rootkit or a malware in case of physical access, The threat is not just copying the data.

I believe most of UEFI firmware can be easily bypassed, even they only allow short alphanumeric passwords only, even password can be reset with the manufacturer’s default password that you can get using the provided lock code after few failed login trials.

A full disk encryption including /boot is a must!

Debian 12 does that out of the box if you choose manual partitioning then created an EFI partition and an encrypted / parition.

Since in UbuntuCore the kernel, initrd and even grub itself are inside readonly gpg signed snap packages, how exactly do you envision they could be modified ?

(Note that this thread is about full disk encryption on UbuntuCore, not about desktop PCs, though I believe the PC implementation introduced with 23.10 is using the same setup with a signed kernel snap which should make it tinker proof, regardless if /boot is encrypted or not)

Kernel is signed with a certificate that exists inside the UEFI firmware, and if you gained access to the firmware as I explained above, you can import any certificate you want (it’s a feature of the firmware) and sign the modified kernel with it and the system will boot just fine.

The kernel comes from a snap (signed squashfs) that grub loop mounts from a hardcoded path … even if you changed the cert, how would you change the snap content without trashing the snaps gpg checksum that is used for verification?

1 Like

This phrasing is a little ambiguous; telling me only what isn’t supported doesn’t have as much strength as also telling me what is supported. Can this be disambiguated as a list of implementations which are supported, and a second list of implementations which aren’t?