fi
fi
done < <(find hashes/ukis hashes/kernels -type f \( -name '*efi.sig' -o -name 'vmlinu*.sig' \) -printf '%P\n')
-rm -rf nss-db "$OUTPUTDIR"/*.sig hashes/ukis
+rm -rf "$OUTPUTDIR"/*.sig hashes/ukis
+
+# If there are signed bootloaders, install them in the ESP
+while read -r BOOTLOADER; do
+ unsigned="$(basename "${BOOTLOADER%.sig}")"
+ signed="$(basename "${BOOTLOADER%.sig}".signed)"
+ ddi="${OUTPUTDIR}/${BOOTLOADER%%/*}"
+ # remove leading directory from BOOTLOADER
+ dest="${BOOTLOADER#*/}"
+ dest="${dest%.sig}"
+
+ if [ -f "${ddi}.zst" ]; then
+ unzstd "${ddi}.zst"
+ fi
+
+ offset="$(systemd-repart --json=short "$ddi" | jq -r '.[] | select(.type == "esp") | .offset')"
+ if [ -z "$offset" ] || [ "$offset" = "null" ]; then
+ if [ -f "$ddi.zst" ]; then
+ rm -f "$ddi"
+ fi
+ continue
+ fi
+
+ rm -f "$unsigned"
+ mcopy -i "${ddi}@@${offset}" "::$dest" "$unsigned"
+
+ # ensure the EFI hash matches before and after attaching the signature
+ old_hash=$(pesign -n sql:"$nss_db" -h -P -i "$unsigned" | cut -d' ' -f1)
+
+ pesign -n sql:"$nss_db" --force -c cert -i "$unsigned" -o "$signed" -d sha256 -I "hashes/bootloaders/${BOOTLOADER%.sig}" -R "hashes/bootloaders/${BOOTLOADER}"
+
+ new_hash=$(pesign -n sql:"$nss_db" -h -i "$signed" | cut -d' ' -f1)
+ if [ "$old_hash" != "$new_hash" ]; then
+ echo "Pesign hash mismatch error: $old_hash $new_hash"
+ exit 1
+ fi
+
+ mcopy -o -i "${ddi}@@${offset}" "$signed" "::$dest"
+
+ if [ -f "${ddi}.zst" ]; then
+ zstd --force "$ddi"
+ rm -f "$ddi"
+ fi
+done < <(find "hashes/bootloaders/$(basename "$ddi")/" -type f -iname '*.efi.sig' -printf '%P\n')
+rm -rf hashes/bootloaders
+rm -rf nss-db
# Second step: if there are PCR policy signatures, rebuild the JSON
# blobs with the attached signatures
mapfile -t KERNELS < <(find "$OUTPUTDIR" -type f -name "vmlinu*" -printf '%P\n')
declare -a ROOTHASHES
mapfile -t ROOTHASHES < <(find "$OUTPUTDIR" -type f -name "*.roothash" -printf '%P\n')
+declare -a DDIS
+mapfile -t DDIS < <(find "$OUTPUTDIR" -type f -name "*.raw*")
-if ((${#UKIS[@]} == 0)) && ((${#KERNELS[@]} == 0)) && ((${#ROOTHASHES[@]} == 0)); then
+if ((${#UKIS[@]} == 0)) && ((${#KERNELS[@]} == 0)) && ((${#ROOTHASHES[@]} == 0)) && ((${#DDIS[@]} == 0)); then
echo "No unsigned files found, exiting"
exit 0
fi
fi
done
+# Handle bootloaders separately from UKIs
+for ddi in "${DDIS[@]}"; do
+ test -f "$ddi" || continue
+ if [[ $ddi == *.zst ]]; then
+ unzstd "${ddi}"
+ fi
+ offset="$(systemd-repart --json=short "${ddi%.zst}" | jq -r '.[] | select(.type == "esp") | .offset')"
+ if [ "$offset" = "null" ]; then
+ if [[ $ddi == *.zst ]]; then
+ rm -f "${ddi%.zst}"
+ fi
+ continue
+ fi
+
+ rm -rf EFI
+ mcopy -s -i "${ddi%.zst}@@${offset}" ::EFI EFI || true
+ find EFI
+
+ # UKIs are handled separately
+ rm -rf EFI/Linux
+
+ while read -r BOOTLOADER; do
+ mkdir -p "hashes/bootloaders/$(basename "${ddi%.zst}")/$(dirname "$BOOTLOADER")"
+ pesign --force -n sql:"$nss_db" -i "$BOOTLOADER" -E "hashes/bootloaders/$(basename "${ddi%.zst}")/$BOOTLOADER"
+ done < <(find EFI -type f -iname '*.efi')
+
+ if [[ $ddi == *.zst ]]; then
+ rm -f "${ddi%.zst}"
+ fi
+ rm -rf EFI
+done
+
# Pack everything into a CPIO archive and place it where OBS expects it
pushd hashes
find . -type f | cpio -H newc -o >"$OUTPUTDIR/hashes.cpio.rsasign"