1# tcsd daemon.
2{
3 config,
4 options,
5 pkgs,
6 lib,
7 ...
8}:
9let
10
11 cfg = config.services.tcsd;
12 opt = options.services.tcsd;
13
14 tcsdConf = pkgs.writeText "tcsd.conf" ''
15 port = 30003
16 num_threads = 10
17 system_ps_file = ${cfg.stateDir}/system.data
18 # This is the log of each individual measurement done by the system.
19 # By re-calculating the PCR registers based on this information, even
20 # finer details about the measured environment can be inferred than
21 # what is available directly from the PCR registers.
22 firmware_log_file = /sys/kernel/security/tpm0/binary_bios_measurements
23 kernel_log_file = /sys/kernel/security/ima/binary_runtime_measurements
24 firmware_pcrs = ${cfg.firmwarePCRs}
25 kernel_pcrs = ${cfg.kernelPCRs}
26 platform_cred = ${cfg.platformCred}
27 conformance_cred = ${cfg.conformanceCred}
28 endorsement_cred = ${cfg.endorsementCred}
29 #remote_ops = create_key,random
30 #host_platform_class = server_12
31 #all_platform_classes = pc_11,pc_12,mobile_12
32 '';
33
34in
35{
36
37 ###### interface
38
39 options = {
40
41 services.tcsd = {
42
43 enable = lib.mkOption {
44 default = false;
45 type = lib.types.bool;
46 description = ''
47 Whether to enable tcsd, a Trusted Computing management service
48 that provides TCG Software Stack (TSS). The tcsd daemon is
49 the only portal to the Trusted Platform Module (TPM), a hardware
50 chip on the motherboard.
51 '';
52 };
53
54 user = lib.mkOption {
55 default = "tss";
56 type = lib.types.str;
57 description = "User account under which tcsd runs.";
58 };
59
60 group = lib.mkOption {
61 default = "tss";
62 type = lib.types.str;
63 description = "Group account under which tcsd runs.";
64 };
65
66 stateDir = lib.mkOption {
67 default = "/var/lib/tpm";
68 type = lib.types.path;
69 description = ''
70 The location of the system persistent storage file.
71 The system persistent storage file holds keys and data across
72 restarts of the TCSD and system reboots.
73 '';
74 };
75
76 firmwarePCRs = lib.mkOption {
77 default = "0,1,2,3,4,5,6,7";
78 type = lib.types.str;
79 description = "PCR indices used in the TPM for firmware measurements.";
80 };
81
82 kernelPCRs = lib.mkOption {
83 default = "8,9,10,11,12";
84 type = lib.types.str;
85 description = "PCR indices used in the TPM for kernel measurements.";
86 };
87
88 platformCred = lib.mkOption {
89 default = "${cfg.stateDir}/platform.cert";
90 defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/platform.cert"'';
91 type = lib.types.path;
92 description = ''
93 Path to the platform credential for your TPM. Your TPM
94 manufacturer may have provided you with a set of credentials
95 (certificates) that should be used when creating identities
96 using your TPM. When a user of your TPM makes an identity,
97 this credential will be encrypted as part of that process.
98 See the 1.1b TPM Main specification section 9.3 for information
99 on this process. '';
100 };
101
102 conformanceCred = lib.mkOption {
103 default = "${cfg.stateDir}/conformance.cert";
104 defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/conformance.cert"'';
105 type = lib.types.path;
106 description = ''
107 Path to the conformance credential for your TPM.
108 See also the platformCred option'';
109 };
110
111 endorsementCred = lib.mkOption {
112 default = "${cfg.stateDir}/endorsement.cert";
113 defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/endorsement.cert"'';
114 type = lib.types.path;
115 description = ''
116 Path to the endorsement credential for your TPM.
117 See also the platformCred option'';
118 };
119 };
120
121 };
122
123 ###### implementation
124
125 config = lib.mkIf cfg.enable {
126
127 environment.systemPackages = [ pkgs.trousers ];
128
129 services.udev.extraRules = ''
130 # Give tcsd ownership of all TPM devices
131 KERNEL=="tpm[0-9]*", MODE="0660", OWNER="${cfg.user}", GROUP="${cfg.group}"
132 # Tag TPM devices to create a .device unit for tcsd to depend on
133 ACTION=="add", KERNEL=="tpm[0-9]*", TAG+="systemd"
134 '';
135
136 systemd.tmpfiles.rules = [
137 # Initialise the state directory
138 "d ${cfg.stateDir} 0770 ${cfg.user} ${cfg.group} - -"
139 ];
140
141 systemd.services.tcsd = {
142 description = "Manager for Trusted Computing resources";
143 documentation = [ "man:tcsd(8)" ];
144
145 requires = [ "dev-tpm0.device" ];
146 after = [ "dev-tpm0.device" ];
147 wantedBy = [ "multi-user.target" ];
148
149 serviceConfig = {
150 User = cfg.user;
151 Group = cfg.group;
152 ExecStart = "${pkgs.trousers}/sbin/tcsd -f -c ${tcsdConf}";
153 };
154 };
155
156 users.users = lib.optionalAttrs (cfg.user == "tss") {
157 tss = {
158 group = "tss";
159 isSystemUser = true;
160 };
161 };
162
163 users.groups = lib.optionalAttrs (cfg.group == "tss") { tss = { }; };
164 };
165}