Skip to content

Commit fcd6c17

Browse files
vadikaMic92
authored andcommitted
jetson-orin: enroll UEFI secure boot keys from certs
Signed-off-by: vadik likholetov <vadikas@gmail.com>
1 parent 40e2c3f commit fcd6c17

File tree

10 files changed

+540
-0
lines changed

10 files changed

+540
-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
@@ -43,3 +43,38 @@ efi-readvar -v PK
4343
efi-readvar -v KEK
4444
efi-readvar -v db
4545
```
46+
47+
## Jetson Orin signed flashing workflow
48+
49+
Jetson Orin targets produce two independent build artifacts in CI:
50+
51+
1. The flash script (`nix build .#nvidia-jetson-orin-agx-debug-from-x86_64-flash-script`) which orchestrates NVIDIA's flashing tools.
52+
2. The filesystem image (`nix build .#nvidia-jetson-orin-agx-debug-from-x86_64`) that contains the ESP and root partitions.
53+
54+
After the filesystem image is signed, pass its Nix store path directly to the flash helper:
55+
56+
```sh
57+
SIGNED_SD_IMAGE=$(nix path-info .#nvidia-jetson-orin-agx-debug-from-x86_64)
58+
./result/bin/initrd-flash-ghaf-host -s "$SIGNED_SD_IMAGE"
59+
```
60+
61+
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.
62+
63+
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.
64+
65+
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:
66+
67+
```sh
68+
./modules/secureboot/extract-signed-orin-artifacts.sh \
69+
--sd-image-dir "$SIGNED_SD_IMAGE" \
70+
--output /build/orin-flash-artifacts \
71+
--force
72+
73+
# Optional: reuse the staged directory via configuration or the environment
74+
export SIGNED_ARTIFACTS_DIR=/build/orin-flash-artifacts
75+
./result/bin/initrd-flash-ghaf-host
76+
```
77+
78+
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.
79+
80+
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
./pci-passthrough-common.nix
1011
./virtualization
1112
./optee.nix

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

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

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

5367
config = mkIf cfg.enable {
68+
ghaf.hardware.nvidia.orin.secureboot.enable = lib.mkDefault true;
69+
5470
hardware.nvidia-jetpack.kernel.version = "${cfg.kernelVersion}";
5571
nixpkgs.hostPlatform.system = "aarch64-linux";
5672

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,57 @@ let
146146
WORKDIR=$PWD
147147
mkdir -pv "$WORKDIR/bootloader"
148148
rm -fv "$WORKDIR/bootloader/esp.img"
149+
''
150+
+ lib.optionalString (cfg.flashScriptOverrides.signedArtifactsPath != null) ''
151+
152+
if [ -z "''${SIGNED_ARTIFACTS_DIR:-}" ]; then
153+
SIGNED_ARTIFACTS_DIR=${lib.escapeShellArg cfg.flashScriptOverrides.signedArtifactsPath}
154+
fi
155+
''
156+
+ ''
157+
158+
if [ -n "''${SIGNED_ARTIFACTS_DIR:-}" ]; then
159+
echo "Using signed artifacts from $SIGNED_ARTIFACTS_DIR"
160+
161+
for artifact in BOOTAA64.EFI Image; do
162+
if [ ! -f "$SIGNED_ARTIFACTS_DIR/$artifact" ]; then
163+
echo "ERROR: Missing $artifact in $SIGNED_ARTIFACTS_DIR" >&2
164+
exit 1
165+
fi
166+
done
167+
168+
export BOOTAA64_EFI="$SIGNED_ARTIFACTS_DIR/BOOTAA64.EFI"
169+
export KERNEL_IMAGE="$SIGNED_ARTIFACTS_DIR/Image"
170+
171+
if [ -f "$SIGNED_ARTIFACTS_DIR/initrd" ]; then
172+
export INITRD_IMAGE="$SIGNED_ARTIFACTS_DIR/initrd"
173+
fi
174+
175+
if [ -f "$SIGNED_ARTIFACTS_DIR/dtb" ]; then
176+
export DTB_IMAGE="$SIGNED_ARTIFACTS_DIR/dtb"
177+
fi
178+
fi
179+
180+
if [ -n "''${BOOTAA64_EFI:-}" ]; then
181+
if [ ! -f "$BOOTAA64_EFI" ]; then
182+
echo "ERROR: BOOTAA64_EFI not found: $BOOTAA64_EFI" >&2
183+
exit 1
184+
fi
185+
echo "Using external BOOTAA64.EFI: $BOOTAA64_EFI"
186+
cp -f "$BOOTAA64_EFI" "$WORKDIR/bootloader/BOOTAA64.EFI"
187+
fi
188+
189+
if [ -n "''${KERNEL_IMAGE:-}" ]; then
190+
if [ ! -f "$KERNEL_IMAGE" ]; then
191+
echo "ERROR: KERNEL_IMAGE not found: $KERNEL_IMAGE" >&2
192+
exit 1
193+
fi
194+
echo "Using external kernel Image: $KERNEL_IMAGE"
195+
mkdir -pv "$WORKDIR/kernel"
196+
cp -f "$KERNEL_IMAGE" "$WORKDIR/kernel/Image"
197+
fi
198+
''
199+
+ lib.optionalString (!cfg.flashScriptOverrides.onlyQSPI) ''
149200
150201
${lib.optionalString (!cfg.flashScriptOverrides.onlyQSPI) ''
151202
# Read partition offsets and sizes from sdImage metadata
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)