1{ config, lib, ... }:
2with lib;
3let
4 cfg = config.hardware.cpu.intel.sgx;
5 defaultPrvGroup = "sgx_prv";
6in
7{
8 options.hardware.cpu.intel.sgx.enableDcapCompat = mkOption {
9 description = lib.mdDoc ''
10 Whether to enable backward compatibility for SGX software build for the
11 out-of-tree Intel SGX DCAP driver.
12
13 Creates symbolic links for the SGX devices `/dev/sgx_enclave`
14 and `/dev/sgx_provision` to make them available as
15 `/dev/sgx/enclave` and `/dev/sgx/provision`,
16 respectively.
17 '';
18 type = types.bool;
19 default = true;
20 };
21
22 options.hardware.cpu.intel.sgx.provision = {
23 enable = mkEnableOption (lib.mdDoc "access to the Intel SGX provisioning device");
24 user = mkOption {
25 description = lib.mdDoc "Owner to assign to the SGX provisioning device.";
26 type = types.str;
27 default = "root";
28 };
29 group = mkOption {
30 description = lib.mdDoc "Group to assign to the SGX provisioning device.";
31 type = types.str;
32 default = defaultPrvGroup;
33 };
34 mode = mkOption {
35 description = lib.mdDoc "Mode to set for the SGX provisioning device.";
36 type = types.str;
37 default = "0660";
38 };
39 };
40
41 config = mkMerge [
42 (mkIf cfg.provision.enable {
43 assertions = [
44 {
45 assertion = hasAttr cfg.provision.user config.users.users;
46 message = "Given user does not exist";
47 }
48 {
49 assertion = (cfg.provision.group == defaultPrvGroup) || (hasAttr cfg.provision.group config.users.groups);
50 message = "Given group does not exist";
51 }
52 ];
53
54 users.groups = optionalAttrs (cfg.provision.group == defaultPrvGroup) {
55 "${cfg.provision.group}" = { };
56 };
57
58 services.udev.extraRules = with cfg.provision; ''
59 SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${user}", GROUP="${group}", MODE="${mode}"
60 '';
61 })
62 (mkIf cfg.enableDcapCompat {
63 services.udev.extraRules = ''
64 SUBSYSTEM=="misc", KERNEL=="sgx_enclave", SYMLINK+="sgx/enclave"
65 SUBSYSTEM=="misc", KERNEL=="sgx_provision", SYMLINK+="sgx/provision"
66 '';
67 })
68 ];
69}