Skip to content

Secure Boot, TPM & Full-Disk Encryption

Chapter 21: Secure Boot, TPM & Full-Disk Encryption

Section titled “Chapter 21: Secure Boot, TPM & Full-Disk Encryption”
  • Understand Secure Boot and how it protects the boot chain
  • Understand TPM and its role in measured boot and key sealing
  • Implement LUKS full-disk encryption
  • Configure TPM-based auto-unlock for encrypted disks

Secure Boot and TPM (Trusted Platform Module) protect a computer from being tampered with before the OS even loads. They ensure that no malicious code (like a bootkit) has infected the startup process, and they securely store the encryption keys that unlock the hard drive.

Attack Vectors Without Boot Security
─────────────────────────────────────
Physical access → Boot from USB → Mount disk → Read any file
Physical access → Edit GRUB → Boot single-user → Root shell
Evil maid → Swap bootloader → Keylogger captures passphrase
Physical access → Cold boot attack → Read RAM → Get encryption keys
Solution: Chain of Trust
─────────────────────────
┌─────────┐ signs ┌──────────┐ signs ┌──────────┐ signs
│ UEFI │────────►│ Shim/ │────────►│ GRUB2 │────────►
│ Secure │ │ MOK │ │ (signed) │
│ Boot │ │ Manager │ │ │
└─────────┘ └──────────┘ └──────────┘
┌──────────┐ signs ┌──────────────────┐
│ kernel │────────►│ Initramfs, │
│ (signed) │ │ systemd, etc. │
└──────────┘ └──────────────────┘
If ANY link is tampered with → Secure Boot rejects boot

Terminal window
# ── Check Secure Boot Status ──────────────────────────────
mokutil --sb-state
# SecureBoot enabled ← Secure Boot is on
# or: SecureBoot disabled
# Or from kernel:
cat /sys/firmware/efi/efivars/SecureBoot-*/ # UEFI variable
# ── View Enrolled Keys ────────────────────────────────────
# PK (Platform Key) = OEM manufacturer key
# KEK (Key Exchange Key) = Microsoft or distro key
# db (Signature Database) = Keys that are trusted to boot
# dbx (Forbidden Signature Database) = Revoked keys
mokutil --list-enrolled # List MOK (Machine Owner Keys)
mokutil --list-revoked # List revoked keys
# ── Enroll Your Own Key (for custom kernels/modules) ──────
# Generate MOK key
openssl req -newkey rsa:2048 -keyout MOK.priv -new -x509 -days 3650 -out MOK.der \
-subj "/CN=My Secure Boot Key/"
# Enroll the key
mokutil --import MOK.der
# → Prompts for password to use at next boot
# → On next boot, UEFI MOK Manager appears
# Sign a kernel module
/usr/src/linux-headers-$(uname -r)/scripts/sign-file \
sha256 MOK.priv MOK.der /path/to/module.ko
# ── Check Module Signing Status ───────────────────────────
modinfo module_name | grep sig

TPM Architecture and Use Cases
────────────────────────────────
TPM is a secure cryptographic chip:
• Sealed storage: Keys stored inside TPM, only released under
specific PCR (Platform Configuration Register) values
• Attestation: TPM can prove system state to remote verifier
• Random number generation: Hardware entropy source
• PCRs: Measurements of boot process stages
PCR (Platform Configuration Register) Values:
──────────────────────────────────────────────
PCR 0: Core Root of Trust (firmware)
PCR 1: Platform configuration
PCR 2: Option ROM code
PCR 3: Option ROM configuration
PCR 4: MBR / GRUB stage 1
PCR 5: MBR partition table
PCR 6: State transitions
PCR 7: Secure Boot state
PCR 8-15: GRUB, kernel cmdline, initrd measurements
Key Sealing to PCRs:
─────────────────────
Store disk encryption key sealed to PCR 7,14
→ Key only released if Secure Boot state matches
→ Disk won't auto-unlock if bootloader was tampered with!
Terminal window
# ── Check TPM Availability ────────────────────────────────
# TPM 2.0
ls /dev/tpm* # Should show /dev/tpm0 and /dev/tpmrm0
ls /dev/tpmrm0 # Resource manager
# Check TPM capabilities
tpm2_getcap properties-fixed | head -30
# ── Read PCR Values ───────────────────────────────────────
# TPM 2.0
tpm2_pcrread sha256:0,7,14
# View current PCR state (tells you what's currently measured)
tpm2_pcrread sha256
# ── Seal a Secret to TPM ──────────────────────────────────
# Create a policy tied to current PCR values
tpm2_createpolicy --policy-pcr --pcr-list sha256:7,14 --policy /tmp/pcr.policy
# Seal a secret (disk key, password, etc.)
echo "my_secret_key" > /tmp/secret
tpm2_create -G rsa -u /tmp/sealed.pub -r /tmp/sealed.priv \
-C /tmp/primary.ctx \
-L /tmp/pcr.policy \
-i /tmp/secret
# Unseal (only works if PCR values match)
tpm2_unseal -c /tmp/sealed.ctx -L /tmp/pcr.policy -o /tmp/recovered_secret

