1 { config, options, pkgs, lib, ... }:
4 cfg = config.services.aesmd;
5 opt = options.services.aesmd;
7 sgx-psw = pkgs.sgx-psw.override { inherit (cfg) debug; };
9 configFile = with cfg.settings; pkgs.writeText "aesmd.conf" (
10 concatStringsSep "\n" (
11 optional (whitelistUrl != null) "whitelist url = ${whitelistUrl}" ++
12 optional (proxy != null) "aesm proxy = ${proxy}" ++
13 optional (proxyType != null) "proxy type = ${proxyType}" ++
14 optional (defaultQuotingType != null) "default quoting type = ${defaultQuotingType}" ++
15 # Newline at end of file
21 options.services.aesmd = {
22 enable = mkEnableOption (lib.mdDoc "Intel's Architectural Enclave Service Manager (AESM) for Intel SGX");
26 description = lib.mdDoc "Whether to build the PSW package in debug mode.";
29 description = lib.mdDoc "AESM configuration";
31 type = types.submodule {
32 options.whitelistUrl = mkOption {
33 type = with types; nullOr str;
35 example = "http://whitelist.trustedservices.intel.com/SGX/LCWL/Linux/sgx_white_list_cert.bin";
36 description = lib.mdDoc "URL to retrieve authorized Intel SGX enclave signers.";
38 options.proxy = mkOption {
39 type = with types; nullOr str;
41 example = "http://proxy_url:1234";
42 description = lib.mdDoc "HTTP network proxy.";
44 options.proxyType = mkOption {
45 type = with types; nullOr (enum [ "default" "direct" "manual" ]);
46 default = if (cfg.settings.proxy != null) then "manual" else null;
47 defaultText = literalExpression ''
48 if (config.${opt.settings}.proxy != null) then "manual" else null
51 description = lib.mdDoc ''
52 Type of proxy to use. The `default` uses the system's default proxy.
53 If `direct` is given, uses no proxy.
54 A value of `manual` uses the proxy from
55 {option}`services.aesmd.settings.proxy`.
58 options.defaultQuotingType = mkOption {
59 type = with types; nullOr (enum [ "ecdsa_256" "epid_linkable" "epid_unlinkable" ]);
61 example = "ecdsa_256";
62 description = lib.mdDoc "Attestation quote type.";
68 config = mkIf cfg.enable {
70 assertion = !(config.boot.specialFileSystems."/dev".options ? "noexec");
71 message = "SGX requires exec permission for /dev";
74 hardware.cpu.intel.sgx.provision.enable = true;
76 # Make sure the AESM service can find the SGX devices until
77 # https://github.com/intel/linux-sgx/issues/772 is resolved
78 # and updated in nixpkgs.
79 hardware.cpu.intel.sgx.enableDcapCompat = mkForce true;
81 systemd.services.aesmd =
83 storeAesmFolder = "${sgx-psw}/aesm";
84 # Hardcoded path AESM_DATA_FOLDER in psw/ae/aesm_service/source/oal/linux/aesm_util.cpp
85 aesmDataFolder = "/var/opt/aesmd/data";
86 aesmStateDirSystemd = "%S/aesmd";
89 description = "Intel Architectural Enclave Service Manager";
90 wantedBy = [ "multi-user.target" ];
99 NAME = "aesm_service";
100 AESM_PATH = storeAesmFolder;
101 LD_LIBRARY_PATH = storeAesmFolder;
104 # Make sure any of the SGX application enclave devices is available
105 unitConfig.AssertPathExists = [
106 # legacy out-of-tree driver
114 serviceConfig = rec {
115 ExecStartPre = pkgs.writeShellScript "copy-aesmd-data-files.sh" ''
117 whiteListFile="${aesmDataFolder}/white_list_cert_to_be_verify.bin"
118 if [[ ! -f "$whiteListFile" ]]; then
119 ${pkgs.coreutils}/bin/install -m 644 -D \
120 "${storeAesmFolder}/data/white_list_cert_to_be_verify.bin" \
124 ExecStart = "${sgx-psw}/bin/aesm_service --no-daemon";
125 ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"'';
127 Restart = "on-failure";
132 SupplementaryGroups = [
133 config.hardware.cpu.intel.sgx.provision.group
138 WorkingDirectory = storeAesmFolder;
139 StateDirectory = "aesmd";
140 StateDirectoryMode = "0700";
141 RuntimeDirectory = "aesmd";
142 RuntimeDirectoryMode = "0750";
146 # chroot into the runtime directory
147 RootDirectory = "%t/aesmd";
148 BindReadOnlyPaths = [
150 # Hardcoded path AESM_CONFIG_FILE in psw/ae/aesm_service/source/utils/aesm_config.cpp
151 "${configFile}:/etc/aesmd.conf"
154 # Hardcoded path CONFIG_SOCKET_PATH in psw/ae/aesm_service/source/core/ipc/SocketConfig.h
155 "%t/aesmd:/var/run/aesmd"
156 "%S/aesmd:/var/opt/aesmd"
159 # PrivateDevices=true will mount /dev noexec which breaks AESM
160 PrivateDevices = false;
161 DevicePolicy = "closed";
163 # legacy out-of-tree driver
168 "/dev/sgx_enclave rw"
169 "/dev/sgx_provision rw"
172 # Requires Internet access for attestation
173 PrivateNetwork = false;
175 RestrictAddressFamilies = [
176 # Allocates the socket /var/run/aesmd/aesm.socket
178 # Uses the HTTP protocol to initialize some services
184 MemoryDenyWriteExecute = false;
186 # needs the ipc syscall in order to run
207 SystemCallArchitectures = "native";
208 SystemCallErrorNumber = "EPERM";
210 CapabilityBoundingSet = "";
211 KeyringMode = "private";
212 LockPersonality = true;
213 NoNewPrivileges = true;
214 NotifyAccess = "none";
215 PrivateMounts = true;
220 ProtectControlGroups = true;
222 ProtectHostname = true;
223 ProtectKernelLogs = true;
224 ProtectKernelModules = true;
225 ProtectKernelTunables = true;
226 ProtectProc = "invisible";
227 ProtectSystem = "strict";
229 RestrictNamespaces = true;
230 RestrictRealtime = true;
231 RestrictSUIDSGID = true;