diff mbox series

dm verity: add support for signature verification with platform keyring

Message ID 20240617220037.594792-1-luca.boccassi@gmail.com (mailing list archive)
State Accepted, archived
Delegated to: Mikulas Patocka
Headers show
Series dm verity: add support for signature verification with platform keyring | expand

Commit Message

Luca Boccassi June 17, 2024, 10 p.m. UTC
From: Luca Boccassi <bluca@debian.org>

Add a new configuration CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
that enables verifying dm-verity signatures using the platform keyring,
which is populated using the UEFI DB certificates. This is useful for
self-enrolled systems that do not use MOK, as the secondary keyring which
is already used for verification, if the relevant kconfig is enabled, is
linked to the machine keyring, which gets its certificates loaded from MOK.
On datacenter/virtual/cloud deployments it is more common to deploy one's
own certificate chain directly in DB on first boot in unattended mode,
rather than relying on MOK, as the latter typically requires interactive
authentication to enroll, and is more suited for personal machines.

Default to the same value as DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
if not otherwise specified, as it is likely that if one wants to use
MOK certificates to verify dm-verity volumes, DB certificates are
going to be used too. Keys in DB are allowed to load a full kernel
already anyway, so they are already highly privileged.

Signed-off-by: Luca Boccassi <bluca@debian.org>
---
 drivers/md/Kconfig                | 10 ++++++++++
 drivers/md/dm-verity-verify-sig.c |  7 +++++++
 2 files changed, 17 insertions(+)

Comments

Luca Boccassi July 4, 2024, 9:12 a.m. UTC | #1
On Mon, 17 Jun 2024 at 23:00, <luca.boccassi@gmail.com> wrote:
>
> From: Luca Boccassi <bluca@debian.org>
>
> Add a new configuration CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> that enables verifying dm-verity signatures using the platform keyring,
> which is populated using the UEFI DB certificates. This is useful for
> self-enrolled systems that do not use MOK, as the secondary keyring which
> is already used for verification, if the relevant kconfig is enabled, is
> linked to the machine keyring, which gets its certificates loaded from MOK.
> On datacenter/virtual/cloud deployments it is more common to deploy one's
> own certificate chain directly in DB on first boot in unattended mode,
> rather than relying on MOK, as the latter typically requires interactive
> authentication to enroll, and is more suited for personal machines.
>
> Default to the same value as DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
> if not otherwise specified, as it is likely that if one wants to use
> MOK certificates to verify dm-verity volumes, DB certificates are
> going to be used too. Keys in DB are allowed to load a full kernel
> already anyway, so they are already highly privileged.
>
> Signed-off-by: Luca Boccassi <bluca@debian.org>
> ---
>  drivers/md/Kconfig                | 10 ++++++++++
>  drivers/md/dm-verity-verify-sig.c |  7 +++++++
>  2 files changed, 17 insertions(+)
>
> diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
> index 35b1080752cd..1e9db8e4acdf 100644
> --- a/drivers/md/Kconfig
> +++ b/drivers/md/Kconfig
> @@ -540,6 +540,16 @@ config DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
>
>           If unsure, say N.
>
> +config DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> +       bool "Verity data device root hash signature verification with platform keyring"
> +       default DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
> +       depends on DM_VERITY_VERIFY_ROOTHASH_SIG
> +       depends on INTEGRITY_PLATFORM_KEYRING
> +       help
> +         Rely also on the platform keyring to verify dm-verity signatures.
> +
> +         If unsure, say N.
> +
>  config DM_VERITY_FEC
>         bool "Verity forward error correction support"
>         depends on DM_VERITY
> diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
> index 4836508ea50c..d351d7d39c60 100644
> --- a/drivers/md/dm-verity-verify-sig.c
> +++ b/drivers/md/dm-verity-verify-sig.c
> @@ -126,6 +126,13 @@ int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
>                                 NULL,
>  #endif
>                                 VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
> +#ifdef CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> +       if (ret == -ENOKEY)
> +               ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data,
> +                                       sig_len,
> +                                       VERIFY_USE_PLATFORM_KEYRING,
> +                                       VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
> +#endif
>
>         return ret;
>  }

Gentle ping. Anything I can do to help move this patch forward? It
fixes a gap in our dm-verity story that I'd really like to see sorted
for the next release. We will use this in systemd, among other things.
Thanks!
James Bottomley July 4, 2024, 3:21 p.m. UTC | #2
On Mon, 2024-06-17 at 23:00 +0100, luca.boccassi@gmail.com wrote:
> From: Luca Boccassi <bluca@debian.org>
> 
> Add a new configuration
> CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> that enables verifying dm-verity signatures using the platform
> keyring, which is populated using the UEFI DB certificates. This is
> useful for self-enrolled systems that do not use MOK, as the
> secondary keyring which is already used for verification, if the
> relevant kconfig is enabled, is linked to the machine keyring, which
> gets its certificates loaded from MOK. On datacenter/virtual/cloud
> deployments it is more common to deploy one's own certificate chain
> directly in DB on first boot in unattended mode, rather than relying
> on MOK, as the latter typically requires interactive authentication
> to enroll, and is more suited for personal machines.