LUKS (Linux Unified Key Setup) is the standard for disk encryption on Linux.

LUKS Architecture
──────────────────
Physical Disk:
┌─────────────────────────────────────────────────────────┐
│ LUKS Header (metadata) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Cipher: aes-xts-plain64 │ │
│ │ Key size: 512-bit │ │
│ │ Hash: sha512 │ │
│ │ │ │
│ │ Key Slot 0: Encrypted Master Key (by passphrase)│ │
│ │ Key Slot 1: Encrypted Master Key (by TPM key) │ │
│ │ Key Slot 2: Encrypted Master Key (by recovery) │ │
│ │ Key Slots 3-7: (empty) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Encrypted Data (with Master Key) │
│ (filesystem: ext4, XFS, etc.) │
└─────────────────────────────────────────────────────────┘
To decrypt:
1. User provides passphrase
2. Passphrase decrypts the key slot → Master Key
3. Master Key decrypts the data
Multiple key slots = multiple ways to unlock the same disk
Terminal window
# ── Create LUKS-encrypted Partition ──────────────────────
# Format with LUKS2 (modern)
cryptsetup luksFormat --type luks2 \
--cipher aes-xts-plain64 \
--key-size 512 \
--hash sha512 \
--pbkdf argon2id \
/dev/sdb1
# ── Open/Unlock ───────────────────────────────────────────
cryptsetup open /dev/sdb1 mydata # Opens as /dev/mapper/mydata
# Enter passphrase when prompted
# Create filesystem and mount
mkfs.ext4 /dev/mapper/mydata
mount /dev/mapper/mydata /mnt/data
# ── Close ─────────────────────────────────────────────────
umount /mnt/data
cryptsetup close mydata
# ── LUKS Key Management ───────────────────────────────────
# View LUKS info (which slots are used)
cryptsetup luksDump /dev/sdb1
# Add a key (e.g., recovery key)
cryptsetup luksAddKey /dev/sdb1
# Add key from file (for automated systems)
dd if=/dev/urandom of=/etc/luks/recovery_key bs=512 count=1
chmod 400 /etc/luks/recovery_key
cryptsetup luksAddKey /dev/sdb1 /etc/luks/recovery_key
# Remove a key slot
cryptsetup luksRemoveKey /dev/sdb1 # Remove by passphrase
cryptsetup luksKillSlot /dev/sdb1 3 # Remove slot 3
# Change passphrase
cryptsetup luksChangeKey /dev/sdb1
# ── /etc/crypttab (auto-unlock at boot) ───────────────────
# Format: name source_device key_file options
mydata /dev/sdb1 none luks # Prompt for passphrase at boot
mydata /dev/sdb1 /etc/luks/key luks # Use key file
# UUID is preferred over device name:
mydata UUID=abc123-def456 none luks
# Update initramfs to include new crypttab entry
update-initramfs -u -k all # Debian/Ubuntu
dracut --force # RHEL/CentOS

21.5 TPM Auto-Unlock (Passwordless Encrypted Boot)

Section titled “21.5 TPM Auto-Unlock (Passwordless Encrypted Boot)”

Combining TPM sealing with LUKS eliminates the need to enter a passphrase at boot while still requiring physical integrity:

Terminal window
# Using systemd-cryptenroll (systemd 248+)
# Enroll TPM2 as a key slot for LUKS volume
# Basic TPM enrollment (tied to PCR 7 = Secure Boot state)
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sda2
# More secure: tie to PCR 7 (Secure Boot) + PCR 14 (MOK)
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+14 /dev/sda2
# Update /etc/crypttab to use TPM:
# sda2_crypt UUID=xxx none luks,tpm2-device=auto
# Result: On boot, TPM releases the key automatically
# If bootloader is tampered with → PCR values change → TPM won't release key
# → Disk stays encrypted, attacker can't read data
# Using clevis + tang (network-based unlock):
# Server provides key over network when server is in trusted network
# Disk auto-unlocks only when the server can reach the tang server
# (not accessible if attacker takes disk offline)
clevis luks bind -d /dev/sda2 tang '{"url":"https://tang.example.com"}'

