return config.sign_expected_pcr == ConfigFeature.enabled or (
config.sign_expected_pcr == ConfigFeature.auto
and config.find_binary("systemd-measure", "/usr/lib/systemd/systemd-measure") is not None
+ and bool(config.sign_expected_pcr_key)
+ and bool(config.sign_expected_pcr_certificate)
)
arguments += ["--sign-kernel"]
- if want_signed_pcrs(context.config):
+ if want_signed_pcrs(context.config):
+ assert context.config.sign_expected_pcr_key
+ assert context.config.sign_expected_pcr_certificate
+ arguments += [
+ "--pcr-private-key", context.config.sign_expected_pcr_key,
+ # SHA1 might be disabled in OpenSSL depending on the distro so we opt to not sign
+ # for SHA1 to avoid having to manage a bunch of configuration to re-enable SHA1.
+ "--pcr-banks", "sha256",
+ ] # fmt: skip
+ if context.config.sign_expected_pcr_key.exists():
+ options += ["--bind", context.config.sign_expected_pcr_key, context.config.sign_expected_pcr_key]
+ if context.config.sign_expected_pcr_key_source.type == KeySourceType.engine:
arguments += [
- "--pcr-private-key", context.config.secure_boot_key,
- # SHA1 might be disabled in OpenSSL depending on the distro so we opt to not sign
- # for SHA1 to avoid having to manage a bunch of configuration to re-enable SHA1.
- "--pcr-banks", "sha256",
+ "--signing-engine", context.config.sign_expected_pcr_key_source.source,
+ "--pcr-public-key", context.config.sign_expected_pcr_certificate,
+ ] # fmt: skip
+ options += [
+ "--ro-bind",
+ context.config.sign_expected_pcr_certificate,
+ context.config.sign_expected_pcr_certificate,
+ "--bind-try", "/run/pcscd", "/run/pcscd",
] # fmt: skip
- if context.config.secure_boot_key.exists():
- options += ["--bind", context.config.secure_boot_key, context.config.secure_boot_key]
- if context.config.secure_boot_key_source.type == KeySourceType.engine:
- arguments += [
- "--signing-engine", context.config.secure_boot_key_source.source,
- "--pcr-public-key", context.config.secure_boot_certificate,
- ] # fmt: skip
- options += [
- "--ro-bind", context.config.secure_boot_certificate, context.config.secure_boot_certificate, # noqa
- "--bind-try", "/run/pcscd", "/run/pcscd",
- ] # fmt: skip
if microcodes:
# new .ucode section support?
if config.secure_boot and not config.secure_boot_key:
die(
"SecureBoot= is enabled but no secure boot key is configured",
- hint="Run mkosi genkey to generate a secure boot key/certificate pair",
+ hint="Run mkosi genkey to generate a key/certificate pair",
)
if config.secure_boot and not config.secure_boot_certificate:
die(
- "SecureBoot= is enabled but no secure boot key is configured",
- hint="Run mkosi genkey to generate a secure boot key/certificate pair",
+ "SecureBoot= is enabled but no secure boot certificate is configured",
+ hint="Run mkosi genkey to generate a key/certificate pair",
)
+ if config.sign_expected_pcr == ConfigFeature.enabled and not config.sign_expected_pcr_key:
+ die(
+ "SignExpectedPcr= is enabled but no private key is configured",
+ hint="Run mkosi genkey to generate a key/certificate pair",
+ )
+
+ if config.sign_expected_pcr == ConfigFeature.enabled and not config.sign_expected_pcr_certificate:
+ die(
+ "SignExpectedPcr= is enabled but no certificate is configured",
+ hint="Run mkosi genkey to generate a key/certificate pair",
+ )
+
+ if config.secure_boot_key_source != config.sign_expected_pcr_key_source:
+ die("Secure boot key source and expected PCR signatures key source have to be the same")
+
def check_tool(config: Config, *tools: PathString, reason: str, hint: Optional[str] = None) -> Path:
tool = config.find_binary(*tools)
verity_key_source: KeySource
verity_certificate: Optional[Path]
sign_expected_pcr: ConfigFeature
+ sign_expected_pcr_key: Optional[Path]
+ sign_expected_pcr_key_source: KeySource
+ sign_expected_pcr_certificate: Optional[Path]
passphrase: Optional[Path]
checksum: bool
sign: bool
help="Measure the components of the unified kernel image (UKI) and "
"embed the PCR signature into the UKI",
),
+ ConfigSetting(
+ dest="sign_expected_pcr_key",
+ metavar="KEY",
+ section="Validation",
+ parse=config_parse_key,
+ paths=("mkosi.key",),
+ help="Private key for signing expected PCR signature",
+ scope=SettingScope.universal,
+ ),
+ ConfigSetting(
+ dest="sign_expected_pcr_key_source",
+ section="Validation",
+ metavar="SOURCE[:ENGINE]",
+ parse=config_parse_key_source,
+ default=KeySource(type=KeySourceType.file),
+ help="The source to use to retrieve the expected PCR signing key",
+ scope=SettingScope.universal,
+ ),
+ ConfigSetting(
+ dest="sign_expected_pcr_certificate",
+ metavar="PATH",
+ section="Validation",
+ parse=config_make_path_parser(),
+ paths=("mkosi.crt",),
+ help="Certificate for signing expected PCR signature in X509 format",
+ scope=SettingScope.universal,
+ ),
ConfigSetting(
dest="passphrase",
metavar="PATH",
Verity Signing Key Source: {config.verity_key_source}
Verity Certificate: {none_to_none(config.verity_certificate)}
Sign Expected PCRs: {config.sign_expected_pcr}
+ Expected PCRs Signing Key: {none_to_none(config.sign_expected_pcr_key)}
+ Expected PCRs Key Source: {config.sign_expected_pcr_key_source}
+ Expected PCRs Certificate: {none_to_none(config.sign_expected_pcr_certificate)}
Passphrase: {none_to_none(config.passphrase)}
Checksum: {yes_no(config.checksum)}
Sign: {yes_no(config.sign)}
`systemd-measure` binary is in `PATH`. Depends on `SecureBoot=`
being enabled and key from `SecureBootKey=`.
+`SignExpectedPcrKey=`, `--sign-expected-pcr-key=`
+: Path to the PEM file containing the secret key for signing the expected PCR signatures.
+ When `SignExpectedPcrKeySource=` is specified, the input type depends on
+ the source.
+
+`SignExpectedPcrKeySource=`, `--sign-expected-key-source=`
+: Source of `VerityKey=`, to support OpenSSL engines. E.g.:
+ `--verity-key-source=engine:pkcs11`
+
+`SignExpectedPcrCertificate=`, `--sign-expected-pcr-certificate=`
+: Path to the X.509 file containing the certificate for signing the expected PCR signatures.
+
`Passphrase=`, `--passphrase`
: Specify the path to a file containing the passphrase to use for LUKS
encryption. It should contain the passphrase literally, and not end in
- `VerityCertificate=`
- `VerityKey=`
- `VerityKeySource=`
+- `SignExpectedPcrCertificate=`
+- `SignExpectedPcrKey=`
+- `SignExpectedPcrSource=`
- `VolatilePackageDirectories=`
- `WithNetwork=`
- `WithTests`
"ShimBootloader": "none",
"Sign": false,
"SignExpectedPcr": "disabled",
+ "SignExpectedPcrCertificate": "/my/cert",
+ "SignExpectedPcrKey": "/my/key",
+ "SignExpectedPcrKeySource": {
+ "Source": "",
+ "Type": "file"
+ },
"SkeletonTrees": [
{
"Source": "/foo/bar",
shim_bootloader=ShimBootloader.none,
sign=False,
sign_expected_pcr=ConfigFeature.disabled,
+ sign_expected_pcr_key=Path("/my/key"),
+ sign_expected_pcr_key_source=KeySource(type=KeySourceType.file),
+ sign_expected_pcr_certificate=Path("/my/cert"),
skeleton_trees=[ConfigTree(Path("/foo/bar"), Path("/")), ConfigTree(Path("/bar/baz"), Path("/qux"))],
source_date_epoch=12345,
split_artifacts=True,