I think that's true if you roll your own cloud OS.  If you rely on a
distro OS (as, say, IBM Cloud does) you do use shim/mok and actually
you als have to enroll all the driver module keys in MoK.

> Default to the same value as
> DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
> if not otherwise specified, as it is likely that if one wants to use
> MOK certificates to verify dm-verity volumes, DB certificates are
> going to be used too. Keys in DB are allowed to load a full kernel
> already anyway, so they are already highly privileged.

But there's a reason we allow mok users to distrust DB through mokutil.
It's because although you might be OK with these keys guarding the pre-
boot environment (because if they don't do that Microsoft will be
unhappy) and transferring control to SHIM via these keys, you wouldn't
necessarily trust the owner of these keys to tamper with your kernel or
install modules.  Doesn't a similar reasoning apply to dm-verity root
hash signing?

By the way, if I look at how the machine keyring is handled, db certs
won't get added if MokIgnoreDB is set by shim, so I think the behaviour
of this patch is correct, and it's just the wording above that may be
misleading.

James
Luca Boccassi July 4, 2024, 3:41 p.m. UTC | #3
On Thu, 4 Jul 2024 at 16:21, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Mon, 2024-06-17 at 23:00 +0100, luca.boccassi@gmail.com wrote:
> > From: Luca Boccassi <bluca@debian.org>
> >
> > Add a new configuration
> > CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> > that enables verifying dm-verity signatures using the platform
> > keyring, which is populated using the UEFI DB certificates. This is
> > useful for self-enrolled systems that do not use MOK, as the
> > secondary keyring which is already used for verification, if the
> > relevant kconfig is enabled, is linked to the machine keyring, which
> > gets its certificates loaded from MOK. On datacenter/virtual/cloud
> > deployments it is more common to deploy one's own certificate chain
> > directly in DB on first boot in unattended mode, rather than relying
> > on MOK, as the latter typically requires interactive authentication
> > to enroll, and is more suited for personal machines.
>
> I think that's true if you roll your own cloud OS.  If you rely on a
> distro OS (as, say, IBM Cloud does) you do use shim/mok and actually
> you als have to enroll all the driver module keys in MoK.

Yes, that is true, in many cases shim + 2nd stage is still used in
those environments. Perhaps a better use case I should have mentioned
is: this is also useful for those who self-enroll, and do not use
shim/mok at all. This is actually quite common, for example it's the
main way Arch users do SecureBoot, and there's an entire ecosystem
around this workflow, using sbctl and friends. systemd-boot provides
facilities to self-enroll on first boot, for example.
Another use case is in CIs, where we boot with a locally built
systemd-boot, self-enroll in EDK2, run some tests, and then throw away
the VM. This is the case in systemd's upstream CI that uses mkosi, for
example.

> > Default to the same value as
> > DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
> > if not otherwise specified, as it is likely that if one wants to use
> > MOK certificates to verify dm-verity volumes, DB certificates are
> > going to be used too. Keys in DB are allowed to load a full kernel
> > already anyway, so they are already highly privileged.
>
> But there's a reason we allow mok users to distrust DB through mokutil.
> It's because although you might be OK with these keys guarding the pre-
> boot environment (because if they don't do that Microsoft will be
> unhappy) and transferring control to SHIM via these keys, you wouldn't
> necessarily trust the owner of these keys to tamper with your kernel or
> install modules.  Doesn't a similar reasoning apply to dm-verity root
> hash signing?

Yes, although to me it personally feels like the real benefit of that
is avoiding being too exposed to the kitchen sink that is the UEFI 3rd
party CA, more than protection against an intentionally malicious CA
owner, after all if you are malicious and control the first stage of
the chain of trust things are very dire at that point. However, this
is all moot because of the next point that you correctly raised:

> By the way, if I look at how the machine keyring is handled, db certs
> won't get added if MokIgnoreDB is set by shim, so I think the behaviour
> of this patch is correct, and it's just the wording above that may be
> misleading.

