Skip to content

Commit

Permalink
Merge pull request #3466 from DaanDeMeyer/extension-repart-definitions
Browse files Browse the repository at this point in the history
Extend Verity= to support hash-only verity and deferred verity-sig
  • Loading branch information
bluca authored Feb 5, 2025
2 parents 399c8a1 + 1f60496 commit 4f74274
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 22 deletions.
35 changes: 28 additions & 7 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
SecureBootSignTool,
ShimBootloader,
Verb,
Verity,
Vmm,
cat_config,
format_bytes,
Expand Down Expand Up @@ -2603,13 +2604,13 @@ def check_inputs(config: Config) -> None:
"Secure boot certificate source and expected PCR signatures certificate source have to be the same" # noqa: E501
) # fmt: skip

if config.verity == ConfigFeature.enabled and not config.verity_key:
if config.verity == Verity.signed and not config.verity_key:
die(
"Verity= is enabled but no verity key is configured",
hint="Run mkosi genkey to generate a key/certificate pair",
)

if config.verity == ConfigFeature.enabled and not config.verity_certificate:
if config.verity == Verity.signed and not config.verity_certificate:
die(
"Verity= is enabled but no verity certificate is configured",
hint="Run mkosi genkey to generate a key/certificate pair",
Expand Down Expand Up @@ -3257,7 +3258,7 @@ def make_image(
partitions = [Partition.from_dict(d) for d in output]
arch = context.config.architecture

if context.config.verity == ConfigFeature.enabled and not any(
if context.config.verity == Verity.signed and not any(
p.type.startswith(f"usr-{arch}-verity-sig") or p.type.startswith(f"root-{arch}-verity-sig")
for p in partitions
):
Expand All @@ -3275,8 +3276,8 @@ def make_image(


def want_verity(config: Config) -> bool:
return config.verity == ConfigFeature.enabled or bool(
config.verity == ConfigFeature.auto and config.verity_key and config.verity_certificate
return config.verity == Verity.signed or bool(
config.verity == Verity.auto and config.verity_key and config.verity_certificate
)


Expand Down Expand Up @@ -3352,6 +3353,13 @@ def make_disk(

definitions = [defaults]

if context.config.verity == Verity.defer:
skip = [
*skip,
f"root-{context.config.architecture}-verity-sig",
f"usr-{context.config.architecture}-verity-sig",
]

return make_image(
context,
msg=msg,
Expand Down Expand Up @@ -3509,7 +3517,11 @@ def make_esp(context: Context, uki: Path) -> list[Partition]:


def make_extension_or_portable_image(context: Context, output: Path) -> None:
unsigned = "-unsigned" if not want_verity(context.config) else ""
if want_verity(context.config) or context.config.verity == Verity.signed:
unsigned = ""
else:
unsigned = "-unsigned"

r = context.resources / f"repart/definitions/{context.config.output_format}{unsigned}.repart.d"

cmdline: list[PathString] = [
Expand Down Expand Up @@ -3544,6 +3556,15 @@ def make_extension_or_portable_image(context: Context, output: Path) -> None:
if ArtifactOutput.partitions in context.config.split_artifacts:
cmdline += ["--split=yes"]

verity = [
f"root-{context.config.architecture}-verity-sig",
f"usr-{context.config.architecture}-verity-sig",
]
if context.config.verity == Verity.hash:
cmdline += [f"--exclude-partitions={','.join(verity)}"]
elif context.config.verity == Verity.defer:
cmdline += [f"--defer-partitions={','.join(verity)}"]

with complete_step(f"Building {context.config.output_format} extension image"):
j = json.loads(
run_systemd_sign_tool(
Expand Down Expand Up @@ -4389,7 +4410,7 @@ def validate_certificates_and_keys(config: Config) -> None:
if not keyutil:
return

if config.verity != ConfigFeature.disabled and config.verity_certificate and config.verity_key:
if config.verity != Verity.disabled and config.verity_certificate and config.verity_key:
run_systemd_sign_tool(
config,
cmdline=[keyutil, "validate"],
Expand Down
15 changes: 13 additions & 2 deletions mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,14 @@ def __bool__(self) -> bool:
return self != BuildSourcesEphemeral.no


class Verity(StrEnum):
disabled = enum.auto()
hash = enum.auto()
signed = enum.auto()
defer = enum.auto()
auto = enum.auto()


class Architecture(StrEnum):
alpha = enum.auto()
arc = enum.auto()
Expand Down Expand Up @@ -1872,7 +1880,7 @@ class Config:
secure_boot_certificate: Optional[Path]
secure_boot_certificate_source: CertificateSource
secure_boot_sign_tool: SecureBootSignTool
verity: ConfigFeature
verity: Verity
verity_key: Optional[Path]
verity_key_source: KeySource
verity_certificate: Optional[Path]
Expand Down Expand Up @@ -3034,7 +3042,9 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple
dest="verity",
section="Validation",
metavar="FEATURE",
parse=config_parse_feature,
parse=config_make_enum_parser_with_boolean(Verity, yes=Verity.signed, no=Verity.disabled),
default=Verity.auto,
choices=Verity.values(),
help="Configure whether to enforce or disable verity partitions for disk images",
),
ConfigSetting(
Expand Down Expand Up @@ -5171,6 +5181,7 @@ def uki_profile_transformer(
list[ArtifactOutput]: enum_list_transformer,
CertificateSource: certificate_source_transformer,
ConsoleMode: enum_transformer,
Verity: enum_transformer,
}

def json_transformer(key: str, val: Any) -> Any:
Expand Down
25 changes: 14 additions & 11 deletions mkosi/resources/man/mkosi.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -1140,19 +1140,22 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
available, with **systemd-sbsign** being preferred.

`Verity=`, `--verity=`
: Whether to enforce or disable signed verity for extension images.
Takes a boolean value or `auto`. If enabled, a verity key and
certificate must be present and the build will fail if we don't
detect any verity partitions in the disk image produced by
**systemd-repart**. If disabled, verity partitions will be excluded from
the extension images produced by **systemd-repart**. If set to `auto` and
a verity key and certificate are present, **mkosi** will pass them to systemd-repart
and expects the generated disk image to contain verity partitions,
but the build won't fail if no verity partitions are found in the
: Whether to enforce or disable verity for extension images. Takes one of
`signed`, `hash`, `defer`, `auto` or a boolean value. If set to `signed`,
a verity key and certificate must be present and the build will fail if
we don't detect any verity partitions in the disk image produced by
**systemd-repart**. If disabled, verity partitions will be excluded
from the extension images produced by **systemd-repart**. If set to
`hash`, **mkosi** configures **systemd-repart** to create a verity hash
partition, but no signature partition. If set to `defer`, space for the verity
sig partition will be allocated but it will not be populated yet. If set to
`auto` and a verity key and certificate are present, **mkosi** will pass them
to **systemd-repart** and expects the generated disk image to contain verity
partitions, but the build won't fail if no verity partitions are found in the
disk image produced by **systemd-repart**.

Note that explicitly disabling signed verity is not yet implemented
for the `disk` output and only works for extension images at the
Note that explicitly disabling verity signature and/or hash is not yet
implemented for the `disk` output and only works for extension images at the
moment.

`VerityKey=`, `--verity-key=`
Expand Down
10 changes: 10 additions & 0 deletions mkosi/resources/man/mkosi.news.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

# mkosi Changelog

## v26

- Teach `--verity` a new `hash` value, which skips the verity signature
partition for extension / portable images. To align the possible values,
`yes` is renamed to `signed`.
- Teach `--verity` a new `defer` value, which defers creation of the
verity signature partition for disk, extension and portable images (but
still allocates space for it). This is useful to implement offline
signing of the verity roothash.

## v25

- Instead of using bubblewrap, sandboxing is now done with a new tool
Expand Down
5 changes: 3 additions & 2 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
ShimBootloader,
UKIProfile,
Verb,
Verity,
Vmm,
VsockCID,
)
Expand Down Expand Up @@ -388,7 +389,7 @@ def test_config() -> None:
"UseSubvolumes": "auto",
"VSock": "enabled",
"VSockCID": -2,
"Verity": "enabled",
"Verity": "signed",
"VerityCertificate": "/path/to/cert",
"VerityCertificateSource": {
"Source": "",
Expand Down Expand Up @@ -575,7 +576,7 @@ def test_config() -> None:
verity_certificate=Path("/path/to/cert"),
verity_key_source=KeySource(type=KeySourceType.file),
verity_key=None,
verity=ConfigFeature.enabled,
verity=Verity.signed,
vmm=Vmm.qemu,
volatile_package_directories=[Path("def")],
volatile_packages=["abc"],
Expand Down

0 comments on commit 4f74274

Please sign in to comment.