summaryrefslogtreecommitdiffstatshomepage
path: root/docs/tpm-unlock.md
blob: 0cd915b7fa1088415b980a44138bc6783c67ba9a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# TPM Unlock on Arch

The root volume uses a systemd TPM enrollment with a `pcrlock` policy that
protects PCR 7. Keep a working disk passphrase and the policy recovery PIN in
a secure location accessible without unlocking this laptop.

The policy, enrollment, and generated component files are host state. Do not
copy them into this repo. Deploy this configuration only after policy creation,
enrollment, and an automatic unlock test have succeeded.

## Deploy

Run on the Arch host, outside aibox:

```sh
just apply
sudo systemctl daemon-reload
sudo systemctl enable systemd-pcrlock-make-policy.service
sudo systemctl restart systemd-pcrlock-make-policy.service
sudo journalctl -b -u systemd-pcrlock-make-policy.service --no-pager
```

The journal must show PCR 7 in the protection mask, or report that the policy
has not changed. Check for errors and unmet conditions. A successful command
exit alone does not prove that a conditional service ran.

The service runs after root is unlocked. It updates the existing TPM policy
and boot credential from the approved component files. It selects only PCR 7
and requires the policy files and the mounted EFI System Partition at `/boot`.
On a host without an existing policy, the service skips execution.

Leave `systemd-pcrlock-secureboot-policy.service` and
`systemd-pcrlock-secureboot-authority.service` disabled. These services generate
component files from the current system. This setup retains the approved
components instead of automatically accepting changes to Secure Boot settings.

## Updates

Normal kernel and initramfs updates do not require LUKS re-enrollment. Keep the
existing mkinitcpio and Secure Boot signing hooks. Policy maintenance does not
build or sign UKIs.

After a systemd update, check the prediction before rebooting:

```sh
sudo /usr/lib/systemd/systemd-pcrlock --pcr=7 --location=770 predict
```

If PCR 7 is included and the prediction completes without errors, refresh the
policy and check the journal:

```sh
sudo systemctl restart systemd-pcrlock-make-policy.service
sudo journalctl -b -u systemd-pcrlock-make-policy.service --no-pager
```

Prediction uses the current boot log. It cannot guarantee that changed firmware
or boot software will produce the same measurements on the next boot. Keep the
disk passphrase available. No unattended hook relaxes protection or replaces
LUKS enrollments.

## Unused NvPCR Measurements

This host uses PCR 7 for root unlock. It does not use the default `cryptsetup`,
`hardware`, `login`, or `verity` NvPCR measurements. Systemd 262 requires a signed
initrd PCR policy for NvPCR initialization, which this boot setup does not provide.
This is separate from the NV index that stores the `pcrlock` policy.

Empty files in `etc/nvpcr/` mask the four vendor definitions. Empty unit files
mask only `systemd-pcrproduct.service` and `systemd-pcrlogin@.service`. Keep these
files at zero bytes: adding comments removes the mask. SRK setup and PCR 7
policy maintenance remain active. No TPM index or LUKS keyslot is deleted.
The mkinitcpio drop-in includes the masks in each rebuilt initramfs.

Deploy outside aibox, with the recovery passphrase available:

```sh
just apply
sudo mkinitcpio -P
sudo sbctl sign-all
sudo sbctl verify
```

Stop if image generation or signing fails. Confirm that the rebuilt UKIs are
signed before rebooting. No re-enrollment is required. The current boot's failed
setup status can remain until the next boot; do not restart TPM setup merely
to clear that status.

After an approved reboot, confirm automatic unlock and inspect:

```sh
sudo journalctl -b --no-pager \
  -u systemd-tpm2-setup-early.service \
  -u systemd-tpm2-setup.service \
  -u systemd-pcrlock-make-policy.service
systemctl --failed --no-pager
systemctl is-enabled systemd-pcrproduct.service systemd-pcrlogin@.service
```

The two measurement units must report `masked`. SRK setup must have no NvPCR
initialization failures, and the policy must retain PCR 7 protection.

To roll back, remove the four `/etc/nvpcr/*.nvpcr` masks listed above, the two
empty unit files, and `/etc/mkinitcpio.conf.d/60-no-nvpcr.conf`. Remove the same
files from the repo to prevent redeployment. Reload systemd, rebuild and sign
the UKIs, and test at the next approved reboot. This restores the vendor
behavior, including its errors if signed initrd PCR policies are still absent.

Sources: [systemd 262 release notes](https://github.com/systemd/systemd/releases/tag/v262),
[NvPCR setup](https://github.com/systemd/systemd/blob/v262/src/tpm2-setup/tpm2-setup.c),
and [empty-file mask handling](https://github.com/systemd/systemd/blob/v262/src/basic/conf-files.c).

## Recovery

If automatic unlock fails, use the disk passphrase. Inspect the boot journal
and `systemd-pcrlock log` before changing policy. Do not clear the TPM, remove
the policy, or remove password slots.

After confirming that a Secure Boot change was intended, regenerate its
component files:

```sh
sudo /usr/lib/systemd/systemd-pcrlock lock-secureboot-policy
sudo /usr/lib/systemd/systemd-pcrlock lock-secureboot-authority
sudo /usr/lib/systemd/systemd-pcrlock --pcr=7 --location=770 predict
```

Proceed only if PCR 7 is included. Update the existing policy with its recovery
PIN when the old policy no longer permits updates:

```sh
sudo /usr/lib/systemd/systemd-pcrlock \
  --pcr=7 --location=770 --recovery-pin=query make-policy
```

Enter the policy recovery PIN, not the disk passphrase. Do not record this
session or share the PIN. Reboot to test automatic unlock. An update to the
existing policy normally needs neither re-enrollment nor a UKI rebuild.

Reference: [systemd-pcrlock manual](https://man.archlinux.org/man/systemd-pcrlock.8.en).