Terminal window
# ── AWS ───────────────────────────────────────────────────
# EBS encryption with AWS KMS
aws ec2 create-volume \
--size 100 \
--availability-zone us-east-1a \
--encrypted \
--kms-key-id arn:aws:kms:us-east-1:123456789:key/mrk-xxx
# Default encryption for all new EBS volumes
aws ec2 enable-ebs-encryption-by-default --region us-east-1
# ── GCP ───────────────────────────────────────────────────
# CMEK (Customer-Managed Encryption Key) for GCP
gcloud compute disks create my-disk \
--kms-key projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key
# ── Azure ─────────────────────────────────────────────────
# Azure Disk Encryption with Azure Key Vault
az vm encryption enable \
--resource-group myRG \
--name myVM \
--disk-encryption-keyvault myKV \
--volume-type All

Q1: What is Secure Boot and how does it establish a chain of trust?

Answer: Secure Boot is a UEFI feature that ensures only cryptographically signed bootloaders and kernels can execute. The chain of trust: (1) UEFI firmware (signed by OEM, stored in ROM) verifies the bootloader signature against the key database (PK/KEK/db). (2) The bootloader (e.g., GRUB shim) verifies the GRUB binary signature. (3) GRUB verifies the kernel signature. (4) The kernel verifies signed kernel modules. If any component is tampered with (unsigned or wrong signature), boot halts. This prevents: booting from malicious USB, replacing the bootloader with a keylogger, loading unsigned kernel modules.

Q2: What is the difference between a LUKS key slot and the master key?

Answer: The LUKS master key is the actual encryption key that encrypts/decrypts the data on disk. It’s randomly generated and never exposed directly. A key slot stores the master key in encrypted form — encrypted by a user-provided passphrase (or TPM key, or recovery key). LUKS supports 8 key slots, each storing a differently encrypted copy of the same master key. This means: multiple people can have different passphrases to unlock the same disk, you can add/remove passphrases without re-encrypting the entire disk (just re-encrypting the master key slot), and recovery keys can be stored separately. When you unlock with any key slot, you get the same master key.


TechnologyPurpose
Secure BootVerify bootloader/kernel signatures
TPMHardware security chip, PCR measurements
PCRsMeasurements of boot stages
LUKSLinux disk encryption standard
Key slotsMultiple unlock methods for same disk
cryptenrollTPM-based auto-unlock for LUKS
clevis/tangNetwork-based auto-unlock

Chapter 2 (Boot Process).


Advantages: Prevents bootkits, secures disk encryption keys even if the drive is stolen. Disadvantages: Makes installing custom kernels or third-party drivers (like NVIDIA) very difficult.


  • Losing the LUKS recovery key — if TPM fails, data is lost permanently.
  • Updating the kernel or bootloader without resigning or updating PCR measurements, causing boot failure.

SymptomCauseDiagnosisFix
System won’t boot after kernel updateSecure Boot signature missingCheck bootloader error messagesSign the new kernel or temporarily disable Secure Boot
LUKS asks for password despite TPMPCR values changed (e.g., firmware update)Enter recovery passwordRebind the LUKS volume to the new PCR values

Objective: Check Secure Boot and TPM status.

Terminal window
# 1. Check Secure Boot status
mokutil --sb-state
# or: dmesg | grep -i "secure boot"
# 2. Check TPM device
ls -l /dev/tpm*
# 3. View LUKS encrypted volumes
lsblk --fs | grep crypto_LUKS

  1. Use clevis to bind a LUKS volume to a TPM2 chip, allowing automatic decryption at boot.
  2. Use mokutil to enroll a new Machine Owner Key (MOK) for signing custom kernel modules.

  • Secure Boot ensures only signed bootloaders and kernels can run.
  • TPM securely stores cryptographic keys and performs platform measurements (PCRs).
  • LUKS provides full-disk encryption to protect data at rest against physical theft.

  • TPM 2.0 specification
  • Arch Wiki: Secure Boot, dm-crypt/Encrypting an entire system


Last Updated: July 2026