This is of course entirely correct, and I should have worded the
commit message better to reflect it. I'll send v2 with these updates.
Thanks for the review!
Luca Boccassi July 4, 2024, 3:55 p.m. UTC | #4
On Thu, 4 Jul 2024 at 16:41, Luca Boccassi <luca.boccassi@gmail.com> wrote:
>
> On Thu, 4 Jul 2024 at 16:21, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> >
> > On Mon, 2024-06-17 at 23:00 +0100, luca.boccassi@gmail.com wrote:
> > > From: Luca Boccassi <bluca@debian.org>
> > >
> > > Add a new configuration
> > > CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
> > > that enables verifying dm-verity signatures using the platform
> > > keyring, which is populated using the UEFI DB certificates. This is
> > > useful for self-enrolled systems that do not use MOK, as the
> > > secondary keyring which is already used for verification, if the
> > > relevant kconfig is enabled, is linked to the machine keyring, which
> > > gets its certificates loaded from MOK. On datacenter/virtual/cloud
> > > deployments it is more common to deploy one's own certificate chain
> > > directly in DB on first boot in unattended mode, rather than relying
> > > on MOK, as the latter typically requires interactive authentication
> > > to enroll, and is more suited for personal machines.
> >
> > I think that's true if you roll your own cloud OS.  If you rely on a
> > distro OS (as, say, IBM Cloud does) you do use shim/mok and actually
> > you als have to enroll all the driver module keys in MoK.
>
> Yes, that is true, in many cases shim + 2nd stage is still used in
> those environments. Perhaps a better use case I should have mentioned
> is: this is also useful for those who self-enroll, and do not use
> shim/mok at all. This is actually quite common, for example it's the
> main way Arch users do SecureBoot, and there's an entire ecosystem
> around this workflow, using sbctl and friends. systemd-boot provides
> facilities to self-enroll on first boot, for example.
> Another use case is in CIs, where we boot with a locally built
> systemd-boot, self-enroll in EDK2, run some tests, and then throw away
> the VM. This is the case in systemd's upstream CI that uses mkosi, for
> example.
>
> > > Default to the same value as
> > > DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
> > > if not otherwise specified, as it is likely that if one wants to use
> > > MOK certificates to verify dm-verity volumes, DB certificates are
> > > going to be used too. Keys in DB are allowed to load a full kernel
> > > already anyway, so they are already highly privileged.
> >
> > But there's a reason we allow mok users to distrust DB through mokutil.
> > It's because although you might be OK with these keys guarding the pre-
> > boot environment (because if they don't do that Microsoft will be
> > unhappy) and transferring control to SHIM via these keys, you wouldn't
> > necessarily trust the owner of these keys to tamper with your kernel or
> > install modules.  Doesn't a similar reasoning apply to dm-verity root
> > hash signing?
>
> Yes, although to me it personally feels like the real benefit of that
> is avoiding being too exposed to the kitchen sink that is the UEFI 3rd
> party CA, more than protection against an intentionally malicious CA
> owner, after all if you are malicious and control the first stage of
> the chain of trust things are very dire at that point. However, this
> is all moot because of the next point that you correctly raised:
>
> > By the way, if I look at how the machine keyring is handled, db certs
> > won't get added if MokIgnoreDB is set by shim, so I think the behaviour
> > of this patch is correct, and it's just the wording above that may be
> > misleading.
>
> This is of course entirely correct, and I should have worded the
> commit message better to reflect it. I'll send v2 with these updates.
> Thanks for the review!

Ah it looks like this was merged yesterday in dm/for-next, so a bit
late to update the commit message. Fortunately it's not wrong per-se,
just missing a couple of useful bits of information :-)
James Bottomley July 4, 2024, 4:09 p.m. UTC | #5
On Thu, 2024-07-04 at 16:41 +0100, Luca Boccassi wrote:
> On Thu, 4 Jul 2024 at 16:21, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
[...]
> > But there's a reason we allow mok users to distrust DB through
> > mokutil. It's because although you might be OK with these keys
> > guarding the pre-boot environment (because if they don't do that
> > Microsoft will be unhappy) and transferring control to SHIM via
> > these keys, you wouldn't necessarily trust the owner of these keys
> > to tamper with your kernel or install modules.  Doesn't a similar
> > reasoning apply to dm-verity root hash signing?
> 
> Yes, although to me it personally feels like the real benefit of that
> is avoiding being too exposed to the kitchen sink that is the UEFI
> 3rd party CA,

That's precisely correct.  We trust the regulation of the pre-boot
environment but don't want to encourage people to think db certs should
be usable outside it.

>  more than protection against an intentionally malicious CA owner,
> after all if you are malicious and control the first stage of the
> chain of trust things are very dire at that point. However, this is
> all moot because of the next point that you correctly raised:

I think we mostly agree the 3rd party CA is reasonably well regulated.
The problem is actually OEMs and ODMs that add their own certs to DB
outside of the 3rd party CA control (mostly so their own EFI tooling
will run).  In theory they're still regulated by the MS Hardware
Compatibility requirements, but we don't want them getting the idea
that they can suddenly also sign linux kernel binary modules or
additional IMA policies or add trusted keys to the system keyrings ...

James
diff mbox series

Patch

diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 35b1080752cd..1e9db8e4acdf 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -540,6 +540,16 @@  config DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
 
 	  If unsure, say N.
 
+config DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
+	bool "Verity data device root hash signature verification with platform keyring"
+	default DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
+	depends on DM_VERITY_VERIFY_ROOTHASH_SIG
+	depends on INTEGRITY_PLATFORM_KEYRING
+	help
+	  Rely also on the platform keyring to verify dm-verity signatures.
+
+	  If unsure, say N.
+
 config DM_VERITY_FEC
 	bool "Verity forward error correction support"
 	depends on DM_VERITY
diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
index 4836508ea50c..d351d7d39c60 100644
--- a/drivers/md/dm-verity-verify-sig.c
+++ b/drivers/md/dm-verity-verify-sig.c
@@ -126,6 +126,13 @@  int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
 				NULL,
 #endif
 				VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+#ifdef CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING
+	if (ret == -ENOKEY)
+		ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data,
+					sig_len,
+					VERIFY_USE_PLATFORM_KEYRING,
+					VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+#endif
 
 	return ret;
 }