Skip to content

Commit 7c42129

Browse files
committed
jetson-orin: enroll UEFI secure boot keys from certs
Signed-off-by: vadik likholetov <vadikas@gmail.com>
1 parent 57e6fe0 commit 7c42129

File tree

10 files changed

+536
-0
lines changed

10 files changed

+536
-0
lines changed

docs/src/content/docs/ghaf/overview/arch/secureboot.mdx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,38 @@ efi-readvar -v PK
4141
efi-readvar -v KEK
4242
efi-readvar -v db
4343
```
44+
45+
## Jetson Orin signed flashing workflow
46+
47+
Jetson Orin targets produce two independent build artifacts in CI:
48+
49+
1. The flash script (`nix build .#nvidia-jetson-orin-agx-debug-from-x86_64-flash-script`) which orchestrates NVIDIA's flashing tools.
50+
2. The filesystem image (`nix build .#nvidia-jetson-orin-agx-debug-from-x86_64`) that contains the ESP and root partitions.
51+
52+
After the filesystem image is signed, pass its Nix store path directly to the flash helper:
53+
54+
```sh
55+
SIGNED_SD_IMAGE=$(nix path-info .#nvidia-jetson-orin-agx-debug-from-x86_64)
56+
./result/bin/initrd-flash-ghaf-host -s "$SIGNED_SD_IMAGE"
57+
```
58+
59+
The `-s/--signed-sd-image` flag extracts `BOOTAA64.EFI` and the kernel from the signed image, wires them into the flashing workdir, and launches NVIDIA's flashing script without requiring any additional staging directories or host key material.
60+
61+
For ad-hoc debugging you can also point `-s` to a copy of the signed build outside the Nix store (for example, `cp -a $(nix path-info …) /tmp/orin-signed` and then pass `/tmp/orin-signed`), which is useful when the original store path is unavailable on the flashing host.
62+
63+
For CI jobs that still need a deterministic artifact directory (for example when reusing the same signed files across multiple runs), the helper `modules/secureboot/extract-signed-orin-artifacts.sh` can be used:
64+
65+
```sh
66+
./modules/secureboot/extract-signed-orin-artifacts.sh \
67+
--sd-image-dir "$SIGNED_SD_IMAGE" \
68+
--output /build/orin-flash-artifacts \
69+
--force
70+
71+
# Optional: reuse the staged directory via configuration or the environment
72+
export SIGNED_ARTIFACTS_DIR=/build/orin-flash-artifacts
73+
./result/bin/initrd-flash-ghaf-host
74+
```
75+
76+
The helper resolves the supplied directory—whether it's a `/nix/store/...` path or a copy under `/tmp`—before extracting the ESP and root partitions.
77+
78+
The existing module option `ghaf.hardware.nvidia.orin.flashScriptOverrides.signedArtifactsPath` still forces the flash script to pick up a specific directory when the environment variable is not convenient.

modules/reference/hardware/jetpack/nvidia-jetson-orin/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
imports = [
77
./partition-template.nix
88
./jetson-orin.nix
9+
./secureboot.nix
910

1011
./pci-passthrough-common.nix
1112

modules/reference/hardware/jetpack/nvidia-jetson-orin/jetson-orin.nix

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ in
2929
default = "";
3030
};
3131

32+
flashScriptOverrides.signedArtifactsPath = mkOption {
33+
description = ''
34+
Absolute path on the host that contains pre-signed Jetson Orin boot
35+
artifacts.
36+
37+
The flash script expects at least `BOOTAA64.EFI` and `Image` to be
38+
present in this directory. Optional files such as `initrd` or device
39+
trees can be staged as well. The directory can also be provided at
40+
runtime through the `SIGNED_ARTIFACTS_DIR` environment variable.
41+
'';
42+
type = types.nullOr types.str;
43+
default = null;
44+
};
45+
3246
somType = mkOption {
3347
description = "SoM config Type (NX|AGX32|AGX64|Nano)";
3448
type = types.str;
@@ -49,6 +63,8 @@ in
4963
};
5064

