summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Haupert <mail@vincent-haupert.de>2022-01-11 12:10:09 +0100
committerVincent Haupert <mail@vincent-haupert.de>2022-01-11 14:02:16 +0100
commitb88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861 (patch)
treeb7dc93159cc2a5e23687db97cf33b77141313af9
parent7180c7bb6e8259d3fbb5581ec8651c19e5921bdb (diff)
downloadnixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar.gz
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar.bz2
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar.lz
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar.xz
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.tar.zst
nixpkgs-b88ddadf8bd289f8ea561f3b3f2ca7e1b6fe2861.zip
nixos/intel-sgx: add option for Intel SGX DCAP compatibility
The Intel SGX DCAP driver makes the SGX application enclave device and
the SGX provisioning enclave available below the path `/dev/sgx/`. Since
Linux 5.11, a derivation of the DCAP driver is part of the kernel and
available through the X86_SGX config option; NixOS enables this option
by default.

In contrast to the out-of-tree DCAP driver, the in-tree SGX driver uses
a flat hierarchy for the SGX devices resulting in the paths
`/dev/sgx_enclave` for the application enclave device and
`/dev/sgx_provison` for the provisioning enclave device.

As of this commit, even the latest version of the Intel SGX PSW
libraries still tries to open the (legacy) DCAP paths only. This means
that SGX software currently cannot find the required SGX devices even if
the system actually supports SGX through the in-tree driver. Intel wants
to change this behavior in an upcoming release of intel/linux-sgx.

Having said that, SGX software assuming the SGX devices below
`/dev/sgx/` will prevail. Therefore, this commit introduces the NixOS
configuration option `hardware.cpu.intel.sgx.enableDcapCompat` which
creates the necessary symlinks to support existing SGX software. The
option defaults to true as it is currently the only way to support SGX
software. Also, enabling the SGX AESM service enables the option.

The permissions of the devices `/dev/sgx_enclave` and
`/dev/sgx_provison` remain the same, i.e., are not affected regardless
of having the new option enabled or not.
-rw-r--r--nixos/modules/hardware/cpu/intel-sgx.nix64
-rw-r--r--nixos/modules/services/security/aesmd.nix5
2 files changed, 48 insertions, 21 deletions
diff --git a/nixos/modules/hardware/cpu/intel-sgx.nix b/nixos/modules/hardware/cpu/intel-sgx.nix
index 04647940058..1355ee753f0 100644
--- a/nixos/modules/hardware/cpu/intel-sgx.nix
+++ b/nixos/modules/hardware/cpu/intel-sgx.nix
@@ -1,10 +1,24 @@
 { config, lib, ... }:
 with lib;
 let
-  cfg = config.hardware.cpu.intel.sgx.provision;
-  defaultGroup = "sgx_prv";
+  cfg = config.hardware.cpu.intel.sgx;
+  defaultPrvGroup = "sgx_prv";
 in
 {
+  options.hardware.cpu.intel.sgx.enableDcapCompat = mkOption {
+    description = ''
+      Whether to enable backward compatibility for SGX software build for the
+      out-of-tree Intel SGX DCAP driver.
+
+      Creates symbolic links for the SGX devices <literal>/dev/sgx_enclave</literal>
+      and <literal>/dev/sgx_provision</literal> to make them available as
+      <literal>/dev/sgx/enclave</literal>  and <literal>/dev/sgx/provision</literal>,
+      respectively.
+    '';
+    type = types.bool;
+    default = true;
+  };
+
   options.hardware.cpu.intel.sgx.provision = {
     enable = mkEnableOption "access to the Intel SGX provisioning device";
     user = mkOption {
@@ -15,7 +29,7 @@ in
     group = mkOption {
       description = "Group to assign to the SGX provisioning device.";
       type = types.str;
-      default = defaultGroup;
+      default = defaultPrvGroup;
     };
     mode = mkOption {
       description = "Mode to set for the SGX provisioning device.";
@@ -24,24 +38,32 @@ in
     };
   };
 
-  config = mkIf cfg.enable {
-    assertions = [
-      {
-        assertion = hasAttr cfg.user config.users.users;
-        message = "Given user does not exist";
-      }
-      {
-        assertion = (cfg.group == defaultGroup) || (hasAttr cfg.group config.users.groups);
-        message = "Given group does not exist";
-      }
-    ];
+  config = mkMerge [
+    (mkIf cfg.provision.enable {
+      assertions = [
+        {
+          assertion = hasAttr cfg.provision.user config.users.users;
+          message = "Given user does not exist";
+        }
+        {
+          assertion = (cfg.provision.group == defaultPrvGroup) || (hasAttr cfg.provision.group config.users.groups);
+          message = "Given group does not exist";
+        }
+      ];
 
-    users.groups = optionalAttrs (cfg.group == defaultGroup) {
-      "${cfg.group}" = { };
-    };
+      users.groups = optionalAttrs (cfg.provision.group == defaultPrvGroup) {
+        "${cfg.provision.group}" = { };
+      };
 
-    services.udev.extraRules = ''
-      SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${cfg.user}", GROUP="${cfg.group}", MODE="${cfg.mode}"
-    '';
-  };
+      services.udev.extraRules = with cfg.provision; ''
+        SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${user}", GROUP="${group}", MODE="${mode}"
+      '';
+    })
+    (mkIf cfg.enableDcapCompat {
+      services.udev.extraRules = ''
+        SUBSYSTEM=="misc", KERNEL=="sgx_enclave",   SYMLINK+="sgx/enclave"
+        SUBSYSTEM=="misc", KERNEL=="sgx_provision", SYMLINK+="sgx/provision"
+      '';
+    })
+  ];
 }
diff --git a/nixos/modules/services/security/aesmd.nix b/nixos/modules/services/security/aesmd.nix
index 924d614e471..8268b034a15 100644
--- a/nixos/modules/services/security/aesmd.nix
+++ b/nixos/modules/services/security/aesmd.nix
@@ -73,6 +73,11 @@ in
 
     hardware.cpu.intel.sgx.provision.enable = true;
 
+    # Make sure the AESM service can find the SGX devices until
+    # https://github.com/intel/linux-sgx/issues/772 is resolved
+    # and updated in nixpkgs.
+    hardware.cpu.intel.sgx.enableDcapCompat = mkForce true;
+
     systemd.services.aesmd =
       let
         storeAesmFolder = "${sgx-psw}/aesm";