1 { lib, pkgs, config, ... }:
3 cfg = config.security.tpm2;
5 # This snippet is taken from tpm2-tss/dist/tpm-udev.rules, but modified to allow custom user/groups
6 # The idea is that the tssUser is allowed to access the TPM and kernel TPM resource manager, while
7 # the tssGroup is only allowed to access the kernel resource manager
8 # Therefore, if either of the two are null, the respective part isn't generated
9 udevRules = tssUser: tssGroup: ''
10 ${lib.optionalString (tssUser != null) ''KERNEL=="tpm[0-9]*", MODE="0660", OWNER="${tssUser}"''}
11 ${lib.optionalString (tssUser != null || tssGroup != null)
12 ''KERNEL=="tpmrm[0-9]*", MODE="0660"''
13 + lib.optionalString (tssUser != null) '', OWNER="${tssUser}"''
14 + lib.optionalString (tssGroup != null) '', GROUP="${tssGroup}"''
19 options.security.tpm2 = {
20 enable = lib.mkEnableOption "Trusted Platform Module 2 support";
22 tssUser = lib.mkOption {
24 Name of the tpm device-owner and service user, set if applyUdevRules is
27 type = lib.types.nullOr lib.types.str;
28 default = if cfg.abrmd.enable then "tss" else "root";
29 defaultText = lib.literalExpression ''if config.security.tpm2.abrmd.enable then "tss" else "root"'';
32 tssGroup = lib.mkOption {
34 Group of the tpm kernel resource manager (tpmrm) device-group, set if
35 applyUdevRules is set.
37 type = lib.types.nullOr lib.types.str;
41 applyUdevRules = lib.mkOption {
43 Whether to make the /dev/tpm[0-9] devices accessible by the tssUser, or
44 the /dev/tpmrm[0-9] by tssGroup respectively
46 type = lib.types.bool;
51 enable = lib.mkEnableOption ''
52 Trusted Platform 2 userspace resource manager daemon
55 package = lib.mkOption {
56 description = "tpm2-abrmd package to use";
57 type = lib.types.package;
58 default = pkgs.tpm2-abrmd;
59 defaultText = lib.literalExpression "pkgs.tpm2-abrmd";
64 enable = lib.mkEnableOption ''
65 TPM2 PKCS#11 tool and shared library in system path
66 (`/run/current-system/sw/lib/libtpm2_pkcs11.so`)
69 package = lib.mkOption {
70 description = "tpm2-pkcs11 package to use";
71 type = lib.types.package;
72 default = pkgs.tpm2-pkcs11;
73 defaultText = lib.literalExpression "pkgs.tpm2-pkcs11";
78 enable = lib.mkOption {
80 Set common TCTI environment variables to the specified value.
85 type = lib.types.bool;
89 interface = lib.mkOption {
91 The name of the TPM command transmission interface (TCTI) library to
94 type = lib.types.enum [ "tabrmd" "device" ];
98 deviceConf = lib.mkOption {
100 Configuration part of the device TCTI, e.g. the path to the TPM device.
101 Applies if interface is set to "device".
102 The format is specified in the
104 tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options).
106 type = lib.types.str;
107 default = "/dev/tpmrm0";
110 tabrmdConf = lib.mkOption {
112 Configuration part of the tabrmd TCTI, like the D-Bus bus name.
113 Applies if interface is set to "tabrmd".
114 The format is specified in the
116 tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options).
118 type = lib.types.str;
119 default = "bus_name=com.intel.tss2.Tabrmd";
124 config = lib.mkIf cfg.enable (lib.mkMerge [
126 # PKCS11 tools and library
127 environment.systemPackages = lib.mkIf cfg.pkcs11.enable [
128 (lib.getBin cfg.pkcs11.package)
129 (lib.getLib cfg.pkcs11.package)
132 services.udev.extraRules = lib.mkIf cfg.applyUdevRules
133 (udevRules cfg.tssUser cfg.tssGroup);
135 # Create the tss user and group only if the default value is used
136 users.users.${cfg.tssUser} = lib.mkIf (cfg.tssUser == "tss") {
140 users.groups.${cfg.tssGroup} = lib.mkIf (cfg.tssGroup == "tss") {};
142 environment.variables = lib.mkIf cfg.tctiEnvironment.enable (
143 lib.attrsets.genAttrs [
146 ] (_: ''${cfg.tctiEnvironment.interface}:${
147 if cfg.tctiEnvironment.interface == "tabrmd" then
148 cfg.tctiEnvironment.tabrmdConf
150 cfg.tctiEnvironment.deviceConf
155 (lib.mkIf cfg.abrmd.enable {
156 systemd.services."tpm2-abrmd" = {
157 wantedBy = [ "multi-user.target" ];
162 BusName = "com.intel.tss2.Tabrmd";
163 ExecStart = "${cfg.abrmd.package}/bin/tpm2-abrmd";
169 services.dbus.packages = lib.singleton cfg.abrmd.package;
173 meta.maintainers = with lib.maintainers; [ lschuermann ];