blob: 457d0e1550fb3a97f42c0fbc422b5ddff7bf366b (
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
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
|
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.local.boot.tpm;
pcrList = concatStringsSep "," (map toString cfg.initrd.pcrs);
# Crear signing-key con:
# $ openssl genrsa -out ~/vtmp/signing-key.priv 2048
# $ openssl rsa -in ~/vtmp/signing-key.priv -out ~/vtmp/signing-key.pub -pubout
# Y copiar signing-key.pub a /boot/tpm-boot. Guardar signing-key.priv en lugar seguro.
#
# Crear llave con:
# $ tpm2_loadexternal -G rsa -C owner -u signing-key.pub -c signing-key.ctx -n signing-key.name
# $ tpm2_startauthsession -S session.ctx
# $ tpm2_policyauthorize -S session.ctx -L require-signed.policy -n signing-key.name
# $ tpm2_flushcontext session.ctx
# $ tpm2_createprimary -C owner -g sha256 -G ecc -c prim.ctx
# $ head -c128 /dev/urandom | tpm2_create -C prim.ctx -u key.pub -r key.priv -c key.ctx -L require-signed.policy -i-
# Y mover key.priv/key.pub a /boot/tpm-boot
#
# Usage: tpm2-grant-next-boot < signing-key.priv
# Genera auth.policy y auth.sig
tpm2-grant-next-boot = pkgs.writeShellApplication {
name = "tpm2-grant-next-boot";
runtimeInputs = [
pkgs.jq
pkgs.openssl
pkgs.sbctl
pkgs.tpm2-tools
];
text = ''
if [ -z "''${YES_I_DO_WANT_TO_SIGN_WITH_SECURE_BOOT_DISABLED:=}" ] && [ "$(sbctl status --json | jq .secure_boot)" != "truee" ]; then
echo "$0: bad Secure Boot state, check the output of \`sbctl status\`" >&2
echo "$0: signing a TPM PCR policy with Secure Boot disabled is dangerous" >&2
echo "$0: set 'YES_I_DO_WANT_TO_SIGN_WITH_SECURE_BOOT_DISABLED' to skip this check" >&2
exit 1
fi
ctx_dir="$(mktemp -d)"
trap 'rm -rf -- "$ctx_dir"' EXIT
tpm2_createprimary -Q -C owner -g sha256 -G ecc -c "$ctx_dir/prim.ctx"
tpm2_startauthsession -Q -S "$ctx_dir/session.ctx"
tpm_resets=$(tpm2_readclock | grep reset_count | sed 's/.*: //')
tpm2_policycountertimer -Q -S "$ctx_dir/session.ctx" resets="$((tpm_resets+1))"
tpm2_policypcr -Q -S "$ctx_dir/session.ctx" -L auth.policy -l sha256:${pcrList}
tpm2_flushcontext -Q "$ctx_dir/session.ctx"
openssl dgst -sha256 -sign /dev/stdin -out auth.sig auth.policy
'';
};
in {
options.local.boot.tpm = {
enable = mkEnableOption "Trusted Platform Module 2.0";
driver = mkOption {
type = types.enum ["tis" "crb"];
};
initrd = {
enable = mkEnableOption "TPM2 in initrd";
pcrs = mkOption {
type = with types; listOf (ints.between 0 23);
# From 'systemd-analyze pcrs'
default = [
0 # platform-code
1 # platform-config
2 # external-code
3 # external-config
4 # boot-loader-code
5 # boot-loader-config
7 # secure-boot-policy
9 # kernel-initrd
11 # kernel-boot
12 # kernel-config
13 # sysexts
14 # shim-policy
];
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.initrd.enable -> config.local.boot.efi.enable;
message = "TPM2 in initrd requires EFI";
}
{
assertion = cfg.initrd.enable -> cfg.enable;
message = "TPM2 in initrd requires TPM2";
}
];
boot.initrd = mkIf cfg.initrd.enable {
extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.tpm2-tools}/bin/.tpm2-wrapped
mv $out/bin/{.tpm2-wrapped,tpm2}
cp {${pkgs.tpm2-tss},$out}/lib/libtss2-tcti-device.so.0
'';
kernelModules = [
"tpm_${cfg.driver}"
];
};
environment.systemPackages =
[
pkgs.tpm2-tools
]
++ optionals cfg.initrd.enable [
tpm2-grant-next-boot
];
security.tpm2 = {
enable = true;
pkcs11.enable = true;
tctiEnvironment.enable = true;
};
};
}
|