blob: da6f73a43d58f257797670215adcd5eeeb68ed25 (
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
|
{
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 = optionals cfg.initrd.enable [
tpm2-grant-next-boot
];
security.tpm2 = {
enable = true;
pkcs11.enable = true;
tctiEnvironment.enable = true;
};
};
}
|