lol

nixos/aesmd: add option to configure quote provider library

Changes sgx-psw to append `aesm` to `LD_LIBRARY_PATH`:
- Append instead of prepend to allow for overriding in service config
- As we already add a wrapper to add `aesm` to `LD_LIBRARY_PATH` it is
not necessary to also set in `LD_LIBRARY_PATH` of the systemd service.

Co-authored-by: Vincent Haupert <mail@vincent-haupert.de>

authored by

Andreas Stührk
Vincent Haupert
and committed by
Vincent Haupert
da0dc833 7de32b0c

+68 -32
+7 -2
nixos/modules/services/security/aesmd.nix
··· 25 25 default = false; 26 26 description = lib.mdDoc "Whether to build the PSW package in debug mode."; 27 27 }; 28 + quoteProviderLibrary = mkOption { 29 + type = with types; nullOr path; 30 + default = null; 31 + example = literalExpression "pkgs.sgx-azure-dcap-client"; 32 + description = lib.mdDoc "Custom quote provider library to use."; 33 + }; 28 34 settings = mkOption { 29 35 description = lib.mdDoc "AESM configuration"; 30 36 default = { }; ··· 83 89 storeAesmFolder = "${sgx-psw}/aesm"; 84 90 # Hardcoded path AESM_DATA_FOLDER in psw/ae/aesm_service/source/oal/linux/aesm_util.cpp 85 91 aesmDataFolder = "/var/opt/aesmd/data"; 86 - aesmStateDirSystemd = "%S/aesmd"; 87 92 in 88 93 { 89 94 description = "Intel Architectural Enclave Service Manager"; ··· 98 103 environment = { 99 104 NAME = "aesm_service"; 100 105 AESM_PATH = storeAesmFolder; 101 - LD_LIBRARY_PATH = storeAesmFolder; 106 + LD_LIBRARY_PATH = makeLibraryPath [ cfg.quoteProviderLibrary ]; 102 107 }; 103 108 104 109 # Make sure any of the SGX application enclave devices is available
+59 -28
nixos/tests/aesmd.nix
··· 1 1 { pkgs, lib, ... }: { 2 2 name = "aesmd"; 3 3 meta = { 4 - maintainers = with lib.maintainers; [ veehaitch ]; 4 + maintainers = with lib.maintainers; [ trundle veehaitch ]; 5 5 }; 6 6 7 7 nodes.machine = { lib, ... }: { ··· 25 25 26 26 # We don't have a real SGX machine in NixOS tests 27 27 systemd.services.aesmd.unitConfig.AssertPathExists = lib.mkForce [ ]; 28 + 29 + specialisation = { 30 + withQuoteProvider.configuration = { ... }: { 31 + services.aesmd.quoteProviderLibrary = pkgs.sgx-azure-dcap-client; 32 + }; 33 + }; 28 34 }; 29 35 30 - testScript = '' 31 - with subtest("aesmd.service starts"): 32 - machine.wait_for_unit("aesmd.service") 33 - status, main_pid = machine.systemctl("show --property MainPID --value aesmd.service") 34 - assert status == 0, "Could not get MainPID of aesmd.service" 35 - main_pid = main_pid.strip() 36 + testScript = { nodes, ... }: 37 + let 38 + specialisations = "${nodes.machine.system.build.toplevel}/specialisation"; 39 + in 40 + '' 41 + def get_aesmd_pid(): 42 + status, main_pid = machine.systemctl("show --property MainPID --value aesmd.service") 43 + assert status == 0, "Could not get MainPID of aesmd.service" 44 + return main_pid.strip() 45 + 46 + with subtest("aesmd.service starts"): 47 + machine.wait_for_unit("aesmd.service") 48 + 49 + main_pid = get_aesmd_pid() 50 + 51 + with subtest("aesmd.service runtime directory permissions"): 52 + runtime_dir = "/run/aesmd"; 53 + res = machine.succeed(f"stat -c '%a %U %G' {runtime_dir}").strip() 54 + assert "750 aesmd sgx" == res, f"{runtime_dir} does not have the expected permissions: {res}" 55 + 56 + with subtest("aesm.socket available on host"): 57 + socket_path = "/var/run/aesmd/aesm.socket" 58 + machine.wait_until_succeeds(f"test -S {socket_path}") 59 + machine.succeed(f"test 777 -eq $(stat -c '%a' {socket_path})") 60 + for op in [ "-r", "-w", "-x" ]: 61 + machine.succeed(f"sudo -u sgxtest test {op} {socket_path}") 62 + machine.fail(f"sudo -u nosgxtest test {op} {socket_path}") 63 + 64 + with subtest("Copies white_list_cert_to_be_verify.bin"): 65 + whitelist_path = "/var/opt/aesmd/data/white_list_cert_to_be_verify.bin" 66 + whitelist_perms = machine.succeed( 67 + f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {whitelist_path}" 68 + ).strip() 69 + assert "644" == whitelist_perms, f"white_list_cert_to_be_verify.bin has permissions {whitelist_perms}" 70 + 71 + with subtest("Writes and binds aesm.conf in service namespace"): 72 + aesmd_config = machine.succeed(f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/cat /etc/aesmd.conf") 36 73 37 - with subtest("aesmd.service runtime directory permissions"): 38 - runtime_dir = "/run/aesmd"; 39 - res = machine.succeed(f"stat -c '%a %U %G' {runtime_dir}").strip() 40 - assert "750 aesmd sgx" == res, f"{runtime_dir} does not have the expected permissions: {res}" 74 + assert aesmd_config == "whitelist url = http://nixos.org\nproxy type = direct\ndefault quoting type = ecdsa_256\n", "aesmd.conf differs" 41 75 42 - with subtest("aesm.socket available on host"): 43 - socket_path = "/var/run/aesmd/aesm.socket" 44 - machine.wait_until_succeeds(f"test -S {socket_path}") 45 - machine.succeed(f"test 777 -eq $(stat -c '%a' {socket_path})") 46 - for op in [ "-r", "-w", "-x" ]: 47 - machine.succeed(f"sudo -u sgxtest test {op} {socket_path}") 48 - machine.fail(f"sudo -u nosgxtest test {op} {socket_path}") 76 + with subtest("aesmd.service without quote provider library has correct LD_LIBRARY_PATH"): 77 + status, environment = machine.systemctl("show --property Environment --value aesmd.service") 78 + assert status == 0, "Could not get Environment of aesmd.service" 79 + env_by_name = dict(entry.split("=", 1) for entry in environment.split()) 80 + assert not env_by_name["LD_LIBRARY_PATH"], "LD_LIBRARY_PATH is not empty" 49 81 50 - with subtest("Copies white_list_cert_to_be_verify.bin"): 51 - whitelist_path = "/var/opt/aesmd/data/white_list_cert_to_be_verify.bin" 52 - whitelist_perms = machine.succeed( 53 - f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {whitelist_path}" 54 - ).strip() 55 - assert "644" == whitelist_perms, f"white_list_cert_to_be_verify.bin has permissions {whitelist_perms}" 82 + with subtest("aesmd.service with quote provider library starts"): 83 + machine.succeed('${specialisations}/withQuoteProvider/bin/switch-to-configuration test') 84 + machine.wait_for_unit("aesmd.service") 56 85 57 - with subtest("Writes and binds aesm.conf in service namespace"): 58 - aesmd_config = machine.succeed(f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/cat /etc/aesmd.conf") 86 + main_pid = get_aesmd_pid() 59 87 60 - assert aesmd_config == "whitelist url = http://nixos.org\nproxy type = direct\ndefault quoting type = ecdsa_256\n", "aesmd.conf differs" 61 - ''; 88 + with subtest("aesmd.service with quote provider library has correct LD_LIBRARY_PATH"): 89 + ld_library_path = machine.succeed(f"xargs -0 -L1 -a /proc/{main_pid}/environ | grep LD_LIBRARY_PATH") 90 + assert ld_library_path.startswith("LD_LIBRARY_PATH=${pkgs.sgx-azure-dcap-client}/lib:"), \ 91 + "LD_LIBRARY_PATH is not set to the configured quote provider library" 92 + ''; 62 93 }
+1 -1
nixos/tests/all-tests.nix
··· 69 69 _3proxy = runTest ./3proxy.nix; 70 70 acme = runTest ./acme.nix; 71 71 adguardhome = runTest ./adguardhome.nix; 72 - aesmd = runTest ./aesmd.nix; 72 + aesmd = runTestOn ["x86_64-linux"] ./aesmd.nix; 73 73 agate = runTest ./web-servers/agate.nix; 74 74 agda = handleTest ./agda.nix {}; 75 75 airsonic = handleTest ./airsonic.nix {};
+1 -1
pkgs/os-specific/linux/sgx/psw/default.nix
··· 121 121 122 122 mkdir $out/bin 123 123 makeWrapper $out/aesm/aesm_service $out/bin/aesm_service \ 124 - --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ protobuf ]}:$out/aesm \ 124 + --suffix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ protobuf ]}:$out/aesm \ 125 125 --chdir "$out/aesm" 126 126 127 127 # Make sure we didn't forget to handle any files