From d1a9bd5a8605429e14644d854e0cc94a28bf92f8 Mon Sep 17 00:00:00 2001 From: Jared Baur Date: Tue, 25 Jun 2024 16:44:35 -0700 Subject: [PATCH] Deprecate nixos options related to packaging We have a few nixos options that are mirrors of arguments to `stdenv.mkDerivation` (e.g. `patches`, `postPatch`). Let's encourage users to use the overlay system in order customize packaging. --- UPGRADE_CHECKLIST.md | 7 +- device-pkgs/flash-script.nix | 12 +- modules/flash-script.nix | 44 +--- overlay-with-config.nix | 28 +- overlay.nix | 33 ++- pkgs/optee/arm-trusted-firmware.nix | 39 +++ pkgs/optee/client.nix | 28 ++ pkgs/optee/default.nix | 235 ----------------- pkgs/optee/hw-key-agent.nix | 48 ++++ pkgs/optee/nv-luks-srv.nix | 48 ++++ pkgs/optee/os.nix | 60 +++++ pkgs/optee/tos-image.nix | 31 +++ pkgs/uefi-firmware/default.nix | 324 ++---------------------- pkgs/uefi-firmware/edk2-nvidia-src.nix | 59 +++++ pkgs/uefi-firmware/jetson-edk2-uefi.nix | 217 ++++++++++++++++ 15 files changed, 601 insertions(+), 612 deletions(-) create mode 100644 pkgs/optee/arm-trusted-firmware.nix create mode 100644 pkgs/optee/client.nix delete mode 100644 pkgs/optee/default.nix create mode 100644 pkgs/optee/hw-key-agent.nix create mode 100644 pkgs/optee/nv-luks-srv.nix create mode 100644 pkgs/optee/os.nix create mode 100644 pkgs/optee/tos-image.nix create mode 100644 pkgs/uefi-firmware/edk2-nvidia-src.nix create mode 100644 pkgs/uefi-firmware/jetson-edk2-uefi.nix diff --git a/UPGRADE_CHECKLIST.md b/UPGRADE_CHECKLIST.md index a4b13a7..6c563bd 100644 --- a/UPGRADE_CHECKLIST.md +++ b/UPGRADE_CHECKLIST.md @@ -1,10 +1,11 @@ ### Updating - [ ] Update `l4tVersion`, `jetpackVersion`, and `cudaVersion` in overlay.nix -- [ ] Update branch/revision/sha256s in: +- [ ] Update branch/revision/hashes in: - [ ] `overlay.nix` - [ ] `kernel/default.nix` - - [ ] `uefi-firmware.nix` - - [ ] Grep for "sha256 = ", see if there is anything else not covered + - [ ] `pkgs/uefi-firmware/edk2-nvidia.nix` + - [ ] `pkgs/uefi-firmware/jetson-edk2-uefi.nix` + - [ ] `grep -r -e "hash = " -e "sha256 = "` to see if there is anything else not covered - [ ] Update the kernel version in `kernel/default.nix` if it chaged. - [ ] Grep for the previous version strings e.g. "35.4.1" - [ ] Compare files from `unpackedDebs` before and after diff --git a/device-pkgs/flash-script.nix b/device-pkgs/flash-script.nix index 4a29fb4..4c969c8 100644 --- a/device-pkgs/flash-script.nix +++ b/device-pkgs/flash-script.nix @@ -10,7 +10,7 @@ flash-tools: # be used by the bootloader(s) and passed to the kernel. dtbsDir ? null , # Optional package containing uefi_jetson.efi to replace prebuilt version - uefi-firmware ? null + uefiFirmware ? null , # Optional package containing tos.img to replace prebuilt version tosImage ? null , # Optional EKS file containing encrypted keyblob @@ -44,18 +44,18 @@ flash-tools: ${lib.optionalString (partitionTemplate != null) "cp ${partitionTemplate} flash.xml"} ${lib.optionalString (dtbsDir != null) "cp -r ${dtbsDir}/. kernel/dtb/"} - ${lib.optionalString (uefi-firmware != null) '' - cp ${uefi-firmware}/uefi_jetson.bin bootloader/uefi_jetson.bin + ${lib.optionalString (uefiFirmware != null) '' + cp ${uefiFirmware}/uefi_jetson.bin bootloader/uefi_jetson.bin # For normal NixOS usage, we'd probably use systemd-boot or GRUB instead, # but lets replace the upstream L4TLauncher EFI payload anyway - cp ${uefi-firmware}/L4TLauncher.efi bootloader/BOOTAA64.efi + cp ${uefiFirmware}/L4TLauncher.efi bootloader/BOOTAA64.efi # Replace additional dtbos - cp ${uefi-firmware}/dtbs/*.dtbo kernel/dtb/ + cp ${uefiFirmware}/dtbs/*.dtbo kernel/dtb/ ''} ${lib.optionalString (tosImage != null) '' - cp ${tosImage}/tos.img bootloader/tos-optee_${socType}.img + cp ${tosImage} bootloader/tos-optee_${socType}.img ''} ${lib.optionalString (eksFile != null) '' cp ${eksFile} bootloader/eks_${socType}.img diff --git a/modules/flash-script.nix b/modules/flash-script.nix index b23fbf5..c8e4bcc 100644 --- a/modules/flash-script.nix +++ b/modules/flash-script.nix @@ -22,6 +22,12 @@ in (mkRenamedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "optee" "supplicantExtraArgs" ] [ "hardware" "nvidia-jetpack" "firmware" "optee" "supplicant" "extraArgs" ]) (mkRenamedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "optee" "trustedApplications" ] [ "hardware" "nvidia-jetpack" "firmware" "optee" "supplicant" "trustedApplications" ]) (mkRenamedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "optee" "supplicantPlugins" ] [ "hardware" "nvidia-jetpack" "firmware" "optee" "supplicant" "plugins" ]) + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "uefi" "edk2NvidiaPatches" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.edk2NvidiaSrc` instead.") + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "uefi" "edk2UefiPatches" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.jetsonEdk2Uefi` instead.") + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "flashScriptOverrides" "patches" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.flash-tools` instead.") + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "flashScriptOverrides" "postPatch" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.flash-tools` instead.") + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "optee" "patches" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.opteeOS` instead.") + (mkRemovedOptionModule [ "hardware" "nvidia-jetpack" "firmware" "optee" "extraMakeFlags" ] "Use `nixpkgs.overlays` to modify `pkgs.nvidia-jetpack.opteeOS` instead.") ]; options = { @@ -57,22 +63,6 @@ in default = cfg.firmware.uefi.debugMode; }; - edk2NvidiaPatches = mkOption { - type = types.listOf types.path; - description = lib.mdDoc '' - Patches that will be applied to the edk2-nvidia repo - ''; - default = [ ]; - }; - - edk2UefiPatches = mkOption { - type = types.listOf types.path; - description = lib.mdDoc '' - Patches that will be applied to the nvidia edk2 repo which is nvidia's fork of the upstream edk2 repo - ''; - default = [ ]; - }; - secureBoot = { enrollDefaultKeys = lib.mkEnableOption "enroll default UEFI keys"; defaultPkEslFile = mkOption { @@ -175,16 +165,6 @@ in }; }; - patches = mkOption { - type = types.listOf types.path; - default = [ ]; - }; - - extraMakeFlags = mkOption { - type = types.listOf types.str; - default = [ ]; - }; - taPublicKeyFile = mkOption { type = types.nullOr types.path; default = null; @@ -298,18 +278,6 @@ in description = ".xml file describing partition template to use when flashing"; }; - patches = mkOption { - type = types.listOf types.path; - default = [ ]; - description = "Patches to apply to the flash-tools"; - }; - - postPatch = mkOption { - type = types.lines; - default = ""; - description = "Additional commands to run when building flash-tools"; - }; - additionalDtbOverlays = mkOption { type = types.listOf types.path; default = [ ]; diff --git a/overlay-with-config.nix b/overlay-with-config.nix index aa18865..7c09d6d 100644 --- a/overlay-with-config.nix +++ b/overlay-with-config.nix @@ -5,13 +5,6 @@ final: prev: ( cfg = config.hardware.nvidia-jetpack; inherit (prev) lib; - - tosArgs = { - inherit (final.nvidia-jetpack) socType; - inherit (cfg.firmware.optee) taPublicKeyFile; - opteePatches = cfg.firmware.optee.patches; - extraMakeFlags = cfg.firmware.optee.extraMakeFlags; - }; in { nvidia-jetpack = prev.nvidia-jetpack.overrideScope (finalJetpack: prevJetpack: { @@ -27,24 +20,19 @@ final: prev: ( else if lib.hasPrefix "xavier-" cfg.som then "0x19" else throw "Unknown SoC type"; - uefi-firmware = prevJetpack.uefi-firmware.override ({ + edk2NvidiaSrc = prevJetpack.edk2NvidiaSrc.override { + errorLevelInfo = cfg.firmware.uefi.errorLevelInfo; bootLogo = cfg.firmware.uefi.logo; + }; + + jetsonEdk2Uefi = prevJetpack.jetsonEdk2Uefi.override ({ debugMode = cfg.firmware.uefi.debugMode; - errorLevelInfo = cfg.firmware.uefi.errorLevelInfo; - edk2NvidiaPatches = cfg.firmware.uefi.edk2NvidiaPatches; - edk2UefiPatches = cfg.firmware.uefi.edk2UefiPatches; } // lib.optionalAttrs cfg.firmware.uefi.capsuleAuthentication.enable { inherit (cfg.firmware.uefi.capsuleAuthentication) trustedPublicCertPemFile; }); - flash-tools = prevJetpack.flash-tools.overrideAttrs ({ patches ? [ ], postPatch ? "", ... }: { - patches = patches ++ cfg.flashScriptOverrides.patches; - postPatch = postPatch + cfg.flashScriptOverrides.postPatch; - }); - - tosImage = finalJetpack.buildTOS tosArgs; - taDevKit = finalJetpack.buildOpteeTaDevKit tosArgs; - inherit (finalJetpack.tosImage) nvLuksSrv hwKeyAgent; + armTrustedFirmware = finalJetpack.callPackage ./pkgs/optee/arm-trusted-firmware.nix { }; + tosImage = finalJetpack.callPackage ./pkgs/optee/tos-image.nix { }; flashInitrd = let @@ -101,7 +89,7 @@ final: prev: ( inherit lib; inherit (cfg.firmware) eksFile; inherit (cfg.flashScriptOverrides) additionalDtbOverlays flashArgs partitionTemplate; - inherit (finalJetpack) tosImage socType uefi-firmware; + inherit (finalJetpack) tosImage socType uefiFirmware; dtbsDir = config.hardware.deviceTree.package; } // args); diff --git a/overlay.nix b/overlay.nix index b17bf04..f36c4b2 100644 --- a/overlay.nix +++ b/overlay.nix @@ -59,15 +59,30 @@ in self.gitRepos ); - inherit (prev.callPackages ./pkgs/uefi-firmware { inherit (self) l4tVersion; }) - edk2-jetson uefi-firmware; - - inherit (prev.callPackages ./pkgs/optee { - # Nvidia's recommended toolchain is gcc9: - # https://nv-tegra.nvidia.com/r/gitweb?p=tegra/optee-src/nv-optee.git;a=blob;f=optee/atf_and_optee_README.txt;h=591edda3d4ec96997e054ebd21fc8326983d3464;hb=5ac2ab218ba9116f1df4a0bb5092b1f6d810e8f7#l33 - stdenv = prev.gcc9Stdenv; - inherit (self) bspSrc gitRepos l4tVersion; - }) buildTOS buildOpteeTaDevKit opteeClient; + edk2NvidiaSrc = self.callPackage ./pkgs/uefi-firmware/edk2-nvidia-src.nix { }; + jetsonEdk2Uefi = self.callPackage ./pkgs/uefi-firmware/jetson-edk2-uefi.nix { }; + uefiFirmware = self.callPackage ./pkgs/uefi-firmware/default.nix { }; + + # Nvidia's recommended toolchain for optee is gcc9: + # https://nv-tegra.nvidia.com/r/gitweb?p=tegra/optee-src/nv-optee.git;a=blob;f=optee/atf_and_optee_README.txt;h=591edda3d4ec96997e054ebd21fc8326983d3464;hb=5ac2ab218ba9116f1df4a0bb5092b1f6d810e8f7#l33 + opteeStdenv = prev.gcc9Stdenv; + + opteeClient = self.callPackage ./pkgs/optee/client.nix { }; + + opteeTaDevKit = (self.callPackage ./pkgs/optee/os.nix { }).overrideAttrs (old: { + pname = "optee-ta-dev-kit"; + makeFlags = (old.makeFlags or [ ]) ++ [ "ta_dev_kit" ]; + }); + + nvLuksSrv = self.callPackage ./pkgs/optee/nv-luks-srv.nix { }; + hwKeyAgent = self.callPackage ./pkgs/optee/hw-key-agent.nix { }; + + opteeOS = self.callPackage ./pkgs/optee/os.nix { + earlyTaPaths = [ + "${self.nvLuksSrv}/${self.nvLuksSrv.uuid}.stripped.elf" + "${self.hwKeyAgent}/${self.hwKeyAgent.uuid}.stripped.elf" + ]; + }; flash-tools = self.callPackage ./pkgs/flash-tools { }; diff --git a/pkgs/optee/arm-trusted-firmware.nix b/pkgs/optee/arm-trusted-firmware.nix new file mode 100644 index 0000000..eb88153 --- /dev/null +++ b/pkgs/optee/arm-trusted-firmware.nix @@ -0,0 +1,39 @@ +{ gitRepos +, l4tVersion +, opteeStdenv +, socType +}: + +opteeStdenv.mkDerivation { + pname = "arm-trusted-firmware"; + version = l4tVersion; + src = gitRepos."tegra/optee-src/atf"; + makeFlags = [ + "-C arm-trusted-firmware" + "BUILD_BASE=$(PWD)/build" + "CROSS_COMPILE=${opteeStdenv.cc.targetPrefix}" + "DEBUG=0" + "LOG_LEVEL=20" + "PLAT=tegra" + "SPD=opteed" + "TARGET_SOC=${socType}" + "V=0" + # binutils 2.39 regression + # `warning: /build/source/build/rk3399/release/bl31/bl31.elf has a LOAD segment with RWX permissions` + # See also: https://developer.trustedfirmware.org/T996 + "LDFLAGS=-no-warn-rwx-segments" + ]; + + enableParallelBuilding = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out + cp ./build/tegra/${socType}/release/bl31.bin $out/bl31.bin + + runHook postInstall + ''; + + meta.platforms = [ "aarch64-linux" ]; +} diff --git a/pkgs/optee/client.nix b/pkgs/optee/client.nix new file mode 100644 index 0000000..29364e0 --- /dev/null +++ b/pkgs/optee/client.nix @@ -0,0 +1,28 @@ +{ opteeStdenv, fetchpatch, gitRepos, l4tVersion, pkg-config, libuuid }: + +opteeStdenv.mkDerivation { + pname = "optee_client"; + version = l4tVersion; + src = gitRepos."tegra/optee-src/nv-optee"; + patches = [ + ./0001-Don-t-prepend-foo-bar-baz-to-TEEC_LOAD_PATH.patch + (fetchpatch { + name = "tee-supplicant-Allow-for-TA-load-path-to-be-specified-at-runtime.patch"; + url = "https://github.com/OP-TEE/optee_client/commit/f3845d8bee3645eedfcc494be4db034c3c69e9ab.patch"; + stripLen = 1; + extraPrefix = "optee/optee_client/"; + hash = "sha256-XjFpMbyXy74sqnc8l+EgTaPXqwwHcvni1Z68ShokTGc="; + }) + ]; + nativeBuildInputs = [ pkg-config ]; + buildInputs = [ libuuid ]; + enableParallelBuilding = true; + makeFlags = [ + "-C optee/optee_client" + "DESTDIR=$(out)" + "SBINDIR=/sbin" + "LIBDIR=/lib" + "INCLUDEDIR=/include" + ]; + meta.platforms = [ "aarch64-linux" ]; +} diff --git a/pkgs/optee/default.nix b/pkgs/optee/default.nix deleted file mode 100644 index 02f2a34..0000000 --- a/pkgs/optee/default.nix +++ /dev/null @@ -1,235 +0,0 @@ -{ l4tVersion -, bspSrc -, buildPackages -, lib -, stdenv -, fetchgit -, pkg-config -, libuuid -, dtc -, nukeReferences -, fetchpatch -, gitRepos -}: - -let - atfSrc = gitRepos."tegra/optee-src/atf"; - nvopteeSrc = gitRepos."tegra/optee-src/nv-optee"; - - opteeClient = stdenv.mkDerivation { - pname = "optee_client"; - version = l4tVersion; - src = nvopteeSrc; - patches = [ - ./0001-Don-t-prepend-foo-bar-baz-to-TEEC_LOAD_PATH.patch - (fetchpatch { - name = "tee-supplicant-Allow-for-TA-load-path-to-be-specified-at-runtime.patch"; - url = "https://github.com/OP-TEE/optee_client/commit/f3845d8bee3645eedfcc494be4db034c3c69e9ab.patch"; - stripLen = 1; - extraPrefix = "optee/optee_client/"; - hash = "sha256-XjFpMbyXy74sqnc8l+EgTaPXqwwHcvni1Z68ShokTGc="; - }) - ]; - nativeBuildInputs = [ pkg-config ]; - buildInputs = [ libuuid ]; - enableParallelBuilding = true; - makeFlags = [ - "-C optee/optee_client" - "DESTDIR=$(out)" - "SBINDIR=/sbin" - "LIBDIR=/lib" - "INCLUDEDIR=/include" - ]; - meta.platforms = [ "aarch64-linux" ]; - }; - - buildOptee = lib.makeOverridable ({ pname ? "optee-os" - , socType - , earlyTaPaths ? [ ] - , extraMakeFlags ? [ ] - , opteePatches ? [ ] - , taPublicKeyFile ? null - , ... - }: - let - nvCccPrebuilt = { - t194 = ""; - t234 = "${nvopteeSrc}/optee/optee_os/prebuilt/t234/libcommon_crypto.a"; - }.${socType}; - - makeFlags = [ - "-C optee/optee_os" - "CROSS_COMPILE64=${stdenv.cc.targetPrefix}" - "PLATFORM=tegra" - "PLATFORM_FLAVOR=${socType}" - "CFG_WITH_STMM_SP=y" - "CFG_STMM_PATH=${bspSrc}/bootloader/standalonemm_optee_${socType}.bin" - "NV_CCC_PREBUILT=${nvCccPrebuilt}" - "O=$(out)" - ] - ++ (lib.optional (taPublicKeyFile != null) "TA_PUBLIC_KEY=${taPublicKeyFile}") - ++ extraMakeFlags; - in - stdenv.mkDerivation { - inherit pname; - version = l4tVersion; - src = nvopteeSrc; - patches = opteePatches; - postPatch = '' - patchShebangs $(find optee/optee_os -type d -name scripts -printf '%p ') - ''; - nativeBuildInputs = [ - dtc - (buildPackages.python3.withPackages (p: with p; [ pyelftools cryptography ])) - ]; - inherit makeFlags; - enableParallelBuilding = true; - # NOTE: EARLY_TA_PATHS needs to be added outside of `makeFlags` since it is a - # space separated list of paths. See - # https://nixos.org/manual/nixpkgs/stable/#build-phase for more details. - preBuild = lib.optionalString (earlyTaPaths != [ ]) '' - makeFlagsArray+=(EARLY_TA_PATHS="${toString earlyTaPaths}") - ''; - dontInstall = true; - meta.platforms = [ "aarch64-linux" ]; - }); - - buildOpteeTaDevKit = args: buildOptee (args // { - pname = "optee-ta-dev-kit"; - extraMakeFlags = (args.extraMakeFlags or [ ]) ++ [ "ta_dev_kit" ]; - }); - - buildNvLuksSrv = args: stdenv.mkDerivation { - pname = "nvluks-srv"; - version = l4tVersion; - src = nvopteeSrc; - patches = [ ./0001-nvoptee-no-install-makefile.patch ./0002-Exit-with-non-zero-status-code-on-TEEC_InvokeCommand.patch ]; - nativeBuildInputs = [ (buildPackages.python3.withPackages (p: [ p.cryptography ])) ]; - enableParallelBuilding = true; - makeFlags = [ - "-C optee/samples/luks-srv" - "CROSS_COMPILE=${stdenv.cc.targetPrefix}" - "TA_DEV_KIT_DIR=${buildOpteeTaDevKit args}/export-ta_arm64" - "OPTEE_CLIENT_EXPORT=${opteeClient}" - "O=$(PWD)/out" - ]; - installPhase = '' - runHook preInstall - - install -Dm755 -t $out/bin out/ca/luks-srv/nvluks-srv-app - install -Dm755 -t $out out/early_ta/luks-srv/*.stripped.elf - - runHook postInstall - ''; - meta.platforms = [ "aarch64-linux" ]; - }; - - buildHwKeyAgent = args: stdenv.mkDerivation { - pname = "hwkey-agent"; - version = l4tVersion; - src = nvopteeSrc; - patches = [ ./0001-nvoptee-no-install-makefile.patch ]; - nativeBuildInputs = [ (buildPackages.python3.withPackages (p: [ p.cryptography ])) ]; - enableParallelBuilding = true; - makeFlags = [ - "-C optee/samples/hwkey-agent" - "CROSS_COMPILE=${stdenv.cc.targetPrefix}" - "TA_DEV_KIT_DIR=${buildOpteeTaDevKit args}/export-ta_arm64" - "OPTEE_CLIENT_EXPORT=${opteeClient}" - "O=$(PWD)/out" - ]; - installPhase = '' - runHook preInstall - - install -Dm755 -t $out/bin out/ca/hwkey-agent/nvhwkey-app - install -Dm755 -t $out out/ta/hwkey-agent/*.stripped.elf - - runHook postInstall - ''; - }; - - buildOpteeDTB = lib.makeOverridable ({ socType, ... }: - let - flavor = lib.replaceStrings [ "t" ] [ "" ] socType; - in - buildPackages.runCommand "tegra-${flavor}-optee.dtb" - { - nativeBuildInputs = [ dtc ]; - } '' - mkdir -p $out - dtc -I dts -O dtb -o $out/tegra${flavor}-optee.dtb ${nvopteeSrc}/optee/tegra${flavor}-optee.dts - ''); - - buildArmTrustedFirmware = lib.makeOverridable ({ socType, ... }: - stdenv.mkDerivation { - pname = "arm-trusted-firmware"; - version = l4tVersion; - src = atfSrc; - makeFlags = [ - "-C arm-trusted-firmware" - "BUILD_BASE=$(PWD)/build" - "CROSS_COMPILE=${stdenv.cc.targetPrefix}" - "DEBUG=0" - "LOG_LEVEL=20" - "PLAT=tegra" - "SPD=opteed" - "TARGET_SOC=${socType}" - "V=0" - # binutils 2.39 regression - # `warning: /build/source/build/rk3399/release/bl31/bl31.elf has a LOAD segment with RWX permissions` - # See also: https://developer.trustedfirmware.org/T996 - "LDFLAGS=-no-warn-rwx-segments" - ]; - - enableParallelBuilding = true; - - installPhase = '' - runHook preInstall - - mkdir -p $out - cp ./build/tegra/${socType}/release/bl31.bin $out/bl31.bin - - runHook postInstall - ''; - - meta.platforms = [ "aarch64-linux" ]; - }); - - buildTOS = { socType, ... }@args: - let - armTrustedFirmware = buildArmTrustedFirmware args; - - opteeDTB = buildOpteeDTB args; - - nvLuksSrv = buildNvLuksSrv args; - hwKeyAgent = buildHwKeyAgent args; - - opteeOS = buildOptee ({ - earlyTaPaths = [ - "${nvLuksSrv}/b83d14a8-7128-49df-9624-35f14f65ca6c.stripped.elf" - "${hwKeyAgent}/82154947-c1bc-4bdf-b89d-04f93c0ea97c.stripped.elf" - ]; - } // args); - - image = buildPackages.runCommand "tos.img" - { - nativeBuildInputs = [ nukeReferences ]; - passthru = { inherit nvLuksSrv hwKeyAgent; }; - } '' - mkdir -p $out - ${buildPackages.python3}/bin/python3 ${bspSrc}/nv_tegra/tos-scripts/gen_tos_part_img.py \ - --monitor ${armTrustedFirmware}/bl31.bin \ - --os ${opteeOS}/core/tee-raw.bin \ - --dtb ${opteeDTB}/*.dtb \ - --tostype optee \ - $out/tos.img - - # Get rid of any string references to source(s) - nuke-refs $out/* - ''; - in - image; -in -{ - inherit buildTOS buildOpteeTaDevKit opteeClient; -} diff --git a/pkgs/optee/hw-key-agent.nix b/pkgs/optee/hw-key-agent.nix new file mode 100644 index 0000000..ae310a4 --- /dev/null +++ b/pkgs/optee/hw-key-agent.nix @@ -0,0 +1,48 @@ +{ gitRepos +, opteeStdenv +, l4tVersion +, opteeTaDevKit +, opteeClient +, buildPackages +}: + +let + nvopteeSrc = gitRepos."tegra/optee-src/nv-optee"; +in +opteeStdenv.mkDerivation (finalAttrs: { + pname = "hwkey-agent"; + version = l4tVersion; + + src = nvopteeSrc; + + patches = [ ./0001-nvoptee-no-install-makefile.patch ]; + + nativeBuildInputs = [ (buildPackages.python3.withPackages (p: [ p.cryptography ])) ]; + + enableParallelBuilding = true; + + makeFlags = [ + "-C optee/samples/hwkey-agent" + "CROSS_COMPILE=${opteeStdenv.cc.targetPrefix}" + "TA_DEV_KIT_DIR=${opteeTaDevKit}/export-ta_arm64" + "OPTEE_CLIENT_EXPORT=${opteeClient}" + "O=$(PWD)/out" + ]; + + installPhase = '' + runHook preInstall + + install -Dm755 -t $out/bin out/ca/hwkey-agent/nvhwkey-app + install -Dm755 -t $out out/ta/hwkey-agent/${finalAttrs.passthru.uuid}.stripped.elf + + runHook postInstall + ''; + + + passthru.uuid = "82154947-c1bc-4bdf-b89d-04f93c0ea97c"; + + meta = { + platforms = [ "aarch64-linux" ]; + mainProgram = "nvhwkey-app"; + }; +}) diff --git a/pkgs/optee/nv-luks-srv.nix b/pkgs/optee/nv-luks-srv.nix new file mode 100644 index 0000000..2b4ded9 --- /dev/null +++ b/pkgs/optee/nv-luks-srv.nix @@ -0,0 +1,48 @@ +{ gitRepos +, opteeStdenv +, l4tVersion +, opteeTaDevKit +, opteeClient +, buildPackages +}: + +let + nvopteeSrc = gitRepos."tegra/optee-src/nv-optee"; +in +opteeStdenv.mkDerivation (finalAttrs: { + pname = "nvluks-srv"; + version = l4tVersion; + + src = nvopteeSrc; + + patches = [ ./0001-nvoptee-no-install-makefile.patch ./0002-Exit-with-non-zero-status-code-on-TEEC_InvokeCommand.patch ]; + + nativeBuildInputs = [ (buildPackages.python3.withPackages (p: [ p.cryptography ])) ]; + + enableParallelBuilding = true; + + makeFlags = [ + "-C optee/samples/luks-srv" + "CROSS_COMPILE=${opteeStdenv.cc.targetPrefix}" + "TA_DEV_KIT_DIR=${opteeTaDevKit}/export-ta_arm64" + "OPTEE_CLIENT_EXPORT=${opteeClient}" + "O=$(PWD)/out" + ]; + + installPhase = '' + runHook preInstall + + install -Dm755 -t $out/bin out/ca/luks-srv/nvluks-srv-app + install -Dm755 -t $out out/early_ta/luks-srv/${finalAttrs.passthru.uuid}.stripped.elf + + runHook postInstall + ''; + + + passthru.uuid = "b83d14a8-7128-49df-9624-35f14f65ca6c"; + + meta = { + platforms = [ "aarch64-linux" ]; + mainProgram = "nvluks-srv-app"; + }; +}) diff --git a/pkgs/optee/os.nix b/pkgs/optee/os.nix new file mode 100644 index 0000000..1ab9d4d --- /dev/null +++ b/pkgs/optee/os.nix @@ -0,0 +1,60 @@ +{ lib +, gitRepos +, l4tVersion +, dtc +, buildPackages +, stdenv +, bspSrc +, socType +, earlyTaPaths ? [ ] +, taPublicKeyFile ? null +}: + +let + nvopteeSrc = gitRepos."tegra/optee-src/nv-optee"; + + nvCccPrebuilt = { + t194 = ""; + t234 = "${nvopteeSrc}/optee/optee_os/prebuilt/t234/libcommon_crypto.a"; + }.${socType}; +in +stdenv.mkDerivation { + pname = "optee-os"; + version = l4tVersion; + + src = nvopteeSrc; + + postPatch = '' + patchShebangs $(find optee/optee_os -type d -name scripts -printf '%p ') + ''; + + nativeBuildInputs = [ + dtc + (buildPackages.python3.withPackages (p: with p; [ pyelftools cryptography ])) + ]; + + makeFlags = [ + "-C optee/optee_os" + "CROSS_COMPILE64=${stdenv.cc.targetPrefix}" + "PLATFORM=tegra" + "PLATFORM_FLAVOR=${socType}" + "CFG_WITH_STMM_SP=y" + "CFG_STMM_PATH=${bspSrc}/bootloader/standalonemm_optee_${socType}.bin" + "NV_CCC_PREBUILT=${nvCccPrebuilt}" + "O=$(out)" + ] + ++ (lib.optional (taPublicKeyFile != null) "TA_PUBLIC_KEY=${taPublicKeyFile}"); + + enableParallelBuilding = true; + + # NOTE: EARLY_TA_PATHS needs to be added outside of `makeFlags` since it is a + # space separated list of paths. See + # https://nixos.org/manual/nixpkgs/stable/#build-phase for more details. + preBuild = lib.optionalString (earlyTaPaths != [ ]) '' + makeFlagsArray+=(EARLY_TA_PATHS="${toString earlyTaPaths}") + ''; + + dontInstall = true; + + meta.platforms = [ "aarch64-linux" ]; +} diff --git a/pkgs/optee/tos-image.nix b/pkgs/optee/tos-image.nix new file mode 100644 index 0000000..6a43cef --- /dev/null +++ b/pkgs/optee/tos-image.nix @@ -0,0 +1,31 @@ +{ gitRepos +, lib +, runCommand +, python3 +, dtc +, bspSrc +, armTrustedFirmware +, opteeOS +, nukeReferences +, socType +}: + + +let + flavor = lib.replaceStrings [ "t" ] [ "" ] socType; + nvopteeSrc = gitRepos."tegra/optee-src/nv-optee"; + +in +runCommand "tos.img" +{ + nativeBuildInputs = [ dtc python3 nukeReferences ]; +} '' + dtc -I dts -O dtb -o optee.dtb ${nvopteeSrc}/optee/tegra${flavor}-optee.dts + + python3 ${bspSrc}/nv_tegra/tos-scripts/gen_tos_part_img.py \ + --monitor ${armTrustedFirmware}/bl31.bin \ + --os ${opteeOS}/core/tee-raw.bin \ + --dtb optee.dtb \ + --tostype optee \ + $out +'' diff --git a/pkgs/uefi-firmware/default.nix b/pkgs/uefi-firmware/default.nix index e7ac58b..78c4fb3 100644 --- a/pkgs/uefi-firmware/default.nix +++ b/pkgs/uefi-firmware/default.nix @@ -1,307 +1,29 @@ -{ lib -, stdenv -, buildPackages -, fetchFromGitHub -, fetchurl -, fetchpatch -, fetchpatch2 -, runCommand -, edk2 -, acpica-tools -, dtc +{ runCommand , python3 -, bc -, imagemagick -, unixtools -, libuuid -, applyPatches , nukeReferences , l4tVersion -, # Optional path to a boot logo that will be converted and cropped into the format required - bootLogo ? null -, # Patches to apply to edk2-nvidia source tree - edk2NvidiaPatches ? [ ] -, # Patches to apply to edk2 source tree - edk2UefiPatches ? [ ] -, debugMode ? false -, errorLevelInfo ? debugMode -, # Enables a bunch more info messages - - # The root certificate (in PEM format) for authenticating capsule updates. By - # default, EDK2 authenticates using a test keypair commited upstream. - trustedPublicCertPemFile ? null -, +, edk2NvidiaSrc +, jetsonEdk2Uefi }: -let - # TODO: Move this generation out of uefi-firmware.nix, because this .nix - # file is callPackage'd using an aarch64 version of nixpkgs, and we don't - # want to have to recompilie imagemagick - bootLogoVariants = runCommand "uefi-bootlogo" { nativeBuildInputs = [ buildPackages.buildPackages.imagemagick ]; } '' - mkdir -p $out - convert ${bootLogo} -resize 1920x1080 -gravity Center -extent 1920x1080 -format bmp -define bmp:format=bmp3 $out/logo1080.bmp - convert ${bootLogo} -resize 1280x720 -gravity Center -extent 1280x720 -format bmp -define bmp:format=bmp3 $out/logo720.bmp - convert ${bootLogo} -resize 640x480 -gravity Center -extent 640x480 -format bmp -define bmp:format=bmp3 $out/logo480.bmp - ''; - - ### - - # See: https://github.com/NVIDIA/edk2-edkrepo-manifest/blob/main/edk2-nvidia/Jetson/NVIDIAJetsonManifest.xml - edk2-src = fetchFromGitHub { - owner = "NVIDIA"; - repo = "edk2"; - rev = "r${l4tVersion}-edk2-stable202208"; - fetchSubmodules = true; - sha256 = "sha256-A4nICu2g4Kprdmb0KVfuo8d5I5P7nAri5bzB4j9vUb4="; - }; - - edk2-platforms = fetchFromGitHub { - owner = "NVIDIA"; - repo = "edk2-platforms"; - rev = "r${l4tVersion}-upstream-20220830"; - sha256 = "sha256-PjAJEbbswOLYupMg/xEqkAOJuAC8SxNsQlb9YBswRfo="; - }; - - edk2-non-osi = fetchFromGitHub { - owner = "NVIDIA"; - repo = "edk2-non-osi"; - rev = "r${l4tVersion}-upstream-20220830"; - sha256 = "sha256-EPtI63jYhEIo4uVTH3lUt9NC/lK5vPVacUAc5qgmz9M="; - }; - - edk2-nvidia = applyPatches { - src = fetchFromGitHub { - owner = "NVIDIA"; - repo = "edk2-nvidia"; - rev = "8444db349648a77ed8e2e3047a93004c9cadb2d3"; # Latest on r35.4.1-updates as of 2023-08-07 - sha256 = "sha256-jHyyg5Ywg/tQg39oY1EwHPBjUTE7r7C9q0HO1vqCL6s="; - }; - patches = edk2NvidiaPatches ++ [ - (fetchpatch { - # https://github.com/NVIDIA/edk2-nvidia/pull/68 - name = "fix-disabled-serial.patch"; - url = "https://github.com/NVIDIA/edk2-nvidia/commit/9604259b0d11c049f6a3eb5365a3ae10cfb9e6d9.patch"; - hash = "sha256-v/WEwcSNjBXeN0eXVzzl31dn6mq78wIm0u5lW1jGcdE="; - }) - # Fix Eqos driver to use correct TX clock name - # PR: https://github.com/NVIDIA/edk2-nvidia/pull/76 - (fetchpatch { - url = "https://github.com/NVIDIA/edk2-nvidia/commit/26f50dc3f0f041d20352d1656851c77f43c7238e.patch"; - hash = "sha256-cc+eGLFHZ6JQQix1VWe/UOkGunAzPb8jM9SXa9ScIn8="; - }) - - ./capsule-authentication.patch - - # Have UEFI use the device tree compiled into the firmware, instead of - # using one from the kernel-dtb partition. - # See: https://github.com/anduril/jetpack-nixos/pull/18 - ./edk2-uefi-dtb.patch - ]; - postPatch = lib.optionalString errorLevelInfo '' - sed -i 's#PcdDebugPrintErrorLevel|.*#PcdDebugPrintErrorLevel|0x8000004F#' Platform/NVIDIA/NVIDIA.common.dsc.inc - '' + lib.optionalString (bootLogo != null) '' - cp ${bootLogoVariants}/logo1080.bmp Silicon/NVIDIA/Assets/nvidiagray1080.bmp - cp ${bootLogoVariants}/logo720.bmp Silicon/NVIDIA/Assets/nvidiagray720.bmp - cp ${bootLogoVariants}/logo480.bmp Silicon/NVIDIA/Assets/nvidiagray480.bmp - ''; - }; - - edk2-nvidia-non-osi = fetchFromGitHub { - owner = "NVIDIA"; - repo = "edk2-nvidia-non-osi"; - rev = "r${l4tVersion}"; - sha256 = "sha256-h0EW5j5/pq0c48alz7w2+g4RCU2yQdYOtDiNFH9VI3M="; - }; - - # Patches from upstream tianocore/edk2 for OpenSSL, to enable in-tree build - # of OpenSSL 1.1.1t - opensslPatches = import ./edk2-openssl-patches.nix { - inherit fetchpatch2; - }; - - # This has been taken from: - # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd - vendoredOpenSSL = fetchFromGitHub { - owner = "openssl"; - repo = "openssl"; - rev = "OpenSSL_1_1_1t"; - sha256 = "sha256-gI2+Vm67j1+xLvzBb+DF0YFTOHW7myotRsXRzluzSLY="; - }; - - edk2-jetson = edk2.overrideAttrs (prev: { - src = edk2-src; - - depsBuildBuild = prev.depsBuildBuild ++ [ libuuid ]; - - patches = - # Remove this one patch (CryptoPkg/OpensslLib: Upgrade OpenSSL to 1.1.1t) - # present on nixos-23.05, as it will be added in the opensslPatches below - (builtins.filter (patch: patch.url != "https://bugzilla.tianocore.org/attachment.cgi?id=1330") prev.patches) - ++ opensslPatches; - postUnpack = '' - # This has been taken from: - # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd - rm -rf source/CryptoPkg/Library/OpensslLib/openssl - ''; - postPatch = '' - # This has been taken from: - # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd - - # Replace the edk2's in-tree openssl git-submodule with our 1.1.1t - cp -r ${vendoredOpenSSL} CryptoPkg/Library/OpensslLib/openssl - ''; - }); - - pythonEnv = buildPackages.python3.withPackages (ps: [ ps.tkinter ]); - targetArch = - if stdenv.isi686 then - "IA32" - else if stdenv.isx86_64 then - "X64" - else if stdenv.isAarch64 then - "AARCH64" - else - throw "Unsupported architecture"; - - buildType = - if stdenv.isDarwin then - "CLANGPDB" - else - "GCC5"; - - buildTarget = if debugMode then "DEBUG" else "RELEASE"; - - jetson-edk2-uefi = - # TODO: edk2.mkDerivation doesn't have a way to override the edk version used! - # Make it not via passthru ? - stdenv.mkDerivation { - pname = "jetson-edk2-uefi"; - version = l4tVersion; - - # Initialize the build dir with the build tools from edk2 - src = edk2-src; - - depsBuildBuild = [ buildPackages.stdenv.cc ]; - nativeBuildInputs = [ bc pythonEnv acpica-tools dtc unixtools.whereis ]; - strictDeps = true; - - NIX_CFLAGS_COMPILE = [ - "-Wno-error=format-security" # TODO: Fix underlying issue - - # Workaround for ../Silicon/NVIDIA/Drivers/EqosDeviceDxe/nvethernetrm/osi/core/osi_hal.c:1428: undefined reference to `__aarch64_ldadd4_sync' - "-mno-outline-atomics" - ]; - - ${"GCC5_${targetArch}_PREFIX"} = stdenv.cc.targetPrefix; - - # From edk2-nvidia/Silicon/NVIDIA/edk2nv/stuart/settings.py - PACKAGES_PATH = lib.concatStringsSep ":" [ - "${edk2-src}/BaseTools" # TODO: Is this needed? - edk2-src - edk2-platforms - edk2-non-osi - edk2-nvidia - edk2-nvidia-non-osi - "${edk2-platforms}/Features/Intel/OutOfBandManagement" - ]; - - enableParallelBuilding = true; - - postUnpack = '' - # This has been taken from: - # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd - rm -rf source/CryptoPkg/Library/OpensslLib/openssl - ''; - - prePatch = '' - rm -rf BaseTools - cp -r ${edk2-jetson}/BaseTools BaseTools - chmod -R u+w BaseTools - ''; - - patches = opensslPatches ++ edk2UefiPatches ++ [ - (fetchurl { - # Patch format does not play well with fetchpatch, it should be fine this is a static attachment in a ticket - name = "CVE-2023-45229_CVE-2023-45230_CVE-2023-45231_CVE-2023-45232_CVE-2023-45233_CVE-2023-45234_CVE-2023-45235.patch"; - url = "https://bugzilla.tianocore.org/attachment.cgi?id=1457"; - hash = "sha256-CF41lbjnXbq/6DxMW6q1qcLJ8WAs+U0Rjci+jRwJYYY="; - }) - (fetchpatch { - name = "CVE-2022-36764.patch"; - url = "https://bugzilla.tianocore.org/attachment.cgi?id=1436"; - hash = "sha256-czku8DgElisDv6minI67nNt6BS+vH6txslZdqiGaQR4="; - excludes = [ - "SecurityPkg/Test/SecurityPkgHostTest.dsc" - ]; - }) - ]; - - postPatch = '' - # This has been taken from: - # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd - - # Replace the edk2's in-tree openssl git-submodule with our 1.1.1t - cp -r ${vendoredOpenSSL} CryptoPkg/Library/OpensslLib/openssl - ''; - - configurePhase = '' - runHook preConfigure - export WORKSPACE="$PWD" - source ./edksetup.sh BaseTools - - ${lib.optionalString (trustedPublicCertPemFile != null) '' - echo Using ${trustedPublicCertPemFile} as public certificate for capsule verification - ${lib.getExe buildPackages.openssl} x509 -outform DER -in ${trustedPublicCertPemFile} -out PublicCapsuleKey.cer - python3 BaseTools/Scripts/BinToPcd.py -p gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer -i PublicCapsuleKey.cer -o PublicCapsuleKey.cer.gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer.inc - python3 BaseTools/Scripts/BinToPcd.py -x -p gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr -i PublicCapsuleKey.cer -o PublicCapsuleKey.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc - ''} - - runHook postConfigure - ''; - - buildPhase = '' - runHook preBuild - - # The BUILDID_STRING and BUILD_DATE_TIME are used - # just by nvidia, not generic edk2 - build -a ${targetArch} -b ${buildTarget} -t ${buildType} -p Platform/NVIDIA/Jetson/Jetson.dsc -n $NIX_BUILD_CORES \ - -D BUILDID_STRING=${l4tVersion} \ - -D BUILD_DATE_TIME="$(date --utc --iso-8601=seconds --date=@$SOURCE_DATE_EPOCH)" \ - ${lib.optionalString (trustedPublicCertPemFile != null) "-D CUSTOM_CAPSULE_CERT"} \ - $buildFlags - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - mv -v Build/*/* $out - runHook postInstall - ''; - }; - - uefi-firmware = runCommand "uefi-firmware-${l4tVersion}" - { - nativeBuildInputs = [ python3 nukeReferences ]; - } '' - mkdir -p $out - python3 ${edk2-nvidia}/Silicon/NVIDIA/Tools/FormatUefiBinary.py \ - ${jetson-edk2-uefi}/FV/UEFI_NS.Fv \ - $out/uefi_jetson.bin - - python3 ${edk2-nvidia}/Silicon/NVIDIA/Tools/FormatUefiBinary.py \ - ${jetson-edk2-uefi}/AARCH64/L4TLauncher.efi \ - $out/L4TLauncher.efi - - mkdir -p $out/dtbs - for filename in ${jetson-edk2-uefi}/AARCH64/Silicon/NVIDIA/Tegra/DeviceTree/DeviceTree/OUTPUT/*.dtb; do - cp $filename $out/dtbs/$(basename "$filename" ".dtb").dtbo - done - - # Get rid of any string references to source(s) - nuke-refs $out/uefi_jetson.bin - ''; -in +runCommand "uefi-firmware-${l4tVersion}" { - inherit edk2-jetson uefi-firmware; -} + nativeBuildInputs = [ python3 nukeReferences ]; +} '' + mkdir -p $out + python3 ${edk2NvidiaSrc}/Silicon/NVIDIA/Tools/FormatUefiBinary.py \ + ${jetsonEdk2Uefi}/FV/UEFI_NS.Fv \ + $out/uefi_jetson.bin + + python3 ${edk2NvidiaSrc}/Silicon/NVIDIA/Tools/FormatUefiBinary.py \ + ${jetsonEdk2Uefi}/AARCH64/L4TLauncher.efi \ + $out/L4TLauncher.efi + + mkdir -p $out/dtbs + for filename in ${jetsonEdk2Uefi}/AARCH64/Silicon/NVIDIA/Tegra/DeviceTree/DeviceTree/OUTPUT/*.dtb; do + cp $filename $out/dtbs/$(basename "$filename" ".dtb").dtbo + done + + # Get rid of any string references to source(s) + nuke-refs $out/uefi_jetson.bin +'' diff --git a/pkgs/uefi-firmware/edk2-nvidia-src.nix b/pkgs/uefi-firmware/edk2-nvidia-src.nix new file mode 100644 index 0000000..cef1073 --- /dev/null +++ b/pkgs/uefi-firmware/edk2-nvidia-src.nix @@ -0,0 +1,59 @@ +{ lib +, runCommand +, fetchpatch +, fetchFromGitHub +, imagemagick +, applyPatches +, errorLevelInfo ? false +, bootLogo ? null # Optional path to a boot logo that will be converted and cropped into the format required +}: + +let + bootLogoVariants = runCommand "uefi-bootlogo" { nativeBuildInputs = [ imagemagick ]; } '' + mkdir -p $out + convert ${bootLogo} -resize 1920x1080 -gravity Center -extent 1920x1080 -format bmp -define bmp:format=bmp3 $out/logo1080.bmp + convert ${bootLogo} -resize 1280x720 -gravity Center -extent 1280x720 -format bmp -define bmp:format=bmp3 $out/logo720.bmp + convert ${bootLogo} -resize 640x480 -gravity Center -extent 640x480 -format bmp -define bmp:format=bmp3 $out/logo480.bmp + ''; +in +applyPatches { + name = "edk2-nvidia"; + + src = fetchFromGitHub { + owner = "NVIDIA"; + repo = "edk2-nvidia"; + rev = "8444db349648a77ed8e2e3047a93004c9cadb2d3"; # Latest on r35.4.1-updates as of 2023-08-07 + sha256 = "sha256-jHyyg5Ywg/tQg39oY1EwHPBjUTE7r7C9q0HO1vqCL6s="; + }; + + patches = [ + (fetchpatch { + # https://github.com/NVIDIA/edk2-nvidia/pull/68 + name = "fix-disabled-serial.patch"; + url = "https://github.com/NVIDIA/edk2-nvidia/commit/9604259b0d11c049f6a3eb5365a3ae10cfb9e6d9.patch"; + hash = "sha256-v/WEwcSNjBXeN0eXVzzl31dn6mq78wIm0u5lW1jGcdE="; + }) + + # Fix Eqos driver to use correct TX clock name + # PR: https://github.com/NVIDIA/edk2-nvidia/pull/76 + (fetchpatch { + url = "https://github.com/NVIDIA/edk2-nvidia/commit/26f50dc3f0f041d20352d1656851c77f43c7238e.patch"; + hash = "sha256-cc+eGLFHZ6JQQix1VWe/UOkGunAzPb8jM9SXa9ScIn8="; + }) + + ./capsule-authentication.patch + + # Have UEFI use the device tree compiled into the firmware, instead of + # using one from the kernel-dtb partition. + # See: https://github.com/anduril/jetpack-nixos/pull/18 + ./edk2-uefi-dtb.patch + ]; + + postPatch = lib.optionalString errorLevelInfo '' + sed -i 's#PcdDebugPrintErrorLevel|.*#PcdDebugPrintErrorLevel|0x8000004F#' Platform/NVIDIA/NVIDIA.common.dsc.inc + '' + lib.optionalString (bootLogo != null) '' + cp ${bootLogoVariants}/logo1080.bmp Silicon/NVIDIA/Assets/nvidiagray1080.bmp + cp ${bootLogoVariants}/logo720.bmp Silicon/NVIDIA/Assets/nvidiagray720.bmp + cp ${bootLogoVariants}/logo480.bmp Silicon/NVIDIA/Assets/nvidiagray480.bmp + ''; +} diff --git a/pkgs/uefi-firmware/jetson-edk2-uefi.nix b/pkgs/uefi-firmware/jetson-edk2-uefi.nix new file mode 100644 index 0000000..5ac4a4e --- /dev/null +++ b/pkgs/uefi-firmware/jetson-edk2-uefi.nix @@ -0,0 +1,217 @@ +{ lib +, stdenv +, buildPackages +, fetchFromGitHub +, fetchurl +, fetchpatch +, fetchpatch2 +, edk2 +, acpica-tools +, dtc +, bc +, unixtools +, libuuid +, edk2NvidiaSrc + +, debugMode ? false + # The root certificate (in PEM format) for authenticating capsule updates. By + # default, EDK2 authenticates using a test keypair commited upstream. +, trustedPublicCertPemFile ? null +, l4tVersion +}: +let + # See: https://github.com/NVIDIA/edk2-edkrepo-manifest/blob/main/edk2-nvidia/Jetson/NVIDIAJetsonManifest.xml + edk2Src = fetchFromGitHub { + owner = "NVIDIA"; + repo = "edk2"; + rev = "r${l4tVersion}-edk2-stable202208"; + fetchSubmodules = true; + sha256 = "sha256-A4nICu2g4Kprdmb0KVfuo8d5I5P7nAri5bzB4j9vUb4="; + }; + + edk2Platforms = fetchFromGitHub { + owner = "NVIDIA"; + repo = "edk2-platforms"; + rev = "r${l4tVersion}-upstream-20220830"; + sha256 = "sha256-PjAJEbbswOLYupMg/xEqkAOJuAC8SxNsQlb9YBswRfo="; + }; + + edk2NonOsi = fetchFromGitHub { + owner = "NVIDIA"; + repo = "edk2-non-osi"; + rev = "r${l4tVersion}-upstream-20220830"; + sha256 = "sha256-EPtI63jYhEIo4uVTH3lUt9NC/lK5vPVacUAc5qgmz9M="; + }; + + edk2NvidiaNonOsi = fetchFromGitHub { + owner = "NVIDIA"; + repo = "edk2-nvidia-non-osi"; + rev = "r${l4tVersion}"; + sha256 = "sha256-h0EW5j5/pq0c48alz7w2+g4RCU2yQdYOtDiNFH9VI3M="; + }; + + # Patches from upstream tianocore/edk2 for OpenSSL, to enable in-tree build + # of OpenSSL 1.1.1t + opensslPatches = import ./edk2-openssl-patches.nix { + inherit fetchpatch2; + }; + + # This has been taken from: + # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd + vendoredOpenSSL = fetchFromGitHub { + owner = "openssl"; + repo = "openssl"; + rev = "OpenSSL_1_1_1t"; + sha256 = "sha256-gI2+Vm67j1+xLvzBb+DF0YFTOHW7myotRsXRzluzSLY="; + }; + + edk2-jetson = edk2.overrideAttrs (prev: { + src = edk2Src; + + depsBuildBuild = prev.depsBuildBuild ++ [ libuuid ]; + + patches = + # Remove this one patch (CryptoPkg/OpensslLib: Upgrade OpenSSL to 1.1.1t) + # present on nixos-23.05, as it will be added in the opensslPatches below + (builtins.filter (patch: patch.url != "https://bugzilla.tianocore.org/attachment.cgi?id=1330") prev.patches) + ++ opensslPatches; + postUnpack = '' + # This has been taken from: + # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd + rm -rf source/CryptoPkg/Library/OpensslLib/openssl + ''; + postPatch = '' + # This has been taken from: + # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd + + # Replace the edk2's in-tree openssl git-submodule with our 1.1.1t + cp -r ${vendoredOpenSSL} CryptoPkg/Library/OpensslLib/openssl + ''; + }); + + pythonEnv = buildPackages.python3.withPackages (ps: [ ps.tkinter ]); + targetArch = + if stdenv.isi686 then + "IA32" + else if stdenv.isx86_64 then + "X64" + else if stdenv.isAarch64 then + "AARCH64" + else + throw "Unsupported architecture"; + + buildType = + if stdenv.isDarwin then + "CLANGPDB" + else + "GCC5"; + + buildTarget = if debugMode then "DEBUG" else "RELEASE"; +in +# TODO: edk2.mkDerivation doesn't have a way to override the edk version used! + # Make it not via passthru ? +stdenv.mkDerivation { + pname = "jetson-edk2-uefi"; + version = l4tVersion; + + # Initialize the build dir with the build tools from edk2 + src = edk2Src; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + nativeBuildInputs = [ bc pythonEnv acpica-tools dtc unixtools.whereis ]; + strictDeps = true; + + NIX_CFLAGS_COMPILE = [ + "-Wno-error=format-security" # TODO: Fix underlying issue + + # Workaround for ../Silicon/NVIDIA/Drivers/EqosDeviceDxe/nvethernetrm/osi/core/osi_hal.c:1428: undefined reference to `__aarch64_ldadd4_sync' + "-mno-outline-atomics" + ]; + + ${"GCC5_${targetArch}_PREFIX"} = stdenv.cc.targetPrefix; + + # From edk2-nvidia/Silicon/NVIDIA/edk2nv/stuart/settings.py + PACKAGES_PATH = lib.concatStringsSep ":" [ + "${edk2Src}/BaseTools" # TODO: Is this needed? + edk2Src + edk2Platforms + edk2NonOsi + edk2NvidiaSrc + edk2NvidiaNonOsi + "${edk2Platforms}/Features/Intel/OutOfBandManagement" + ]; + + enableParallelBuilding = true; + + postUnpack = '' + # This has been taken from: + # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd + rm -rf source/CryptoPkg/Library/OpensslLib/openssl + ''; + + prePatch = '' + rm -rf BaseTools + cp -r ${edk2-jetson}/BaseTools BaseTools + chmod -R u+w BaseTools + ''; + + patches = opensslPatches ++ [ + (fetchurl { + # Patch format does not play well with fetchpatch, it should be fine this is a static attachment in a ticket + name = "CVE-2023-45229_CVE-2023-45230_CVE-2023-45231_CVE-2023-45232_CVE-2023-45233_CVE-2023-45234_CVE-2023-45235.patch"; + url = "https://bugzilla.tianocore.org/attachment.cgi?id=1457"; + hash = "sha256-CF41lbjnXbq/6DxMW6q1qcLJ8WAs+U0Rjci+jRwJYYY="; + }) + (fetchpatch { + name = "CVE-2022-36764.patch"; + url = "https://bugzilla.tianocore.org/attachment.cgi?id=1436"; + hash = "sha256-czku8DgElisDv6minI67nNt6BS+vH6txslZdqiGaQR4="; + excludes = [ + "SecurityPkg/Test/SecurityPkgHostTest.dsc" + ]; + }) + ]; + + postPatch = '' + # This has been taken from: + # https://github.com/NixOS/nixpkgs/commit/3ed8d9b547c3941d74d9455fdec120f415ebaacd + + # Replace the edk2's in-tree openssl git-submodule with our 1.1.1t + cp -r ${vendoredOpenSSL} CryptoPkg/Library/OpensslLib/openssl + ''; + + configurePhase = '' + runHook preConfigure + export WORKSPACE="$PWD" + source ./edksetup.sh BaseTools + + ${lib.optionalString (trustedPublicCertPemFile != null) '' + echo Using ${trustedPublicCertPemFile} as public certificate for capsule verification + ${lib.getExe buildPackages.openssl} x509 -outform DER -in ${trustedPublicCertPemFile} -out PublicCapsuleKey.cer + python3 BaseTools/Scripts/BinToPcd.py -p gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer -i PublicCapsuleKey.cer -o PublicCapsuleKey.cer.gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer.inc + python3 BaseTools/Scripts/BinToPcd.py -x -p gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr -i PublicCapsuleKey.cer -o PublicCapsuleKey.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc + ''} + + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + + # The BUILDID_STRING and BUILD_DATE_TIME are used + # just by nvidia, not generic edk2 + build -a ${targetArch} -b ${buildTarget} -t ${buildType} -p Platform/NVIDIA/Jetson/Jetson.dsc -n $NIX_BUILD_CORES \ + -D BUILDID_STRING=${l4tVersion} \ + -D BUILD_DATE_TIME="$(date --utc --iso-8601=seconds --date=@$SOURCE_DATE_EPOCH)" \ + ${lib.optionalString (trustedPublicCertPemFile != null) "-D CUSTOM_CAPSULE_CERT"} \ + $buildFlags + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mv -v Build/*/* $out + runHook postInstall + ''; +}