at master 5.8 kB view raw
1{ 2 lib, 3 pkgs, 4 config, 5 ... 6}: 7let 8 cfg = config.security.tpm2; 9 10 # This snippet is taken from tpm2-tss/dist/tpm-udev.rules, but modified to allow custom user/groups 11 # The idea is that the tssUser is allowed to access the TPM and kernel TPM resource manager, while 12 # the tssGroup is only allowed to access the kernel resource manager 13 # Therefore, if either of the two are null, the respective part isn't generated 14 udevRules = tssUser: tssGroup: '' 15 ${lib.optionalString (tssUser != null) ''KERNEL=="tpm[0-9]*", MODE="0660", OWNER="${tssUser}"''} 16 ${ 17 lib.optionalString (tssUser != null || tssGroup != null) ''KERNEL=="tpmrm[0-9]*", MODE="0660"'' 18 + lib.optionalString (tssUser != null) '', OWNER="${tssUser}"'' 19 + lib.optionalString (tssGroup != null) '', GROUP="${tssGroup}"'' 20 } 21 ''; 22 23in 24{ 25 options.security.tpm2 = { 26 enable = lib.mkEnableOption "Trusted Platform Module 2 support"; 27 28 tssUser = lib.mkOption { 29 description = '' 30 Name of the tpm device-owner and service user, set if applyUdevRules is 31 set. 32 ''; 33 type = lib.types.nullOr lib.types.str; 34 default = if cfg.abrmd.enable then "tss" else "root"; 35 defaultText = lib.literalExpression ''if config.security.tpm2.abrmd.enable then "tss" else "root"''; 36 }; 37 38 tssGroup = lib.mkOption { 39 description = '' 40 Group of the tpm kernel resource manager (tpmrm) device-group, set if 41 applyUdevRules is set. 42 ''; 43 type = lib.types.nullOr lib.types.str; 44 default = "tss"; 45 }; 46 47 applyUdevRules = lib.mkOption { 48 description = '' 49 Whether to make the /dev/tpm[0-9] devices accessible by the tssUser, or 50 the /dev/tpmrm[0-9] by tssGroup respectively 51 ''; 52 type = lib.types.bool; 53 default = true; 54 }; 55 56 abrmd = { 57 enable = lib.mkEnableOption '' 58 Trusted Platform 2 userspace resource manager daemon 59 ''; 60 61 package = lib.mkPackageOption pkgs "tpm2-abrmd" { }; 62 }; 63 64 pkcs11 = { 65 enable = lib.mkEnableOption '' 66 TPM2 PKCS#11 tool and shared library in system path 67 (`/run/current-system/sw/lib/libtpm2_pkcs11.so`) 68 ''; 69 70 package = lib.mkOption { 71 description = "tpm2-pkcs11 package to use"; 72 type = lib.types.package; 73 default = if cfg.abrmd.enable then pkgs.tpm2-pkcs11.abrmd else pkgs.tpm2-pkcs11; 74 defaultText = lib.literalExpression "if config.security.tpm2.abrmd.enable then pkgs.tpm2-pkcs11.abrmd else pkgs.tpm2-pkcs11"; 75 }; 76 }; 77 78 tctiEnvironment = { 79 enable = lib.mkOption { 80 description = '' 81 Set common TCTI environment variables to the specified value. 82 The variables are 83 - `TPM2TOOLS_TCTI` 84 - `TPM2_PKCS11_TCTI` 85 ''; 86 type = lib.types.bool; 87 default = false; 88 }; 89 90 interface = lib.mkOption { 91 description = '' 92 The name of the TPM command transmission interface (TCTI) library to 93 use. 94 ''; 95 type = lib.types.enum [ 96 "tabrmd" 97 "device" 98 ]; 99 default = "device"; 100 }; 101 102 deviceConf = lib.mkOption { 103 description = '' 104 Configuration part of the device TCTI, e.g. the path to the TPM device. 105 Applies if interface is set to "device". 106 The format is specified in the 107 [ 108 tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options). 109 ''; 110 type = lib.types.str; 111 default = "/dev/tpmrm0"; 112 }; 113 114 tabrmdConf = lib.mkOption { 115 description = '' 116 Configuration part of the tabrmd TCTI, like the D-Bus bus name. 117 Applies if interface is set to "tabrmd". 118 The format is specified in the 119 [ 120 tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options). 121 ''; 122 type = lib.types.str; 123 default = "bus_name=com.intel.tss2.Tabrmd"; 124 }; 125 }; 126 }; 127 128 config = lib.mkIf cfg.enable ( 129 lib.mkMerge [ 130 { 131 # PKCS11 tools and library 132 environment.systemPackages = lib.mkIf cfg.pkcs11.enable [ 133 (lib.getBin cfg.pkcs11.package) 134 (lib.getLib cfg.pkcs11.package) 135 ]; 136 137 services.udev.extraRules = lib.mkIf cfg.applyUdevRules (udevRules cfg.tssUser cfg.tssGroup); 138 139 # Create the tss user and group only if the default value is used 140 users.users.${cfg.tssUser} = lib.mkIf (cfg.tssUser == "tss") { 141 isSystemUser = true; 142 group = "tss"; 143 }; 144 users.groups.${cfg.tssGroup} = lib.mkIf (cfg.tssGroup == "tss") { }; 145 146 environment.variables = lib.mkIf cfg.tctiEnvironment.enable ( 147 lib.attrsets.genAttrs 148 [ 149 "TPM2TOOLS_TCTI" 150 "TPM2_PKCS11_TCTI" 151 ] 152 ( 153 _: 154 ''${cfg.tctiEnvironment.interface}:${ 155 if cfg.tctiEnvironment.interface == "tabrmd" then 156 cfg.tctiEnvironment.tabrmdConf 157 else 158 cfg.tctiEnvironment.deviceConf 159 }'' 160 ) 161 ); 162 } 163 164 (lib.mkIf cfg.abrmd.enable { 165 systemd.services."tpm2-abrmd" = { 166 wantedBy = [ "multi-user.target" ]; 167 serviceConfig = { 168 Type = "dbus"; 169 Restart = "always"; 170 RestartSec = 30; 171 BusName = "com.intel.tss2.Tabrmd"; 172 ExecStart = "${cfg.abrmd.package}/bin/tpm2-abrmd"; 173 User = "tss"; 174 Group = "tss"; 175 }; 176 }; 177 178 services.dbus.packages = lib.singleton cfg.abrmd.package; 179 }) 180 ] 181 ); 182 183 meta.maintainers = with lib.maintainers; [ lschuermann ]; 184}