Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bluca committed Jan 20, 2025
1 parent dfebb8e commit 5bf44db
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 14 deletions.
30 changes: 25 additions & 5 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,7 @@ def run_ukify(
arguments: Sequence[PathString] = (),
options: Sequence[PathString] = (),
sign: bool = True,
) -> None:
) -> str:
ukify = context.config.find_binary("ukify", "/usr/lib/systemd/ukify")
if not ukify:
die("Could not find ukify")
Expand Down Expand Up @@ -1590,20 +1590,23 @@ def run_ukify(
else:
cmd += ["--secureboot-certificate", context.config.secure_boot_certificate]

run(
result = run(
cmd,
stdin=(
sys.stdin
if context.config.secure_boot_key_source.type != KeySourceType.file
else subprocess.DEVNULL
),
stdout=subprocess.PIPE,
env=context.config.environment,
sandbox=context.sandbox(
options=[*opt, *options],
devices=context.config.secure_boot_key_source.type != KeySourceType.file,
),
)

return result.stdout.strip()


def build_uki(
context: Context,
Expand All @@ -1615,7 +1618,7 @@ def build_uki(
cmdline: Sequence[str],
profiles: Sequence[Path],
output: Path,
) -> None:
) -> Union[str, None]:
if not (ukify := context.config.find_binary("ukify", "/usr/lib/systemd/ukify")):
die("Could not find ukify")

Expand Down Expand Up @@ -1686,6 +1689,19 @@ def build_uki(
] # fmt: skip
else:
arguments += ["--pcr-private-key", context.config.sign_expected_pcr_key]
elif ArtifactOutput.pcrs in context.config.split_artifacts:
assert context.config.sign_expected_pcr_certificate

arguments += [
"--json=short",
"--policy-digests",
"--pcr-public-key", workdir(context.config.sign_expected_pcr_certificate),
# As above
"--pcr-banks", "sha256",
] # fmt: skip
options += [
"--ro-bind", context.config.sign_expected_pcr_certificate, workdir(context.config.sign_expected_pcr_certificate), # noqa: E501
] # fmt: skip

if microcodes:
# new .ucode section support?
Expand All @@ -1710,7 +1726,7 @@ def build_uki(
options += ["--ro-bind", initrd, workdir(initrd)]

with complete_step(f"Generating unified kernel image for kernel version {kver}"):
run_ukify(context, stub, output, cmdline=cmdline, arguments=arguments, options=options)
return run_ukify(context, stub, output, cmdline=cmdline, arguments=arguments, options=options)


def systemd_stub_binary(context: Context) -> Path:
Expand Down Expand Up @@ -2147,7 +2163,7 @@ def make_uki(
)

initrds = [context.workspace / "initrd"]
build_uki(
pcrs = build_uki(
context,
stub,
kver,
Expand All @@ -2165,6 +2181,10 @@ def make_uki(
if ArtifactOutput.initrd in context.config.split_artifacts:
extract_pe_section(context, output, ".initrd", context.staging / context.config.output_split_initrd)

if ArtifactOutput.pcrs in context.config.split_artifacts:
with open(context.staging / context.config.output_split_pcrs, "w") as f:
f.write(pcrs)


def make_addon(context: Context, stub: Path, output: Path) -> None:
make_cpio(context.root, context.workspace / "initrd", sandbox=context.sandbox)
Expand Down
6 changes: 6 additions & 0 deletions mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ class ArtifactOutput(StrEnum):
kernel = enum.auto()
initrd = enum.auto()
partitions = enum.auto()
pcrs = enum.auto()

@staticmethod
def compat_no() -> list["ArtifactOutput"]:
Expand Down Expand Up @@ -1998,6 +1999,10 @@ def output_split_kernel(self) -> str:
def output_split_initrd(self) -> str:
return f"{self.output}.initrd"

@property
def output_split_pcrs(self) -> str:
return f"{self.output}.pcrs"

@property
def output_nspawn_settings(self) -> str:
return f"{self.output}.nspawn"
Expand Down Expand Up @@ -2027,6 +2032,7 @@ def outputs(self) -> list[str]:
self.output_split_uki,
self.output_split_kernel,
self.output_split_initrd,
self.output_split_pcrs,
self.output_nspawn_settings,
self.output_checksum,
self.output_signature,
Expand Down
54 changes: 52 additions & 2 deletions mkosi/resources/mkosi-obs/mkosi.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ if [ ! -f /usr/src/packages/SOURCES/mkosi.cpio.rsasign.sig ]; then
exit 0
fi

cpio -t < /usr/src/packages/SOURCES/mkosi.cpio.rsasign.sig
mkdir -p hashes
pushd hashes
cpio -idm < /usr/src/packages/SOURCES/mkosi.cpio.rsasign.sig
popd

OUTPUTDIR=/work/src/usr/src/packages/OTHER

Expand Down Expand Up @@ -52,5 +56,51 @@ do
fi

rm -f "$(basename "${infile}").sattrs" "$SIG" "$infile"
done < <(find . -type f \( -name '*efi.sig' -o -name 'vmlinu*.sig' \) -printf '%P\n')
rm -rf nss-db "$OUTPUTDIR"/*.sig
done < <(find hashes/ukis -type f \( -name '*efi.sig' -o -name 'vmlinu*.sig' \) -printf '%P\n')
rm -rf nss-db "$OUTPUTDIR"/*.sig hashes/ukis

Check warning

Code scanning / shellcheck

SC2046 Warning

Quote this to prevent word splitting.

Check warning

Code scanning / shellcheck

SC2086 Warning

Double quote to prevent globbing and word splitting.

Check warning

Code scanning / shellcheck

SC2086 Warning

Double quote to prevent globbing and word splitting.
while read -r SIG
do
uki="$OUTPUTDIR/$(basename $(dirname ${SIG%.sig}))"
pcrs="${uki%.efi}.pcrs"
pol="$(basename ${SIG%.sig})"

test -f "${pcrs}"

jq --arg pol "$pol" --arg sig "$(base64 -w0 < "$SIG")" '
to_entries | map(
.value |= map(
if .pol == $pol then
.sig = $sig
else
.
end
)
) | from_entries
' "${pcrs}" > "${pcrs}.new"
mv "${pcrs}.new" "${pcrs}"

rm -f "$SIG"
done < <(find hashes/pcrs -type f -name '*.sig')
rm -rf hashes/pcrs

mkdir -p "$nss_db"
certutil -N -d sql:"$nss_db" --empty-password

while read -r PCRS
do
uki="${PCRS%.pcrs}.efi"
# Attach the content of the PCRS file to the uki with objcopy in a .pcrsig section
objcopy --add-section .pcrsig="$PCRS" "$uki" "$uki"
mkdir -p hashes/ukis
pesign --force -n sql:"$nss_db" -i "$uki" -E "hashes/ukis/$f"

Check warning

Code scanning / shellcheck

SC2154 Warning

f is referenced but not assigned.
done < <(find "$OUTPUTDIR" -type f -name '*.pcrs')
rm -f "$OUTPUTDIR"/*.pcrs**

# pack everything into a CPIO archive and place it where OBS expects it for the 3rd stage
if [ -d hashes/ukis ]; then
pushd hashes
find . -type f | cpio -H newc -o > "$OUTPUTDIR/mkosi.cpio.rsasign"
popd
fi
rm -rf hashes "$nss_db"
6 changes: 6 additions & 0 deletions mkosi/resources/mkosi-obs/mkosi.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Build]
SandboxTrees=/usr/src/packages/SOURCES:/usr/src/packages/SOURCES

[Output]
SplitArtifacts=pcrs

[Validation]
SignExpectedPcrCertificate=/usr/src/packages/SOURCES/_projectcert.crt
20 changes: 13 additions & 7 deletions mkosi/resources/mkosi-obs/mkosi.postoutput
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
set -e
set -x

if [ -f /usr/src/packages/SOURCES/mkosi.cpio.rsasign.sig ]; then
exit 0
fi

nss_db="$PWD/nss-db"
# certutil will fail if it's called twice
rm -rf "$nss_db"
Expand All @@ -25,15 +21,25 @@ UNSIGNED=( "$(find "$OUTPUTDIR" -type f \( -name "*.efi" -o -name "vmlinu*" \) -

for f in "${UNSIGNED[@]}"
do
pesign --force -n sql:"$nss_db" -i "$OUTPUTDIR/$f" -E "hashes/$f"
if ukify --json=short inspect "${OUTPUTDIR}/${f}" | jq -e 'has(".linux")' > /dev/null && \
! ukify --json=short inspect "${OUTPUTDIR}/${f}" | jq -e 'has(".pcrsig")' > /dev/null; then
mkdir -p "hashes/pcrs/$f"
cat "${OUTPUTDIR}/${f%.efi}.pcrs" | jq -r 'to_entries[] | .value[].pol' | while read -r pol; do

Check warning

Code scanning / shellcheck

SC2002 Warning

Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
echo -n "$pol" | base64 --decode > "hashes/pcrs/${f}/${pol}"
done
else
mkdir -p hashes/ukis
pesign --force -n sql:"$nss_db" -i "${OUTPUTDIR}/${f}" -E "hashes/ukis/$f"
fi
done
rm -rf "$nss_db"

# pack everything into a CPIO archive and place it where OBS expects it
pushd hashes
find . -type f | cpio -H newc -o > "$OUTPUTDIR/mkosi.cpio.rsasign"
popd
rm -rf hashes
rm -rf hashes "$nss_db"

cpio -t < "$OUTPUTDIR/mkosi.cpio.rsasign"

cat <<EOF >"$OUTPUTDIR/mkosi.conf"
[Distribution]
Expand Down

0 comments on commit 5bf44db

Please sign in to comment.