diff --git a/flake.lock b/flake.lock index 1a21262..a46eb64 100644 --- a/flake.lock +++ b/flake.lock @@ -1,34 +1,5 @@ { "nodes": { - "crane": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ], - "rust-overlay": [ - "rust-overlay" - ] - }, - "locked": { - "lastModified": 1683505101, - "narHash": "sha256-VBU64Jfu2V4sUR5+tuQS9erBRAe/QEYUxdVMcJGMZZs=", - "owner": "ipetkov", - "repo": "crane", - "rev": "7b5bd9e5acb2bb0cfba2d65f34d8568a894cdb6c", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { @@ -106,11 +77,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1684077912, - "narHash": "sha256-HNuVjMGmSp3H1MM4ymne3r07ldIB54GgPQViUZjk5Wc=", + "lastModified": 1685071405, + "narHash": "sha256-qENk2wk0Zli0zeLDKMNcs8CfhPIHhtRQgPamlFUM/xw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "57ace723895c43160e102cc126933d8b395391ea", + "rev": "794a24afefde85c3e9b533443c4c73cd871f9e3a", "type": "github" }, "original": { @@ -151,11 +122,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1682596858, - "narHash": "sha256-Hf9XVpqaGqe/4oDGr30W8HlsWvJXtMsEPHDqHZA6dDg=", + "lastModified": 1684842236, + "narHash": "sha256-rYWsIXHvNhVQ15RQlBUv67W3YnM+Pd+DuXGMvCBq2IE=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "fb58866e20af98779017134319b5663b8215d912", + "rev": "61e567d6497bc9556f391faebe5e410e6623217f", "type": "github" }, "original": { @@ -166,36 +137,11 @@ }, "root": { "inputs": { - "crane": "crane", "flake-compat": "flake-compat", "flake-parts": "flake-parts", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", - "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1684030847, - "narHash": "sha256-z4tOxaN9Cl8C80u6wyZBpPt9A9MbL21fZ3zdB/vG+AU=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "aa1480f16bec7dda3c62b8cdb184c7e823331ba2", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" + "pre-commit-hooks-nix": "pre-commit-hooks-nix" } }, "systems": { diff --git a/flake.nix b/flake.nix index 3df5cc3..888a398 100644 --- a/flake.nix +++ b/flake.nix @@ -18,27 +18,13 @@ # avoid having multiple versions in our dependencies. flake-utils.url = "github:numtide/flake-utils"; - crane = { - url = "github:ipetkov/crane"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.rust-overlay.follows = "rust-overlay"; - inputs.flake-utils.follows = "flake-utils"; - inputs.flake-compat.follows = "flake-compat"; - }; - - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.flake-utils.follows = "flake-utils"; - }; - flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; }; - outputs = inputs@{ self, nixpkgs, crane, rust-overlay, flake-parts, ... }: + outputs = inputs@{ self, nixpkgs, flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } ({ moduleWithSystem, ... }: { imports = [ # Derive the output overlay automatically from all packages that we define. @@ -48,27 +34,20 @@ inputs.pre-commit-hooks-nix.flakeModule ]; - flake.nixosModules.lanzaboote = moduleWithSystem ( - perSystem@{ config }: + flake.nixosModules.lanzaboote = moduleWithSystem (perSystem@{ config }: { ... }: { - imports = [ - ./nix/modules/lanzaboote.nix - ]; + imports = [ ./nix/modules/lanzaboote.nix ]; boot.lanzaboote.package = perSystem.config.packages.tool; - } - ); + }); - flake.nixosModules.uki = moduleWithSystem ( - perSystem@{ config }: + flake.nixosModules.uki = moduleWithSystem (perSystem@{ config }: { lib, ... }: { - imports = [ - ./nix/modules/uki.nix - ]; + imports = [ ./nix/modules/uki.nix ]; - boot.loader.uki.stub = lib.mkDefault "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; - } - ); + boot.loader.uki.stub = lib.mkDefault + "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; + }); systems = [ "x86_64-linux" @@ -79,94 +58,23 @@ perSystem = { config, system, pkgs, ... }: let - pkgs = import nixpkgs { - system = system; - overlays = [ - rust-overlay.overlays.default - ]; + pkgs = import nixpkgs { inherit system; }; + uefiPkgs = import nixpkgs { + inherit system; + crossSystem = { + config = "${pkgs.hostPlatform.linuxArch}-windows"; + rustc.config = "${pkgs.hostPlatform.linuxArch}-unknown-uefi"; + libc = null; + useLLVM = true; + }; }; inherit (pkgs) lib; - uefi-rust-stable = pkgs.rust-bin.fromRustupToolchainFile ./rust/stub/rust-toolchain.toml; - craneLib = crane.lib.x86_64-linux.overrideToolchain uefi-rust-stable; - - # Build attributes for a Rust application. - buildRustApp = lib.makeOverridable ( - { src - , target ? null - , doCheck ? true - , extraArgs ? { } - }: - let - commonArgs = { - inherit src; - CARGO_BUILD_TARGET = target; - inherit doCheck; - - # Workaround for https://github.com/ipetkov/crane/issues/262. - dummyrs = pkgs.writeText "dummy.rs" '' - #![allow(unused)] - - #![cfg_attr( - any(target_os = "none", target_os = "uefi"), - no_std, - no_main, - )] - - #[cfg_attr(any(target_os = "none", target_os = "uefi"), panic_handler)] - fn panic(_info: &::core::panic::PanicInfo<'_>) -> ! { - loop {} - } - - #[cfg_attr(any(target_os = "none", target_os = "uefi"), export_name = "efi_main")] - fn main() {} - ''; - } // extraArgs; - - cargoArtifacts = craneLib.buildDepsOnly commonArgs; - in - { - package = craneLib.buildPackage (commonArgs // { - inherit cargoArtifacts; - }); - - clippy = craneLib.cargoClippy (commonArgs // { - inherit cargoArtifacts; - cargoClippyExtraArgs = "-- --deny warnings"; - }); - - rustfmt = craneLib.cargoFmt (commonArgs // { inherit cargoArtifacts; }); - } - ); - - stubCrane = buildRustApp { - src = craneLib.cleanCargoSource ./rust/stub; - target = "x86_64-unknown-uefi"; - doCheck = false; - }; - - fatStubCrane = stubCrane.override { - extraArgs = { - cargoExtraArgs = "--no-default-features --features fat"; - }; - }; - - stub = stubCrane.package; - fatStub = fatStubCrane.package; - - toolCrane = buildRustApp { - src = ./rust/tool; - extraArgs = { - TEST_SYSTEMD = pkgs.systemd; - nativeCheckInputs = with pkgs; [ - binutils-unwrapped - sbsigntool - ]; - }; - }; - - tool = toolCrane.package; + stub = uefiPkgs.callPackage ./nix/packages/stub.nix { }; + fatStub = + uefiPkgs.callPackage ./nix/packages/stub.nix { fatVariant = true; }; + tool = pkgs.callPackage ./nix/packages/tool.nix { }; wrappedTool = pkgs.runCommand "lzbt" { @@ -177,7 +85,9 @@ # Clean PATH to only contain what we need to do objcopy. Also # tell lanzatool where to find our UEFI binaries. makeWrapper ${tool}/bin/lzbt $out/bin/lzbt \ - --set PATH ${lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ]} \ + --set PATH ${ + lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ] + } \ --set LANZABOOTE_STUB ${stub}/bin/lanzaboote_stub.efi ''; in @@ -188,31 +98,28 @@ lzbt = wrappedTool; }; - overlayAttrs = { - inherit (config.packages) tool; - }; + overlayAttrs = { inherit (config.packages) tool; }; - checks = - let - nixosLib = import (pkgs.path + "/nixos/lib") { }; - runTest = module: nixosLib.runTest { + checks = let + nixosLib = import (pkgs.path + "/nixos/lib") { }; + runTest = module: + nixosLib.runTest { imports = [ module ]; hostPkgs = pkgs; }; - in - { - toolClippy = toolCrane.clippy; - stubClippy = stubCrane.clippy; - fatStubClippy = fatStubCrane.clippy; - toolFmt = toolCrane.rustfmt; - stubFmt = stubCrane.rustfmt; - } // (import ./nix/tests/lanzaboote.nix { - inherit pkgs; - lanzabooteModule = self.nixosModules.lanzaboote; - }) // (import ./nix/tests/stub.nix { - inherit pkgs runTest; - ukiModule = self.nixosModules.uki; - }); + in { + toolFmt = (tool.override { enableFmt = true; }); + stubFmt = (stub.override { enableFmt = true; }); + toolClippy = (tool.override { enableLint = true; }); + stubClippy = (stub.override { enableLint = true; }); + fatStubClippy = (fatStub.override { enableLint = true; }); + } // (import ./nix/tests/lanzaboote.nix { + inherit pkgs; + lanzabooteModule = self.nixosModules.lanzaboote; + }) // (import ./nix/tests/stub.nix { + inherit pkgs runTest; + ukiModule = self.nixosModules.uki; + }); pre-commit = { check.enable = true; @@ -236,32 +143,21 @@ export PATH=$PATH:${systemdUkify}/lib/systemd ''; - packages = - let - uefi-run = pkgs.callPackage ./nix/packages/uefi-run.nix { - inherit craneLib; - }; - in - [ - uefi-run - pkgs.openssl - (pkgs.sbctl.override { - databasePath = "pki"; - }) - pkgs.sbsigntool - pkgs.efitools - pkgs.python39Packages.ovmfvartool - pkgs.qemu - pkgs.nixpkgs-fmt - pkgs.statix - pkgs.cargo-release - ]; - - inputsFrom = [ - config.packages.stub - config.packages.tool + packages = [ + pkgs.uefi-run + pkgs.openssl + (pkgs.sbctl.override { databasePath = "pki"; }) + pkgs.sbsigntool + pkgs.efitools + pkgs.python39Packages.ovmfvartool + pkgs.qemu + pkgs.nixpkgs-fmt + pkgs.statix + pkgs.cargo-release ]; + inputsFrom = [ config.packages.stub config.packages.tool ]; + TEST_SYSTEMD = pkgs.systemd; }; }; diff --git a/nix/packages/stub.nix b/nix/packages/stub.nix new file mode 100644 index 0000000..9daab7b --- /dev/null +++ b/nix/packages/stub.nix @@ -0,0 +1,66 @@ +{ rust, rustPlatform, clippy, rustfmt, stdenv, lib, runCommand, enableFmt ? false, enableLint ? false, fatVariant ? false }: + +let + targetSpec = rust.toRustTargetSpec stdenv.hostPlatform; + targetIsJSON = lib.hasSuffix ".json" targetSpec; + shortTarget = + if targetIsJSON then + (lib.removeSuffix ".json" (builtins.baseNameOf "${targetSpec}")) + else targetSpec; +in +rustPlatform.buildRustPackage + ({ + pname = "lanzaboote_stub"; + version = "0.3.0"; + src = runCommand "src" { } '' + install -D ${../../rust/stub/Cargo.toml} $out/Cargo.toml + install -D ${../../rust/stub/Cargo.lock} $out/Cargo.lock + cp -r ${../../rust/stub/src} $out/src + ''; + + # We don't want the thin code. + buildNoDefaultFeatures = true; + buildFeatures = if fatVariant then [ "fat" ] else [ "thin" ]; + + # We don't want the thin code. + buildNoDefaultFeatures = fatVariant; + buildFeatures = lib.optional fatVariant "fat"; + + cargoLock = { + lockFile = ../../rust/stub/Cargo.lock; + }; + + # Necessary because our `cc-wrapper` doesn't understand MSVC link options. + RUSTFLAGS = "-Clinker=${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}ld.lld -Clinker-flavor=lld-link"; + # Necessary because otherwise we will get (useless) hardening options in front of + # -flavor link which will break the whole command-line processing for the ld.lld linker. + hardeningDisable = [ "all" ]; + + meta = with lib; { + description = "Lanzaboote UEFI stub for SecureBoot enablement on NixOS systems"; + homepage = "https://github.com/nix-community/lanzaboote"; + license = licenses.mit; + platforms = [ "x86_64-windows" "aarch64-windows" "i686-windows" ]; + }; + } // lib.optionalAttrs enableLint { + buildPhase = '' + cargo clippy --target ${shortTarget} --all-features -- -D warnings + if grep -R 'dbg!' ./src; then + echo "use of dbg macro found in code!" + false + fi + ''; + + installPhase = '' + touch $out + ''; + } // lib.optionalAttrs enableFmt { + buildPhase = '' + echo "checking formatting..." + cargo fmt --all -- --check + ''; + + installPhase = '' + touch $out + ''; + }) diff --git a/nix/packages/tool.nix b/nix/packages/tool.nix new file mode 100644 index 0000000..5d3bb9c --- /dev/null +++ b/nix/packages/tool.nix @@ -0,0 +1,67 @@ +{ stdenv +, systemd +, binutils-unwrapped +, sbsigntool +, rustPlatform +, lib +, runCommand +, fetchurl +, clippy +, rustfmt +, path +, enableLint ? false +, enableFmt ? false +}: +rustPlatform.buildRustPackage + ({ + pname = "lanzaboote_tool"; + version = "0.3.0"; + src = runCommand "src" { } '' + install -D ${../../rust/tool/Cargo.toml} $out/Cargo.toml + install -D ${../../rust/tool/Cargo.lock} $out/Cargo.lock + cp -r ${../../rust/tool/src} $out/src + ''; + + TEST_SYSTEMD = systemd; + + nativeBuildInputs = lib.optional enableLint clippy ++ lib.optional enableFmt rustfmt; + + cargoLock = { + lockFile = ../../rust/tool/Cargo.lock; + }; + + nativeCheckInputs = [ + binutils-unwrapped + sbsigntool + ]; + + meta = with lib; { + description = "Lanzaboote UEFI tooling for SecureBoot enablement on NixOS systems"; + homepage = "https://github.com/nix-community/lanzaboote"; + license = licenses.mit; + }; + } // lib.optionalAttrs enableLint { + doCheck = false; + buildPhase = '' + cargo clippy --all-targets --all-features -- -D warnings + if grep -R 'dbg!' ./src; then + echo "use of dbg macro found in code!" + false + fi + ''; + + installPhase = '' + touch $out + ''; + } // lib.optionalAttrs enableFmt { + doCheck = false; + + buildPhase = '' + echo "checking formatting..." + cargo fmt --all -- --check + ''; + + installPhase = '' + touch $out + ''; + }) diff --git a/nix/packages/uefi-run.nix b/nix/packages/uefi-run.nix deleted file mode 100644 index 4f13d6b..0000000 --- a/nix/packages/uefi-run.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ fetchFromGitHub, craneLib, makeWrapper, OVMF, qemu }: -craneLib.buildPackage { - src = fetchFromGitHub { - owner = "Richard-W"; - repo = "uefi-run"; - - rev = "8ba33c934525458a784a6620705bcf46c3ca91d2"; - sha256 = "fwzWdOinW/ECVI/65pPB1shxPdl2nZThAqlg8wlWg/g="; - }; - - nativeBuildInputs = [ makeWrapper ]; - - postInstall = '' - # The hook runs for the dependency-only derivation where the binary is not - # produced. We need to skip it there. - if [ -f $out/bin/uefi-run ]; then - wrapProgram "$out/bin/uefi-run" \ - --add-flags '--bios-path ${OVMF.fd}/FV/OVMF.fd --qemu-path ${qemu}/bin/qemu-system-x86_64' - fi - ''; -}