5165
config = mkIf cfg.enable {
66+
ghaf.hardware.nvidia.orin.secureboot.enable = lib.mkDefault true;
67+
5268
hardware.nvidia-jetpack.kernel.version = "${cfg.kernelVersion}";
5369
nixpkgs.hostPlatform.system = "aarch64-linux";
5470

modules/reference/hardware/jetpack/nvidia-jetson-orin/partition-template.nix

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,53 @@ in
147147
rm -fv "$WORKDIR/bootloader/esp.img"
148148
mkdir -pv "$WORKDIR/bootloader"
149149
150+
${lib.optionalString (cfg.flashScriptOverrides.signedArtifactsPath != null) ''
151+
if [ -z "''${SIGNED_ARTIFACTS_DIR:-}" ]; then
152+
SIGNED_ARTIFACTS_DIR=${lib.escapeShellArg cfg.flashScriptOverrides.signedArtifactsPath}
153+
fi
154+
''}
155+
156+
if [ -n "''${SIGNED_ARTIFACTS_DIR:-}" ]; then
157+
echo "Using signed artifacts from $SIGNED_ARTIFACTS_DIR"
158+
159+
for artifact in BOOTAA64.EFI Image; do
160+
if [ ! -f "$SIGNED_ARTIFACTS_DIR/$artifact" ]; then
161+
echo "ERROR: Missing $artifact in $SIGNED_ARTIFACTS_DIR" >&2
162+
exit 1
163+
fi
164+
done
165+
166+
export BOOTAA64_EFI="$SIGNED_ARTIFACTS_DIR/BOOTAA64.EFI"
167+
export KERNEL_IMAGE="$SIGNED_ARTIFACTS_DIR/Image"
168+
169+
if [ -f "$SIGNED_ARTIFACTS_DIR/initrd" ]; then
170+
export INITRD_IMAGE="$SIGNED_ARTIFACTS_DIR/initrd"
171+
fi
172+
173+
if [ -f "$SIGNED_ARTIFACTS_DIR/dtb" ]; then
174+
export DTB_IMAGE="$SIGNED_ARTIFACTS_DIR/dtb"
175+
fi
176+
fi
177+
178+
if [ -n "''${BOOTAA64_EFI:-}" ]; then
179+
if [ ! -f "$BOOTAA64_EFI" ]; then
180+
echo "ERROR: BOOTAA64_EFI not found: $BOOTAA64_EFI" >&2
181+
exit 1
182+
fi
183+
echo "Using external BOOTAA64.EFI: $BOOTAA64_EFI"
184+
cp -f "$BOOTAA64_EFI" "$WORKDIR/bootloader/BOOTAA64.EFI"
185+
fi
186+
187+
if [ -n "''${KERNEL_IMAGE:-}" ]; then
188+
if [ ! -f "$KERNEL_IMAGE" ]; then
189+
echo "ERROR: KERNEL_IMAGE not found: $KERNEL_IMAGE" >&2
190+
exit 1
191+
fi
192+
echo "Using external kernel Image: $KERNEL_IMAGE"
193+
mkdir -pv "$WORKDIR/kernel"
194+
cp -f "$KERNEL_IMAGE" "$WORKDIR/kernel/Image"
195+
fi
196+
150197
# See https://developer.download.nvidia.com/embedded/L4T/r35_Release_v4.1/docs/Jetson_Linux_Release_Notes_r35.4.1.pdf
151198
# and https://developer.download.nvidia.com/embedded/L4T/r35_Release_v5.0/docs/Jetson_Linux_Release_Notes_r35.5.0.pdf
152199
#
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
{
5+
config,
6+
lib,
7+
pkgs,
8+
...
9+
}:
10+
let
11+
cfg = config.ghaf.hardware.nvidia.orin.secureboot;
12+
13+
eslFromCert =
14+
name: cert:
15+
pkgs.runCommand name { nativeBuildInputs = [ pkgs.buildPackages.efitools ]; } ''
16+
${pkgs.buildPackages.efitools}/bin/cert-to-efi-sig-list ${cert} $out
17+
'';
18+
19+
keysDir = cfg.keysSource;
20+
21+
pkEsl = eslFromCert "PK.esl" "${keysDir}/PK.crt";
22+
kekEsl = eslFromCert "KEK.esl" "${keysDir}/KEK.crt";
23+
dbEsl = eslFromCert "db.esl" "${keysDir}/db.crt";
24+
in
25+
{
26+
options.ghaf.hardware.nvidia.orin.secureboot = {
27+
enable = lib.mkEnableOption "UEFI Secure Boot key enrollment for Jetson Orin";
28+
29+
keysSource = lib.mkOption {
30+
type = lib.types.path;
31+
default = ../../../../secureboot/keys;
32+
description = "Directory containing PK.crt, KEK.crt and db.crt used to generate ESLs.";
33+
};
34+
};
35+
36+
config = lib.mkIf cfg.enable {
37+
hardware.nvidia-jetpack.firmware.uefi.secureBoot = {
38+
enrollDefaultKeys = true;
39+
defaultPkEslFile = pkEsl;
40+
defaultKekEslFile = kekEsl;
41+
defaultDbEslFile = dbEsl;
42+
};
43+
};
44+
}

0 commit comments

Comments
 (0)