summary refs log tree commit diff
diff options
context:
space:
mode:
authorJörg Thalheim <Mic92@users.noreply.github.com>2021-12-13 14:16:26 +0000
committerGitHub <noreply@github.com>2021-12-13 14:16:26 +0000
commitafa3c99cd5ea99dbf3f599506570be5d69b2aba1 (patch)
treedd566bcf19d25241274a313d1b4d0bbffdf1702c
parent0dadd5fabb2a10d39e2641b5b7857ea1131517a6 (diff)
parentd6cc0ad96e0a8723d457d0a8c6c6bfc54df2920b (diff)
downloadnixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar.gz
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar.bz2
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar.lz
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar.xz
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.tar.zst
nixpkgs-afa3c99cd5ea99dbf3f599506570be5d69b2aba1.zip
Merge pull request #148593 from veehaitch/sgx-psw
sgx-psw: init package and module
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2205.section.xml12
-rw-r--r--nixos/doc/manual/release-notes/rl-2205.section.md2
-rw-r--r--nixos/modules/hardware/cpu/intel-sgx.nix47
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/services/security/aesmd.nix227
-rw-r--r--nixos/tests/aesmd.nix62
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--pkgs/os-specific/linux/sgx/psw/default.nix190
-rw-r--r--pkgs/os-specific/linux/sgx/sdk/default.nix (renamed from pkgs/os-specific/linux/sgx-sdk/default.nix)8
-rw-r--r--pkgs/os-specific/linux/sgx/sdk/ipp-crypto.nix (renamed from pkgs/os-specific/linux/sgx-sdk/ipp-crypto.nix)0
-rw-r--r--pkgs/os-specific/linux/sgx/sdk/samples.nix (renamed from pkgs/os-specific/linux/sgx-sdk/samples.nix)0
-rw-r--r--pkgs/top-level/all-packages.nix4
12 files changed, 549 insertions, 6 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index c84a3e3b019..144b277438a 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -19,8 +19,16 @@
   </section>
   <section xml:id="sec-release-22.05-new-services">
     <title>New Services</title>
-    <para>
-    </para>
+    <itemizedlist spacing="compact">
+      <listitem>
+        <para>
+          <link xlink:href="https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw">aesmd</link>,
+          the Intel SGX Architectural Enclave Service Manager. Available
+          as
+          <link linkend="opt-services.aesmd.enable">services.aesmd</link>.
+        </para>
+      </listitem>
+    </itemizedlist>
   </section>
   <section xml:id="sec-release-22.05-incompatibilities">
     <title>Backward Incompatibilities</title>
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index 45ed69cf1b0..4418c8142a1 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -8,6 +8,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 ## New Services {#sec-release-22.05-new-services}
 
+- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
+
 ## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
 
 - `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
diff --git a/nixos/modules/hardware/cpu/intel-sgx.nix b/nixos/modules/hardware/cpu/intel-sgx.nix
new file mode 100644
index 00000000000..04647940058
--- /dev/null
+++ b/nixos/modules/hardware/cpu/intel-sgx.nix
@@ -0,0 +1,47 @@
+{ config, lib, ... }:
+with lib;
+let
+  cfg = config.hardware.cpu.intel.sgx.provision;
+  defaultGroup = "sgx_prv";
+in
+{
+  options.hardware.cpu.intel.sgx.provision = {
+    enable = mkEnableOption "access to the Intel SGX provisioning device";
+    user = mkOption {
+      description = "Owner to assign to the SGX provisioning device.";
+      type = types.str;
+      default = "root";
+    };
+    group = mkOption {
+      description = "Group to assign to the SGX provisioning device.";
+      type = types.str;
+      default = defaultGroup;
+    };
+    mode = mkOption {
+      description = "Mode to set for the SGX provisioning device.";
+      type = types.str;
+      default = "0660";
+    };
+  };
+
+  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";
+      }
+    ];
+
+    users.groups = optionalAttrs (cfg.group == defaultGroup) {
+      "${cfg.group}" = { };
+    };
+
+    services.udev.extraRules = ''
+      SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${cfg.user}", GROUP="${cfg.group}", MODE="${cfg.mode}"
+    '';
+  };
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 3cc9ea88e17..1f826220a0f 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -45,6 +45,7 @@
   ./hardware/ckb-next.nix
   ./hardware/cpu/amd-microcode.nix
   ./hardware/cpu/intel-microcode.nix
+  ./hardware/cpu/intel-sgx.nix
   ./hardware/corectrl.nix
   ./hardware/digitalbitbox.nix
   ./hardware/device-tree.nix
@@ -928,6 +929,7 @@
   ./services/search/kibana.nix
   ./services/search/meilisearch.nix
   ./services/search/solr.nix
+  ./services/security/aesmd.nix
   ./services/security/certmgr.nix
   ./services/security/cfssl.nix
   ./services/security/clamav.nix
diff --git a/nixos/modules/services/security/aesmd.nix b/nixos/modules/services/security/aesmd.nix
new file mode 100644
index 00000000000..bb53bc49e25
--- /dev/null
+++ b/nixos/modules/services/security/aesmd.nix
@@ -0,0 +1,227 @@
+{ config, pkgs, lib, ... }:
+with lib;
+let
+  cfg = config.services.aesmd;
+
+  sgx-psw = pkgs.sgx-psw.override { inherit (cfg) debug; };
+
+  configFile = with cfg.settings; pkgs.writeText "aesmd.conf" (
+    concatStringsSep "\n" (
+      optional (whitelistUrl != null) "whitelist url = ${whitelistUrl}" ++
+      optional (proxy != null) "aesm proxy = ${proxy}" ++
+      optional (proxyType != null) "proxy type = ${proxyType}" ++
+      optional (defaultQuotingType != null) "default quoting type = ${defaultQuotingType}" ++
+      # Newline at end of file
+      [ "" ]
+    )
+  );
+in
+{
+  options.services.aesmd = {
+    enable = mkEnableOption "Intel's Architectural Enclave Service Manager (AESM) for Intel SGX";
+    debug = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Whether to build the PSW package in debug mode.";
+    };
+    settings = mkOption {
+      description = "AESM configuration";
+      default = { };
+      type = types.submodule {
+        options.whitelistUrl = mkOption {
+          type = with types; nullOr str;
+          default = null;
+          example = "http://whitelist.trustedservices.intel.com/SGX/LCWL/Linux/sgx_white_list_cert.bin";
+          description = "URL to retrieve authorized Intel SGX enclave signers.";
+        };
+        options.proxy = mkOption {
+          type = with types; nullOr str;
+          default = null;
+          example = "http://proxy_url:1234";
+          description = "HTTP network proxy.";
+        };
+        options.proxyType = mkOption {
+          type = with types; nullOr (enum [ "default" "direct" "manual" ]);
+          default = if (cfg.settings.proxy != null) then "manual" else null;
+          example = "default";
+          description = ''
+            Type of proxy to use. The <literal>default</literal> uses the system's default proxy.
+            If <literal>direct</literal> is given, uses no proxy.
+            A value of <literal>manual</literal> uses the proxy from
+            <option>services.aesmd.settings.proxy</option>.
+          '';
+        };
+        options.defaultQuotingType = mkOption {
+          type = with types; nullOr (enum [ "ecdsa_256" "epid_linkable" "epid_unlinkable" ]);
+          default = null;
+          example = "ecdsa_256";
+          description = "Attestation quote type.";
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    assertions = [{
+      assertion = !(config.boot.specialFileSystems."/dev".options ? "noexec");
+      message = "SGX requires exec permission for /dev";
+    }];
+
+    hardware.cpu.intel.sgx.provision.enable = true;
+
+    systemd.services.aesmd =
+      let
+        storeAesmFolder = "${sgx-psw}/aesm";
+        # Hardcoded path AESM_DATA_FOLDER in psw/ae/aesm_service/source/oal/linux/aesm_util.cpp
+        aesmDataFolder = "/var/opt/aesmd/data";
+        aesmStateDirSystemd = "%S/aesmd";
+      in
+      {
+        description = "Intel Architectural Enclave Service Manager";
+        wantedBy = [ "multi-user.target" ];
+
+        after = [
+          "auditd.service"
+          "network.target"
+          "syslog.target"
+        ];
+
+        environment = {
+          NAME = "aesm_service";
+          AESM_PATH = storeAesmFolder;
+          LD_LIBRARY_PATH = storeAesmFolder;
+        };
+
+        # Make sure any of the SGX application enclave devices is available
+        unitConfig.AssertPathExists = [
+          # legacy out-of-tree driver
+          "|/dev/isgx"
+          # DCAP driver
+          "|/dev/sgx/enclave"
+          # in-tree driver
+          "|/dev/sgx_enclave"
+        ];
+
+        serviceConfig = rec {
+          ExecStartPre = pkgs.writeShellScript "copy-aesmd-data-files.sh" ''
+            set -euo pipefail
+            whiteListFile="${aesmDataFolder}/white_list_cert_to_be_verify.bin"
+            if [[ ! -f "$whiteListFile" ]]; then
+              ${pkgs.coreutils}/bin/install -m 644 -D \
+                "${storeAesmFolder}/data/white_list_cert_to_be_verify.bin" \
+                "$whiteListFile"
+            fi
+          '';
+          ExecStart = "${sgx-psw}/bin/aesm_service --no-daemon";
+          ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"'';
+
+          Restart = "on-failure";
+          RestartSec = "15s";
+
+          DynamicUser = true;
+          Group = "sgx";
+          SupplementaryGroups = [
+            config.hardware.cpu.intel.sgx.provision.group
+          ];
+
+          Type = "simple";
+
+          WorkingDirectory = storeAesmFolder;
+          StateDirectory = "aesmd";
+          StateDirectoryMode = "0700";
+          RuntimeDirectory = "aesmd";
+          RuntimeDirectoryMode = "0750";
+
+          # Hardening
+
+          # chroot into the runtime directory
+          RootDirectory = "%t/aesmd";
+          BindReadOnlyPaths = [
+            builtins.storeDir
+            # Hardcoded path AESM_CONFIG_FILE in psw/ae/aesm_service/source/utils/aesm_config.cpp
+            "${configFile}:/etc/aesmd.conf"
+          ];
+          BindPaths = [
+            # Hardcoded path CONFIG_SOCKET_PATH in psw/ae/aesm_service/source/core/ipc/SocketConfig.h
+            "%t/aesmd:/var/run/aesmd"
+            "%S/aesmd:/var/opt/aesmd"
+          ];
+
+          # PrivateDevices=true will mount /dev noexec which breaks AESM
+          PrivateDevices = false;
+          DevicePolicy = "closed";
+          DeviceAllow = [
+            # legacy out-of-tree driver
+            "/dev/isgx rw"
+            # DCAP driver
+            "/dev/sgx rw"
+            # in-tree driver
+            "/dev/sgx_enclave rw"
+            "/dev/sgx_provision rw"
+          ];
+
+          # Requires Internet access for attestation
+          PrivateNetwork = false;
+
+          RestrictAddressFamilies = [
+            # Allocates the socket /var/run/aesmd/aesm.socket
+            "AF_UNIX"
+            # Uses the HTTP protocol to initialize some services
+            "AF_INET"
+            "AF_INET6"
+          ];
+
+          # True breaks stuff
+          MemoryDenyWriteExecute = false;
+
+          # needs the ipc syscall in order to run
+          SystemCallFilter = [
+            "@system-service"
+            "~@aio"
+            "~@chown"
+            "~@clock"
+            "~@cpu-emulation"
+            "~@debug"
+            "~@keyring"
+            "~@memlock"
+            "~@module"
+            "~@mount"
+            "~@privileged"
+            "~@raw-io"
+            "~@reboot"
+            "~@resources"
+            "~@setuid"
+            "~@swap"
+            "~@sync"
+            "~@timer"
+          ];
+          SystemCallArchitectures = "native";
+          SystemCallErrorNumber = "EPERM";
+
+          CapabilityBoundingSet = "";
+          KeyringMode = "private";
+          LockPersonality = true;
+          NoNewPrivileges = true;
+          NotifyAccess = "none";
+          PrivateMounts = true;
+          PrivateTmp = true;
+          PrivateUsers = true;
+          ProcSubset = "pid";
+          ProtectClock = true;
+          ProtectControlGroups = true;
+          ProtectHome = true;
+          ProtectHostname = true;
+          ProtectKernelLogs = true;
+          ProtectKernelModules = true;
+          ProtectKernelTunables = true;
+          ProtectProc = "invisible";
+          ProtectSystem = "strict";
+          RemoveIPC = true;
+          RestrictNamespaces = true;
+          RestrictRealtime = true;
+          RestrictSUIDSGID = true;
+          UMask = "0066";
+        };
+      };
+  };
+}
diff --git a/nixos/tests/aesmd.nix b/nixos/tests/aesmd.nix
new file mode 100644
index 00000000000..59c04fe7e96
--- /dev/null
+++ b/nixos/tests/aesmd.nix
@@ -0,0 +1,62 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
+  name = "aesmd";
+  meta = {
+    maintainers = with lib.maintainers; [ veehaitch ];
+  };
+
+  machine = { lib, ... }: {
+    services.aesmd = {
+      enable = true;
+      settings = {
+        defaultQuotingType = "ecdsa_256";
+        proxyType = "direct";
+        whitelistUrl = "http://nixos.org";
+      };
+    };
+
+    # Should have access to the AESM socket
+    users.users."sgxtest" = {
+      isNormalUser = true;
+      extraGroups = [ "sgx" ];
+    };
+
+    # Should NOT have access to the AESM socket
+    users.users."nosgxtest".isNormalUser = true;
+
+    # We don't have a real SGX machine in NixOS tests
+    systemd.services.aesmd.unitConfig.AssertPathExists = lib.mkForce [ ];
+  };
+
+  testScript = ''
+    with subtest("aesmd.service starts"):
+      machine.wait_for_unit("aesmd.service")
+      status, main_pid = machine.systemctl("show --property MainPID --value aesmd.service")
+      assert status == 0, "Could not get MainPID of aesmd.service"
+      main_pid = main_pid.strip()
+
+    with subtest("aesmd.service runtime directory permissions"):
+      runtime_dir = "/run/aesmd";
+      res = machine.succeed(f"stat -c '%a %U %G' {runtime_dir}").strip()
+      assert "750 aesmd sgx" == res, f"{runtime_dir} does not have the expected permissions: {res}"
+
+    with subtest("aesm.socket available on host"):
+      socket_path = "/var/run/aesmd/aesm.socket"
+      machine.wait_until_succeeds(f"test -S {socket_path}")
+      machine.succeed(f"test 777 -eq $(stat -c '%a' {socket_path})")
+      for op in [ "-r", "-w", "-x" ]:
+        machine.succeed(f"sudo -u sgxtest test {op} {socket_path}")
+        machine.fail(f"sudo -u nosgxtest test {op} {socket_path}")
+
+    with subtest("Copies white_list_cert_to_be_verify.bin"):
+      whitelist_path = "/var/opt/aesmd/data/white_list_cert_to_be_verify.bin"
+      whitelist_perms = machine.succeed(
+        f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {whitelist_path}"
+      ).strip()
+      assert "644" == whitelist_perms, f"white_list_cert_to_be_verify.bin has permissions {whitelist_perms}"
+
+    with subtest("Writes and binds aesm.conf in service namespace"):
+      aesmd_config = machine.succeed(f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/cat /etc/aesmd.conf")
+
+      assert aesmd_config == "whitelist url = http://nixos.org\nproxy type = direct\ndefault quoting type = ecdsa_256\n", "aesmd.conf differs"
+  '';
+})
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 06305460c6a..f86cc2544da 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -23,6 +23,7 @@ in
 {
   _3proxy = handleTest ./3proxy.nix {};
   acme = handleTest ./acme.nix {};
+  aesmd = handleTest ./aesmd.nix {};
   agda = handleTest ./agda.nix {};
   airsonic = handleTest ./airsonic.nix {};
   amazon-init-shell = handleTest ./amazon-init-shell.nix {};
diff --git a/pkgs/os-specific/linux/sgx/psw/default.nix b/pkgs/os-specific/linux/sgx/psw/default.nix
new file mode 100644
index 00000000000..e449c99b077
--- /dev/null
+++ b/pkgs/os-specific/linux/sgx/psw/default.nix
@@ -0,0 +1,190 @@
+{ stdenv
+, lib
+, fetchurl
+, cmake
+, coreutils
+, curl
+, file
+, glibc
+, makeWrapper
+, nixosTests
+, protobuf
+, python3
+, sgx-sdk
+, shadow
+, systemd
+, util-linux
+, which
+, debug ? false
+}:
+stdenv.mkDerivation rec {
+  inherit (sgx-sdk) version versionTag src;
+  pname = "sgx-psw";
+
+  postUnpack =
+    let
+      ae.prebuilt = fetchurl {
+        url = "https://download.01.org/intel-sgx/sgx-linux/${versionTag}/prebuilt_ae_${versionTag}.tar.gz";
+        hash = "sha256-nGKZEpT2Mx0DLgqjv9qbZqBt1pQaSHcnA0K6nHma3sk";
+      };
+      dcap = rec {
+        version = "1.11";
+        filename = "prebuilt_dcap_${version}.tar.gz";
+        prebuilt = fetchurl {
+          url = "https://download.01.org/intel-sgx/sgx-dcap/${version}/linux/${filename}";
+          hash = "sha256-ShGScS4yNLki04RNPxxLvqzGmy4U1L0gVETvfAo8w9M=";
+        };
+      };
+    in
+    sgx-sdk.postUnpack + ''
+      # Make sure we use the correct version of prebuilt DCAP
+      grep -q 'ae_file_name=${dcap.filename}' "$src/external/dcap_source/QuoteGeneration/download_prebuilt.sh" \
+        || (echo "Could not find expected prebuilt DCAP ${dcap.filename} in linux-sgx source" >&2 && exit 1)
+
+      tar -zxf ${ae.prebuilt}   -C $sourceRoot/
+      tar -zxf ${dcap.prebuilt} -C $sourceRoot/external/dcap_source/QuoteGeneration/
+    '';
+
+  nativeBuildInputs = [
+    cmake
+    file
+    makeWrapper
+    python3
+    sgx-sdk
+    which
+  ];
+
+  buildInputs = [
+    curl
+    protobuf
+  ];
+
+  hardeningDisable = lib.optionals debug [
+    "fortify"
+  ];
+
+  postPatch = ''
+    # https://github.com/intel/linux-sgx/pull/730
+    substituteInPlace buildenv.mk --replace '/bin/cp' 'cp'
+    substituteInPlace psw/ae/aesm_service/source/CMakeLists.txt \
+      --replace '/usr/bin/getconf' 'getconf'
+
+    # https://github.com/intel/SGXDataCenterAttestationPrimitives/pull/205
+    substituteInPlace ./external/dcap_source/QuoteGeneration/buildenv.mk \
+      --replace '/bin/cp' 'cp'
+    substituteInPlace external/dcap_source/tools/SGXPlatformRegistration/Makefile \
+      --replace '/bin/cp' 'cp'
+    substituteInPlace external/dcap_source/tools/SGXPlatformRegistration/buildenv.mk \
+      --replace '/bin/cp' 'cp'
+
+    patchShebangs \
+      linux/installer/bin/build-installpkg.sh \
+      linux/installer/common/psw/createTarball.sh \
+      linux/installer/common/psw/install.sh
+  '';
+
+  dontUseCmakeConfigure = true;
+
+  # Randomly fails if enabled
+  enableParallelBuilding = false;
+
+  buildFlags = [
+    "psw_install_pkg"
+  ] ++ lib.optionals debug [
+    "DEBUG=1"
+  ];
+
+  installFlags = [
+    "-C linux/installer/common/psw/output"
+    "DESTDIR=$(TMPDIR)/install"
+  ];
+
+  postInstall = ''
+    installDir=$TMPDIR/install
+    sgxPswDir=$installDir/opt/intel/sgxpsw
+
+    mv $installDir/usr/lib64/ $out/lib/
+    ln -sr $out/lib $out/lib64
+
+    # Install udev rules to lib/udev/rules.d
+    mv $sgxPswDir/udev/ $out/lib/
+
+    # Install example AESM config
+    mkdir $out/etc/
+    mv $sgxPswDir/aesm/conf/aesmd.conf $out/etc/
+    rmdir $sgxPswDir/aesm/conf/
+
+    # Delete init service
+    rm $sgxPswDir/aesm/aesmd.conf
+
+    # Move systemd services
+    mkdir -p $out/lib/systemd/system/
+    mv $sgxPswDir/aesm/aesmd.service $out/lib/systemd/system/
+    mv $sgxPswDir/remount-dev-exec.service $out/lib/systemd/system/
+
+    # Move misc files
+    mkdir $out/share/
+    mv $sgxPswDir/licenses $out/share/
+
+    # Remove unnecessary files
+    rm $sgxPswDir/{cleanup.sh,startup.sh}
+    rm -r $sgxPswDir/scripts
+
+    mv $sgxPswDir/aesm/ $out/
+
+    mkdir $out/bin
+    makeWrapper $out/aesm/aesm_service $out/bin/aesm_service \
+      --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ protobuf ]}:$out/aesm \
+      --run "cd $out/aesm"
+
+    # Make sure we didn't forget to handle any files
+    rmdir $sgxPswDir || (echo "Error: The directory $installDir still contains unhandled files: $(ls -A $installDir)" >&2 && exit 1)
+  '';
+
+  # Most—if not all—of those fixups are not relevant for NixOS as we have our own
+  # NixOS module which is based on those files without relying on them. Still, it
+  # is helpful to have properly patched versions for non-NixOS distributions.
+  postFixup = ''
+    header "Fixing aesmd.service"
+    substituteInPlace $out/lib/systemd/system/aesmd.service \
+      --replace '@aesm_folder@' \
+                "$out/aesm" \
+      --replace 'Type=forking' \
+                'Type=simple' \
+      --replace "ExecStart=$out/aesm/aesm_service" \
+                "ExecStart=$out/bin/aesm_service --no-daemon"\
+      --replace "/bin/mkdir" \
+                "${coreutils}/bin/mkdir" \
+      --replace "/bin/chown" \
+                "${coreutils}/bin/chown" \
+      --replace "/bin/chmod" \
+                "${coreutils}/bin/chmod" \
+      --replace "/bin/kill" \
+                "${coreutils}/bin/kill"
+
+    header "Fixing remount-dev-exec.service"
+    substituteInPlace $out/lib/systemd/system/remount-dev-exec.service \
+      --replace '/bin/mount' \
+                "${util-linux}/bin/mount"
+
+    header "Fixing linksgx.sh"
+    # https://github.com/intel/linux-sgx/pull/736
+    substituteInPlace $out/aesm/linksgx.sh \
+      --replace '/usr/bin/getent' \
+                '${glibc.bin}/bin/getent' \
+      --replace '/usr/sbin/usermod' \
+                '${shadow}/bin/usermod'
+  '';
+
+  passthru.tests = {
+    service = nixosTests.aesmd;
+  };
+
+  meta = with lib; {
+    description = "Intel SGX Architectural Enclave Service Manager";
+    homepage = "https://github.com/intel/linux-sgx";
+    maintainers = with maintainers; [ veehaitch citadelcore ];
+    platforms = [ "x86_64-linux" ];
+    license = with licenses; [ bsd3 ];
+  };
+}
diff --git a/pkgs/os-specific/linux/sgx-sdk/default.nix b/pkgs/os-specific/linux/sgx/sdk/default.nix
index cb9d140e4ed..e08511272af 100644
--- a/pkgs/os-specific/linux/sgx-sdk/default.nix
+++ b/pkgs/os-specific/linux/sgx/sdk/default.nix
@@ -21,13 +21,13 @@
 , validatePkgConfig
 , writeShellScript
 , writeText
+, debug ? false
 }:
-with lib;
 stdenv.mkDerivation rec {
   pname = "sgx-sdk";
   version = "2.14.100.2";
 
-  versionTag = concatStringsSep "." (take 2 (splitVersion version));
+  versionTag = lib.concatStringsSep "." (lib.take 2 (lib.splitVersion version));
 
   src = fetchFromGitHub {
     owner = "intel";
@@ -140,6 +140,8 @@ stdenv.mkDerivation rec {
 
   buildFlags = [
     "sdk_install_pkg"
+  ] ++ lib.optionals debug [
+    "DEBUG=1"
   ];
 
   enableParallelBuilding = true;
@@ -264,7 +266,7 @@ stdenv.mkDerivation rec {
 
   passthru.tests = callPackage ./samples.nix { };
 
-  meta = {
+  meta = with lib; {
     description = "Intel SGX SDK for Linux built with IPP Crypto Library";
     homepage = "https://github.com/intel/linux-sgx";
     maintainers = with maintainers; [ sbellem arturcygan veehaitch ];
diff --git a/pkgs/os-specific/linux/sgx-sdk/ipp-crypto.nix b/pkgs/os-specific/linux/sgx/sdk/ipp-crypto.nix
index ac5fd2ad1cc..ac5fd2ad1cc 100644
--- a/pkgs/os-specific/linux/sgx-sdk/ipp-crypto.nix
+++ b/pkgs/os-specific/linux/sgx/sdk/ipp-crypto.nix
diff --git a/pkgs/os-specific/linux/sgx-sdk/samples.nix b/pkgs/os-specific/linux/sgx/sdk/samples.nix
index 82dbc24568e..82dbc24568e 100644
--- a/pkgs/os-specific/linux/sgx-sdk/samples.nix
+++ b/pkgs/os-specific/linux/sgx/sdk/samples.nix
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 4a1798545b7..e23e45590f8 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -22737,7 +22737,9 @@ with pkgs;
 
   seturgent = callPackage ../os-specific/linux/seturgent { };
 
-  sgx-sdk = callPackage ../os-specific/linux/sgx-sdk { };
+  sgx-sdk = callPackage ../os-specific/linux/sgx/sdk { };
+
+  sgx-psw = callPackage ../os-specific/linux/sgx/psw { };
 
   shadow = callPackage ../os-specific/linux/shadow { };