summarylogtreecommitdiffstats
path: root/README.md
blob: e42a6c5999ac70f10a58fb5e9aac69401e1477c0 (plain)
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
mkinitcpio TPM2 hook
====================

This mkinitcpio hook allows for an encrypted root device to use a key sealed by
a TPM 2.0. It should be placed immediately before the `encrypt` hook in
`/etc/mkinitcpio.conf`.

    HOOKS="base udev ... block tpm2 encrypt filesystems 

The `tpm2` hook attempts to "unseal" a LUKS keyfile previously sealed by the
TPM. The sealed files must reside on an unencrypted filesystem available to the
kernel at boot or may be stored in TPM non-volatile memory (NVRAM). For example,
assuming your unencrypted keyfile is at `/root/mykey` and a primary TPM key has
been persisted to `0x81000001`:

    # tpm2_createpolicy -P -L sha1:0,2,4,7 -f pcr.pol -T device:/dev/tpmrm0
    # tpm2_create -H 0x81000001 -g sha256 -G keyedhash -A 0x492 -I /root/mykey \
      -L pcr.pol -r /boot/mykey.priv -u /boot/mykey.pub -T device:/dev/tpmrm0

After generating a TPM-sealed key, both `tpmkey` and `tpmpcr` should be specified
on the kernel command line.

The `tpmkey` parameter has several formats:

    tpmkey=[device]:[path]:[handle]
    tpmkey=[device]:[publicpath]:[privatepath]:[handle]
    tpmkey=nvram:[index]
    tpmkey=nvram:[index]:[offset]:[size]

Where `[device]` represents the raw block device on which the key exists,
`[path]` is the absolute base path of the sealed files within the device, and
`[handle]` is the TPM handle of the key's parent object. If only `[path]` is
specified, '.pub' and '.priv' will be appended to the path to locate the public
and private files, respectively. The absolute `[publicpath]` and `[privatepath]`
can be specified separately if needed. For example, if `/dev/sda1` is an EFI
partition mounted at `/boot`:

    tpmkey=/dev/sda1:/mykey:0x81000001

Setting `[device]` to 'nvram' indicates that the key is stored in TPM NVRAM. In
this case `[index]` is the NVRAM area index, `[offset]` is the offset of the key
in bytes and `[size]` is the size of the key in bytes.

The `tpmpcr` parameter should hold the TPM2 PCR bank specification that will
unlock the sealed key.

    tpmpcr=sha1:0,2,7

Multiple specs can be separated by a '|' and key decryption will be attempted
with each set of banks.

    tpmpcr=sha1:0,2,4,7|sha1:0,2,7

Instead of a bank specification, the first item in the `tpmpcr` parameter may be
used to indicate a PCR to extend _after_ the key has been unsealed.

    extend:[pcrnum]:[alg]

Where `[pcrnum]` is the PCR number to extend and `[alg]` is the bank algorithm.
For example, to extend PCR 8 in the sha1 bank:

    tpmpcr=extend:8:sha1|sha1:0,2,7

You may also need to add the `vfat` file system driver to the `MODULES` array:

    MODULES=(vfat)

Finally, rebuild the initramfs:

    # mkinitcpio -p linux

During boot, the hook will initialize the TPM and attempt to unseal the key. If
the key is successfully unsealed, it will be passed to the `encrypt` hook to
perform the actual decryption of the root file system.

Depending on the PCR banks to which the sealed key is bound, system changes such
as kernel updates or firmware adjustments may prevent the key from being
unsealed. If this happens, the disk must be manually unlocked with a passphrase
and a new sealed key file needs to be generated. For this reason, it is CRUCIAL
to add a separate "recovery" passphrase to the LUKS keys.