Skip to content

Commit 8ae6aa8

Browse files
committed
Sign EFI binaries at flash time for UEFI Secure Boot
The secureboot PR (#1713) enrolls PK/KEK/db keys into the Jetson Orin firmware, but nothing was signing the UKI or systemd-boot. Once keys are enrolled and the UEFI leaves Setup Mode, it rejects unsigned binaries with 'Access denied', bricking the device. Move ESP image construction from a Nix derivation into the flash script so we can sign EFI binaries with sbsign just before writing them to the FAT partition. The private key is read at flash time from SECURE_BOOT_SIGNING_KEY_DIR (or the signingKeyDir option), keeping it out of the Nix store. Add self-signed development keys under modules/secureboot/dev-keys/ for testing. These are explicitly not secret and must not be used in production. Tested on Jetson AGX Orin: device boots with Secure Boot enabled (user mode), unsigned UKI is rejected with 'Access denied'.
1 parent 6e9e06f commit 8ae6aa8

File tree

17 files changed

+365
-61
lines changed

17 files changed

+365
-61
lines changed

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

Lines changed: 114 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,37 +42,131 @@ efi-readvar -v KEK
4242
efi-readvar -v db
4343
```
4444

45-
## Jetson Orin signed flashing workflow
45+
## Jetson Orin Secure Boot
4646

47-
Jetson Orin targets produce two independent build artifacts in CI:
47+
On Jetson Orin targets with verity boot, Secure Boot is handled differently from
48+
the x86 laptop flow. The NVIDIA UEFI firmware supports standard UEFI Secure Boot
49+
key enrollment via a device tree overlay, and EFI binaries (systemd-boot and UKIs)
50+
are signed at flash time rather than build time.
4851

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.
52+
This keeps private signing keys out of the Nix store while still producing a
53+
fully signed boot chain.
5154

52-
After the filesystem image is signed, pass its Nix store path directly to the flash helper:
55+
### How it works
56+
57+
1. **Key enrollment**: During flash, a DTB overlay (`UefiDefaultSecurityKeys.dtbo`)
58+
embeds PK, KEK, and db certificates into the firmware. On first boot, the UEFI
59+
enrolls these keys and transitions from Setup Mode to User Mode.
60+
61+
2. **EFI signing**: The flash script builds the ESP image at flash time. Before
62+
copying EFI binaries into the FAT partition, it signs each `.efi` file with
63+
`sbsign` using the db private key. This signs both systemd-boot (`BOOTAA64.efi`)
64+
and the UKI.
65+
66+
3. **Enforcement**: Once in User Mode (SetupMode=0, SecureBoot=1), the UEFI
67+
firmware rejects any unsigned or incorrectly signed EFI binary with
68+
"Access denied".
69+
70+
### Key material
71+
72+
The repository contains two sets of keys:
73+
74+
- **`modules/secureboot/keys/`** — Production certificates generated from a
75+
NetHSM. Contains only `.crt` and `.auth` files (public material).
76+
77+
- **`modules/secureboot/dev-keys/`** — Self-signed development keys for testing.
78+
Contains both `.crt` (public) and `.key` (private) files. These keys are
79+
checked into the repository for convenience — they are explicitly **not secret**
80+
and must not be used in production.
81+
82+
### Configuration
83+
84+
Secure Boot is enabled by default for Orin targets via `jetson-orin.nix`:
85+
86+
```nix
87+
ghaf.hardware.nvidia.orin.secureboot.enable = lib.mkDefault true;
88+
```
89+
90+
The Orin profile overrides the enrollment certificates to use dev keys:
91+
92+
```nix
93+
ghaf.hardware.nvidia.orin.secureboot.keysSource = lib.mkDefault ../secureboot/dev-keys;
94+
```
95+
96+
Available options:
97+
98+
| Option | Description |
99+
|--------|-------------|
100+
| `ghaf.hardware.nvidia.orin.secureboot.enable` | Enable/disable UEFI Secure Boot key enrollment |
101+
| `ghaf.hardware.nvidia.orin.secureboot.keysSource` | Directory with `PK.crt`, `KEK.crt`, `db.crt` for enrollment |
102+
| `ghaf.hardware.nvidia.orin.secureboot.signingKeyDir` | Directory with `db.key` and `db.crt` for flash-time signing |
103+
104+
### Flashing with Secure Boot
105+
106+
The flash script reads the signing key from `SECURE_BOOT_SIGNING_KEY_DIR` (or
107+
falls back to the `signingKeyDir` option). Since private keys are not copied into
108+
the Nix store, you must point the environment variable to the working tree:
53109

54110
```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"
111+
# Build the flash script
112+
nix build .#nvidia-jetson-orin-agx-verity-debug-from-x86_64-flash-script
113+
114+
# Flash with dev keys (device must be in recovery mode)
115+
sudo SECURE_BOOT_SIGNING_KEY_DIR=$PWD/modules/secureboot/dev-keys \
116+
./result/bin/flash-ghaf-host
57117
```
58118

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.
119+
The flash script will:
120+
1. Sign `BOOTAA64.efi` and the UKI with the db key
121+
2. Build the ESP FAT image with the signed binaries
122+
3. Flash QSPI firmware (with key enrollment DTB overlay) and eMMC partitions
60123

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.
124+
### Production key workflow
125+
126+
For production builds, replace the key material:
127+
128+
1. Generate production PK/KEK/db certificates (e.g., from a Hardware Security
129+
Module).
130+
2. Set `keysSource` to the directory containing the production `.crt` files.
131+
3. At flash time, set `SECURE_BOOT_SIGNING_KEY_DIR` to a directory containing
132+
the production `db.key` and `db.crt` (e.g., from an HSM-backed PKCS#11
133+
token or a secure build machine).
134+
135+
```nix
136+
ghaf.hardware.nvidia.orin.secureboot = {
137+
keysSource = /path/to/production/certs; # PK.crt, KEK.crt, db.crt
138+
signingKeyDir = "/secure/signing/keys"; # db.key, db.crt (runtime path)
139+
};
140+
```
62141

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:
142+
### Verification
143+
144+
After flashing and booting, verify Secure Boot is active:
64145

65146
```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
147+
# Check UEFI variables
148+
efi-readvar
149+
150+
# Check boot status
151+
bootctl status | head -10
152+
# Should show: Secure Boot: enabled (user)
153+
154+
# Check SetupMode is off (enforcing)
155+
hexdump -C /sys/firmware/efi/efivars/SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c
156+
# Last byte should be 00 (not in setup mode)
74157
```
75158

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.
159+
### Generating new dev keys
160+
161+
To regenerate the development keys:
162+
163+
```sh
164+
cd modules/secureboot/dev-keys
165+
for name in PK KEK db; do
166+
openssl req -new -x509 -newkey rsa:2048 -nodes \
167+
-keyout "$name.key" -out "$name.crt" \
168+
-subj "/CN=Ghaf Dev Secure Boot $name/" -days 3650
169+
done
170+
```
77171

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.
172+
After regenerating, you must reflash the device for the new keys to take effect.

modules/profiles/orin.nix

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ in
216216
givc.enable = true;
217217
global-config.givc.enable = true;
218218

219+
# Use development keys for both enrollment and signing.
220+
# Production builds should override keysSource with the real
221+
# certs and set SECURE_BOOT_SIGNING_KEY_DIR to the HSM-backed
222+
# key directory at flash time.
223+
hardware.nvidia.orin.secureboot.keysSource = lib.mkDefault ../secureboot/dev-keys;
224+
219225
host.networking = {
220226
enable = true;
221227
};

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

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,58 @@ let
126126
# prevents flash.sh from rebuilding esp.img via create_espimage.
127127
export NO_ESP_IMG=0
128128
129-
echo "Decompressing pre-built ESP image..."
130-
"${pkgs.pkgsBuildBuild.zstd}/bin/zstd" -f -d "${verityImages}/esp.img.zst" -o "$WORKDIR/bootloader/esp.img"
129+
echo "Building ESP image..."
130+
_esp="$WORKDIR/bootloader/esp.img"
131+
_uki_name=$(cat "${verityImages}/esp-files/uki-filename")
132+
_uki_src="${verityImages}/esp-files/uki.efi"
133+
_boot_src="${verityImages}/esp-files/systemd-bootaa64.efi"
134+
135+
# Copy to writable tmp so we can sign in-place
136+
_sign_dir=$(mktemp -d)
137+
cp "$_boot_src" "$_sign_dir/BOOTAA64.efi"
138+
cp "$_uki_src" "$_sign_dir/$_uki_name"
139+
140+
# Sign EFI binaries if secure boot keys are available
141+
_sb_key_dir="''${SECURE_BOOT_SIGNING_KEY_DIR:-${
142+
if config.ghaf.hardware.nvidia.orin.secureboot.enable then
143+
config.ghaf.hardware.nvidia.orin.secureboot.signingKeyDir
144+
else
145+
""
146+
}}"
147+
if [ -n "$_sb_key_dir" ] && [ -f "$_sb_key_dir/db.key" ] && [ -f "$_sb_key_dir/db.crt" ]; then
148+
echo "Signing EFI binaries with $_sb_key_dir/db.crt ..."
149+
for _efi in "$_sign_dir"/*.efi; do
150+
echo " Signing: $(basename "$_efi")"
151+
"${pkgs.pkgsBuildBuild.sbsigntool}/bin/sbsign" \
152+
--key "$_sb_key_dir/db.key" --cert "$_sb_key_dir/db.crt" \
153+
--output "$_efi" "$_efi"
154+
done
155+
${
156+
if config.ghaf.hardware.nvidia.orin.secureboot.enable then
157+
''
158+
else
159+
echo "ERROR: Secure Boot is enabled but no signing keys found." >&2
160+
echo " Set SECURE_BOOT_SIGNING_KEY_DIR or place db.key + db.crt in:" >&2
161+
echo " $_sb_key_dir" >&2
162+
exit 1
163+
''
164+
else
165+
''
166+
else
167+
echo "Secure Boot signing skipped (no keys found)."
168+
''
169+
}
170+
fi
171+
172+
# Create 512M FAT32 ESP image
173+
"${pkgs.pkgsBuildBuild.dosfstools}/bin/mkfs.vfat" -F 32 -n ESP -C "$_esp" $((512 * 1024))
174+
"${pkgs.pkgsBuildBuild.mtools}/bin/mmd" -i "$_esp" ::EFI
175+
"${pkgs.pkgsBuildBuild.mtools}/bin/mmd" -i "$_esp" ::EFI/BOOT
176+
"${pkgs.pkgsBuildBuild.mtools}/bin/mmd" -i "$_esp" ::EFI/Linux
177+
"${pkgs.pkgsBuildBuild.mtools}/bin/mcopy" -i "$_esp" "$_sign_dir/BOOTAA64.efi" ::EFI/BOOT/BOOTAA64.efi
178+
"${pkgs.pkgsBuildBuild.mtools}/bin/mcopy" -i "$_esp" "$_sign_dir/$_uki_name" "::EFI/Linux/$_uki_name"
179+
rm -rf "$_sign_dir"
180+
echo "ESP image built: $_esp"
131181
132182
echo "Decompressing pre-built system (LVM) sparse image..."
133183
"${pkgs.pkgsBuildBuild.zstd}/bin/zstd" -f -d "${verityImages}/system.img.zst" -o "$WORKDIR/bootloader/system.img"

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors
22
# SPDX-License-Identifier: Apache-2.0
3-
3+
#
4+
# UEFI Secure Boot for Jetson Orin
5+
#
6+
# Enrolls PK/KEK/db keys into the firmware via a DTB overlay.
7+
# EFI binaries are signed at flash time by partition-template-verity.nix
8+
# using the db private key. Private keys never enter the Nix store.
49
{
510
config,
611
lib,
@@ -31,6 +36,19 @@ in
3136
default = ../../../../secureboot/keys;
3237
description = "Directory containing PK.crt, KEK.crt and db.crt used to generate ESLs.";
3338
};
39+
40+
signingKeyDir = lib.mkOption {
41+
type = lib.types.str;
42+
default = toString ../../../../secureboot/dev-keys;
43+
description = ''
44+
Path to directory containing db.key and db.crt for signing EFI
45+
binaries at flash time. This is intentionally a string (not a
46+
path) to avoid copying private keys into the Nix store.
47+
48+
Can be overridden at flash time via the SECURE_BOOT_SIGNING_KEY_DIR
49+
environment variable.
50+
'';
51+
};
3452
};
3553

3654
config = lib.mkIf cfg.enable {

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

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -32,43 +32,26 @@ let
3232
# ghaf_<ver>_<hash>.manifest — JSON manifest
3333
inherit (config.system.build) ghafImage;
3434

35-
espImage =
36-
pkgs.runCommand "esp-image"
37-
{
38-
nativeBuildInputs = with pkgs.buildPackages; [
39-
dosfstools
40-
mtools
41-
zstd
42-
];
43-
}
44-
''
45-
mkdir -p $out
46-
47-
# Find the UKI from ghafImage (built without .dtb, roothash patched)
48-
uki=$(find ${ghafImage} -name '*.efi' | head -1)
49-
if [ -z "$uki" ]; then
50-
echo "ERROR: No UKI (.efi) found in ghafImage output"
51-
ls -la ${ghafImage}/
52-
exit 1
53-
fi
54-
echo "Using UKI: $uki"
55-
56-
# Create 512M FAT32 image
57-
truncate -s 512M esp.img
58-
mkfs.vfat -F 32 -n ESP esp.img
59-
60-
# Install systemd-boot as BOOTAA64.efi
61-
boot_efi="${config.systemd.package}/lib/systemd/boot/efi/systemd-bootaa64.efi"
62-
mmd -i esp.img ::EFI
63-
mmd -i esp.img ::EFI/BOOT
64-
mmd -i esp.img ::EFI/Linux
65-
mcopy -i esp.img "$boot_efi" ::EFI/BOOT/BOOTAA64.efi
66-
67-
# Install UKI — auto-discovered by systemd-boot from EFI/Linux/
68-
mcopy -i esp.img "$uki" "::EFI/Linux/$(basename "$uki")"
69-
70-
zstd --compress esp.img -o $out/esp.img.zst
71-
'';
35+
# The ESP FAT image is built at flash time (not here) so that
36+
# EFI binaries can be signed with a private key that never enters
37+
# the Nix store. We only export the individual files needed.
38+
espFiles = pkgs.runCommand "esp-files" { } ''
39+
mkdir -p $out
40+
41+
# UKI (roothash-patched)
42+
uki=$(find ${ghafImage} -name '*.efi' | head -1)
43+
if [ -z "$uki" ]; then
44+
echo "ERROR: No UKI (.efi) found in ghafImage output"
45+
ls -la ${ghafImage}/
46+
exit 1
47+
fi
48+
ln -s "$uki" "$out/uki.efi"
49+
basename "$uki" > "$out/uki-filename"
50+
51+
# systemd-boot
52+
ln -s "${config.systemd.package}/lib/systemd/boot/efi/systemd-bootaa64.efi" \
53+
"$out/systemd-bootaa64.efi"
54+
'';
7255

7356
# LVM image: must be built in a VM because LVM needs block devices.
7457
# Reads the manifest from ghafImage to determine LV names, then writes
@@ -228,7 +211,7 @@ in
228211
config = lib.mkIf cfg.enable {
229212
system.build.verityImages = pkgs.runCommand "verity-images" { } ''
230213
mkdir -p $out
231-
ln -s ${espImage}/esp.img.zst $out/esp.img.zst
214+
ln -s ${espFiles} $out/esp-files
232215
ln -s ${lvmImage}/system.img.zst $out/system.img.zst
233216
ln -s ${lvmImage}/system.raw_size $out/system.raw_size
234217
'';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDJzCCAg+gAwIBAgIUKgZOKjCeExGRuKBKJUB3Xx3f8fgwDQYJKoZIhvcNAQEL
3+
BQAwIzEhMB8GA1UEAwwYR2hhZiBEZXYgU2VjdXJlIEJvb3QgS0VLMB4XDTI2MDIy
4+
NDE3NTUyMloXDTM2MDIyMjE3NTUyMlowIzEhMB8GA1UEAwwYR2hhZiBEZXYgU2Vj
5+
dXJlIEJvb3QgS0VLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoYiA
6+
bnOFBfPs03ajvbPRLP1KIEi6J8K8SGkA5Q6wIrezrYWRQTfGBcLhMOGjlTbfUyrf
7+
FFzdadMH2iPl3cuu1IfHk1O0S/+UPZrQ1xhiNvXYoxTJsq0rKWvcSPm2KjULUtcH
8+
/ZhWlZlZQKi80E8h/mDOr5BnOfLJ8D8BzxTan50V3iEjUpryxGG0iZzl8vElm4Kw
9+
DLfx8OFTr/VgTB/KvuUjZ98qeUJm0GIoTJN51KAXw8GsE9DIRTQo0oxqK1uVEse4
10+
MvV/IMCVqzVzP9ogfGFGEY3OWZ6XkmdM0EYFUjQQiz1+a0AthaxIPr0tqIcw7BzG
11+
0EVK7qMsSOfQl/xmSwIDAQABo1MwUTAdBgNVHQ4EFgQUDjNPiTHM6bFAfxOLr0hm
12+
8FlDFdswHwYDVR0jBBgwFoAUDjNPiTHM6bFAfxOLr0hm8FlDFdswDwYDVR0TAQH/
13+
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIhmQkI8Cl+kdEoCBOAHuEqP3/0wA
14+
YtDutO4tUw3tpS9RaFwzmTg7Ckf6IVTJTnxDkbqvbHtMIzLnWGEMT0j0JWQETuT0
15+
FLoE1AULwVxxCvE98EIOXzECtB0x5KLj+b5NTriCVfjUB+qRyp+BmcJKhwSiX690
16+
OzGrPDdAnIFacpUgcadqui/Wrh8MRhrQ80905Gpu2H5prPxP9eHbVQmFgT+B7QcE
17+
s6FsOJyby1jRsaKyp+3sgVaIKHAPp8Cj0ExNXRhSj/Wfv3tViY6ZDtCgk9knxHTI
18+
vfOw5iSoQ+FwLHf0XaW3M83unzVSoa+ybJJ5lBsD29RBmiF7zGK6E+U+vA==
19+
-----END CERTIFICATE-----
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors
2+
SPDX-License-Identifier: Apache-2.0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQChiIBuc4UF8+zT
3+
dqO9s9Es/UogSLonwrxIaQDlDrAit7OthZFBN8YFwuEw4aOVNt9TKt8UXN1p0wfa
4+
I+Xdy67Uh8eTU7RL/5Q9mtDXGGI29dijFMmyrSspa9xI+bYqNQtS1wf9mFaVmVlA
5+
qLzQTyH+YM6vkGc58snwPwHPFNqfnRXeISNSmvLEYbSJnOXy8SWbgrAMt/Hw4VOv
6+
9WBMH8q+5SNn3yp5QmbQYihMk3nUoBfDwawT0MhFNCjSjGorW5USx7gy9X8gwJWr
7+
NXM/2iB8YUYRjc5ZnpeSZ0zQRgVSNBCLPX5rQC2FrEg+vS2ohzDsHMbQRUruoyxI
8+
59CX/GZLAgMBAAECggEABQh1x/s9d9QD2wrlSzHhIJ+7wYnCkx6UM0ViS8DLaCmF
9+
JbD1t6x/NQq/bYB6UlnlV3gMf1vtYjC7G+bmcKS6C9E3PLXs9jk+azT5sNoHpWK/
10+
n0U0i6ato5rCwFtXe7UvZyNgEly+xeaDS2p2h58Plhd6GSpMrReNhzjPW55wuWxk
11+
53L6+sOLY5YJvsmC+3rQkf8NYfU7NR7qmmcpxU5xecnXrEXH5onE0lb6UtRTNVnn
12+
j/JY0wEr7a/Px9kmVnrQ7kOrK4iysVzYzpxfUpyEiCbdDo3exfq+g9nNxqaxmZRW
13+
4OYbkW+6gonfthGw9PKrJxJgZYnURTBA0nbaV/9WkQKBgQDO1c0qPrUn0VGaPcSx
14+
0g6m9huz+YkVtzZRqK/rpwLffZSriWGlseXfPpzFc8iG/QrzNQOMqtgU5bCT5Zlf
15+
JeXsnDwDxMKoa9gmyE6F8F9KCl6hukRlZPhRhTWiE16Yeo/E6CuTMVKdNclr1CHM
16+
gk+Jk7B+rZo3rYmumYJi2lrmJwKBgQDH7gPvVMWt+ScA3l3fweG8edJgfit0YIQt
17+
vdXbYySX+3HiKogHHujFPIvifrKfY1pbPINaqim6STsvq+R6JKghLoJ/oBx+sPQy
18+
RswbUoI3ZUx1Bm8avs1ThEDB/8qPKKL7/7fYuqSbT5ZbC2cZG7vHOKOCkTbCI7Kw
19+
PlsMGTBZPQKBgDX69qCf3QeXSYTHuh3uhIRulqxR48UXG8YUEFWgMM/DJpneMO3d
20+
j/DDloaxwRP51nHC1DpSHDLX/02aDn0Wlvs5izAwmdz6yF7WyCeMpFHegvQSeOc9
21+
gtFDwsuZ4oZI9lyde0HfDYCaGQdbRbbqC3gMY3OsOyNs1xIKXk0OT8rhAoGAfivg
22+
Qda+1hcJnUu39HD306kRsiGNrOkIIZHO95/uxRdC/JcYt12zSl32bZ7FfT8HE9Lx
23+
lnMS2GREvMX+73JYxHAEnSRfNzjXMy9oucltMiZ0hNnlnfxRueYZtBSIMaZUjTIJ
24+
RPYs0XL9kUF18+uDqqs8zTZ1VzmOGBmR/eWblIUCgYAHOewawwwxFxCxRDjjMdOM
25+
APweu1nzcFBs3VyvYTYSK0J9T/qN9uA/h72IyRFxDEW1yBbMyhbS3gE9d6LAoaO6
26+
LNgsVj2mRUduTp0vHGtLimqLzOGy96IgFErYQFtbY1DrbgfEhDgu8JmGBJ8g3SAz
27+
6JK2cy6SzW+pxV092xeJ4g==
28+
-----END PRIVATE KEY-----
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors
2+
SPDX-License-Identifier: Apache-2.0

0 commit comments

Comments
 (0)