The way that NvPCRs are initialized and anchored in systemd is changing,
and to support this, the UKI needs to include signed PCR policies that
can only be satisfied during the initrd, as these are used to authorize
NvPCR initialization. This is enabled with a new --sign-initrd-pcrs
option for ukify.
This adds a new "SignInitrdPCRs=" option to control this. The default is
"auto" which will turn on this option if PCR signing is enabled and
ukify is new enough.
The corresponding systemd PR is https://github.com/systemd/systemd/pull/42796
"--pcr-banks", "sha256",
] # fmt: skip
"--pcr-banks", "sha256",
] # fmt: skip
- if (
- systemd_tool_version(
- python_binary(context.config),
- ukify,
- sandbox=context.sandbox,
- )
- >= "258"
- ):
+ ukify_version = systemd_tool_version(python_binary(context.config), ukify, sandbox=context.sandbox)
+
+ if ukify_version >= "258":
cert_parameter = "--pcr-certificate"
else:
cert_parameter = "--pcr-public-key"
cert_parameter = "--pcr-certificate"
else:
cert_parameter = "--pcr-public-key"
+ if context.config.sign_initrd_pcrs == ConfigFeature.enabled or (
+ context.config.sign_initrd_pcrs == ConfigFeature.auto and ukify_version >= "262~devel"
+ ):
+ arguments += ["--sign-initrd-pcrs"]
+
# If we're providing the private key via an engine or provider, we have to pass in a X.509
# certificate via --pcr-certificate as well.
if context.config.sign_expected_pcr_key_source.type != KeySourceType.file:
# If we're providing the private key via an engine or provider, we have to pass in a X.509
# certificate via --pcr-certificate as well.
if context.config.sign_expected_pcr_key_source.type != KeySourceType.file:
hint="Run mkosi genkey to generate a key/certificate pair",
)
hint="Run mkosi genkey to generate a key/certificate pair",
)
+ if config.sign_initrd_pcrs == ConfigFeature.enabled and not want_signed_pcrs(config):
+ die("SignInitrdPCRs= is enabled but PCR signing is not enabled")
+
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")
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")
reason="sign PCR hashes with OpenSSL engine",
)
reason="sign PCR hashes with OpenSSL engine",
)
+ if config.sign_initrd_pcrs == ConfigFeature.enabled and want_signed_pcrs(config):
+ check_ukify(
+ config,
+ version="262~devel",
+ reason="sign a PCR policy for the initrd",
+ )
+
if config.verity_key_source.type != KeySourceType.file:
check_systemd_tool(
config,
if config.verity_key_source.type != KeySourceType.file:
check_systemd_tool(
config,
sign_expected_pcr_key_source: KeySource
sign_expected_pcr_certificate: Optional[Path]
sign_expected_pcr_certificate_source: CertificateSource
sign_expected_pcr_key_source: KeySource
sign_expected_pcr_certificate: Optional[Path]
sign_expected_pcr_certificate_source: CertificateSource
+ sign_initrd_pcrs: ConfigFeature
passphrase: Optional[Path]
checksum: bool
sign: bool
passphrase: Optional[Path]
checksum: bool
sign: bool
help="The source to use to retrieve the expected PCR signing certificate",
scope=SettingScope.inherit,
),
help="The source to use to retrieve the expected PCR signing certificate",
scope=SettingScope.inherit,
),
+ ConfigSetting(
+ dest="sign_initrd_pcrs",
+ metavar="FEATURE",
+ section="Validation",
+ name="SignInitrdPCRs",
+ parse=config_parse_feature,
+ help="Generate a signed PCR policy that can only be satisfied from the initrd and embed this into the UKI", # noqa: E501
+ ),
ConfigSetting(
dest="passphrase",
metavar="PATH",
ConfigSetting(
dest="passphrase",
metavar="PATH",
Expected PCRs Key Source: {config.sign_expected_pcr_key_source}
Expected PCRs Certificate: {none_to_none(config.sign_expected_pcr_certificate)}
Expected PCRs Certificate Source: {config.sign_expected_pcr_certificate_source}
Expected PCRs Key Source: {config.sign_expected_pcr_key_source}
Expected PCRs Certificate: {none_to_none(config.sign_expected_pcr_certificate)}
Expected PCRs Certificate Source: {config.sign_expected_pcr_certificate_source}
+ Sign initrd PCRs: {config.sign_initrd_pcrs}
Passphrase: {none_to_none(config.passphrase)}
Checksum: {yes_no(config.checksum)}
Sign: {yes_no(config.sign)}
Passphrase: {none_to_none(config.passphrase)}
Checksum: {yes_no(config.checksum)}
Sign: {yes_no(config.sign)}
`SignExpectedPcrCertificate=`, `--sign-expected-pcr-certificate=`
: Path to the X.509 file containing the certificate for signing the expected PCR signatures.
`SignExpectedPcrCertificate=`, `--sign-expected-pcr-certificate=`
: Path to the X.509 file containing the certificate for signing the expected PCR signatures.
+`SignInitrdPCRs=`, `--sign-initrd-pcrs=`
+: Whether to generate signed PCR policies that can only be satisfied from the
+ initrd. This is required for initialization of NvPCRs. This takes a boolean value
+ or the special value `auto`, which is the default and is equivalent to a true value
+ if PCR signing is enabled (see `SignExpectedPcr=`) and the version of **ukify** is
+ at least v262. Signing is performed with the key that is supplied to `SignExpectedPcrKey=`.
+
`SecureBootKeySource=`, `--secure-boot-key-source=`, `VerityKeySource=`, `--verity-key-source=`, `SignExpectedPcrKeySource=`, `--sign-expected-key-source=`
: The source of the corresponding private key, to support OpenSSL engines and providers,
e.g. `--secure-boot-key-source=engine:pkcs11` or `--secure-boot-key-source=provider:pkcs11`.
`SecureBootKeySource=`, `--secure-boot-key-source=`, `VerityKeySource=`, `--verity-key-source=`, `SignExpectedPcrKeySource=`, `--sign-expected-key-source=`
: The source of the corresponding private key, to support OpenSSL engines and providers,
e.g. `--secure-boot-key-source=engine:pkcs11` or `--secure-boot-key-source=provider:pkcs11`.
"Source": "",
"Type": "file"
},
"Source": "",
"Type": "file"
},
+ "SignInitrdPCRs": "disabled",
"SkeletonTrees": [
{
"Source": "/foo/bar",
"SkeletonTrees": [
{
"Source": "/foo/bar",
sign_expected_pcr_key_source=KeySource(type=KeySourceType.file),
sign_expected_pcr_key=Path("/my/key"),
sign_expected_pcr=ConfigFeature.disabled,
sign_expected_pcr_key_source=KeySource(type=KeySourceType.file),
sign_expected_pcr_key=Path("/my/key"),
sign_expected_pcr=ConfigFeature.disabled,
+ sign_initrd_pcrs=ConfigFeature.disabled,
sign=False,
skeleton_trees=[ConfigTree(Path("/foo/bar"), Path("/")), ConfigTree(Path("/bar/baz"), Path("/qux"))],
snapshot="snapshot",
sign=False,
skeleton_trees=[ConfigTree(Path("/foo/bar"), Path("/")), ConfigTree(Path("/bar/baz"), Path("/qux"))],
snapshot="snapshot",