Unverified Commit 6af71350 authored by Connor Baker's avatar Connor Baker Committed by GitHub
Browse files

nixos/tee-supplicant: add tee-supplicant module (and more) (#237613)

parents 3dd7bc34 b8937303
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -222,6 +222,8 @@ Alongside many enhancements to NixOS modules and general system improvements, th

- [Limine](https://github.com/limine-bootloader/limine) a modern, advanced, portable, multiprotocol bootloader and boot manager. Available as [boot.loader.limine](#opt-boot.loader.limine.enable).

- [tee-supplicant](https://github.com/OP-TEE/optee_client), a userspace supplicant for OP-TEE OS. Available as [services.tee-supplicant](#opt-services.tee-supplicant.enable).

- [Orthanc](https://orthanc.uclouvain.be/) a lightweight, RESTful DICOM server for healthcare and medical research. Available as [services.orthanc](#opt-services.orthanc.enable).

- [Docling Serve](https://github.com/docling-project/docling-serve) running [Docling](https://github.com/docling-project/docling) as an API service. Available as [services.docling-serve](#opt-services.docling-serve.enable).
+1 −0
Original line number Diff line number Diff line
@@ -930,6 +930,7 @@
  ./services/misc/taskchampion-sync-server.nix
  ./services/misc/taskserver
  ./services/misc/tautulli.nix
  ./services/misc/tee-supplicant
  ./services/misc/tiddlywiki.nix
  ./services/misc/tp-auto-kbbl.nix
  ./services/misc/transfer-sh.nix
+95 −0
Original line number Diff line number Diff line
{
  config,
  pkgs,
  lib,
  ...
}:
let
  inherit (lib)
    getExe'
    mkEnableOption
    mkIf
    mkOption
    mkPackageOption
    types
    ;

  cfg = config.services.tee-supplicant;

  taDir = "optee_armtz";

  trustedApplications = pkgs.linkFarm "runtime-trusted-applications" (
    map (
      ta:
      let
        # This is safe since we are using it as the path value, so the context
        # will still ensure that this nix store path exists on the running
        # system.
        taFile = builtins.baseNameOf (builtins.unsafeDiscardStringContext ta);
      in
      {
        name = "lib/${taDir}/${taFile}";
        path = ta;
      }
    ) cfg.trustedApplications
  );
in
{
  options.services.tee-supplicant = {
    enable = mkEnableOption "OP-TEE userspace supplicant";

    package = mkPackageOption pkgs "optee-client" { };

    trustedApplications = mkOption {
      type = types.listOf types.path;
      default = [ ];
      description = ''
        A list of full paths to trusted applications that will be loaded at
        runtime by tee-supplicant.
      '';
    };

    pluginPath = mkOption {
      type = types.path;
      default = "/run/current-system/sw/lib/tee-supplicant/plugins";
      description = ''
        The directory where plugins will be loaded from on startup.
      '';
    };

    reeFsParentPath = mkOption {
      type = types.path;
      default = "/var/lib/tee";
      description = ''
        The directory where the secure filesystem will be stored in the rich
        execution environment (REE FS).
      '';
    };
  };

  config = mkIf cfg.enable {
    environment = mkIf (cfg.trustedApplications != [ ]) {
      systemPackages = [ trustedApplications ];
      pathsToLink = [ "/lib/${taDir}" ];
    };

    systemd.services.tee-supplicant = {
      description = "Userspace supplicant for OPTEE-OS";

      serviceConfig = {
        ExecStart = toString [
          (getExe' cfg.package "tee-supplicant")
          "--ta-dir ${taDir}"
          "--fs-parent-path ${cfg.reeFsParentPath}"
          "--plugin-path ${cfg.pluginPath}"
        ];
        Restart = "always";
      };

      after = [ "modprobe@optee.service" ];
      wants = [ "modprobe@optee.service" ];

      wantedBy = [ "multi-user.target" ];
    };
  };
}
+1 −0
Original line number Diff line number Diff line
@@ -1080,6 +1080,7 @@ in
  openvscode-server = runTest ./openvscode-server.nix;
  open-webui = runTest ./open-webui.nix;
  openvswitch = runTest ./openvswitch.nix;
  optee = handleTestOn [ "aarch64-linux" ] ./optee.nix { };
  orangefs = runTest ./orangefs.nix;
  os-prober = handleTestOn [ "x86_64-linux" ] ./os-prober.nix { };
  osquery = handleTestOn [ "x86_64-linux" ] ./osquery.nix { };

nixos/tests/optee.nix

0 → 100644
+72 −0
Original line number Diff line number Diff line
import ./make-test-python.nix (
  { pkgs, lib, ... }:
  {
    name = "optee";

    meta = with pkgs.lib.maintainers; {
      maintainers = [ jmbaur ];
    };

    nodes.machine =
      { config, pkgs, ... }:
      let
        inherit (pkgs) armTrustedFirmwareQemu opteeQemuAarch64 ubootQemuAarch64;

        # Default environment for qemu-arm64 uboot does not work well with
        # large nixos kernel/initrds.
        uboot = ubootQemuAarch64.overrideAttrs (old: {
          postPatch =
            (old.postPatch or "")
            + ''
              substituteInPlace board/emulation/qemu-arm/qemu-arm.env \
                --replace-fail "ramdisk_addr_r=0x44000000" "ramdisk_addr_r=0x46000000"
            '';
        });

        bios = armTrustedFirmwareQemu.override {
          extraMakeFlags = [
            "SPD=opteed"
            "BL32=${opteeQemuAarch64}/tee-header_v2.bin"
            "BL32_EXTRA1=${opteeQemuAarch64}/tee-pager_v2.bin"
            "BL32_EXTRA2=${opteeQemuAarch64}/tee-pageable_v2.bin"
            "BL33=${uboot}/u-boot.bin"
            "all"
            "fip"
          ];
          filesToInstall = [
            "build/qemu/release/bl1.bin"
            "build/qemu/release/fip.bin"
          ];
          postInstall = ''
            dd if=$out/bl1.bin of=$out/bios.bin bs=4096 conv=notrunc
            dd if=$out/fip.bin of=$out/bios.bin seek=64 bs=4096 conv=notrunc
          '';
        };
      in
      {
        virtualisation = {
          inherit bios;
          cores = 2;
          qemu.options = [
            "-machine virt,secure=on,accel=tcg,gic-version=2"
            "-cpu cortex-a57"
          ];
        };

        # VM boots up via qfw
        boot.loader.grub.enable = false;

        services.tee-supplicant = {
          enable = true;
          # pkcs11 trusted application
          trustedApplications = [ "${opteeQemuAarch64.devkit}/ta/fd02c9da-306c-48c7-a49c-bbd827ae86ee.ta" ];
        };
      };
    testScript = ''
      machine.wait_for_unit("tee-supplicant.service")
      out = machine.succeed("${pkgs.opensc}/bin/pkcs11-tool --module ${lib.getLib pkgs.optee-client}/lib/libckteec.so --list-token-slots")
      if out.find("OP-TEE PKCS11 TA") < 0:
          raise Exception("optee pkcs11 token not found")
    '';
  }
)
Loading