Hello,
I've been looking into how a migration to using trusted/encrypted keys
would look like (particularly with dm-crypt).
Currently, it seems the the only way is to re-encrypt the partitions
because trusted/encrypted keys always generate their payloads from
RNG.
If instead there was a key command to initialize a new trusted/encrypted
key with a user provided value, users could use whatever mechanism they
used beforehand to get a plaintext key and use that to initialize a new
trusted/encrypted key. From there on, the key will be like any other
trusted/encrypted key and not be disclosed again to userspace.
What are your thoughts on this? Would an API like
keyctl add trusted dmcrypt-key 'set <content>' # user-supplied content
be acceptable?
Cheers,
Ahmad
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> Hello,
>
> I've been looking into how a migration to using trusted/encrypted keys
> would look like (particularly with dm-crypt).
>
> Currently, it seems the the only way is to re-encrypt the partitions
> because trusted/encrypted keys always generate their payloads from
> RNG.
>
> If instead there was a key command to initialize a new trusted/encrypted
> key with a user provided value, users could use whatever mechanism they
> used beforehand to get a plaintext key and use that to initialize a new
> trusted/encrypted key. From there on, the key will be like any other
> trusted/encrypted key and not be disclosed again to userspace.
>
> What are your thoughts on this? Would an API like
>
> keyctl add trusted dmcrypt-key 'set <content>' # user-supplied content
>
> be acceptable?
Maybe it's the lack of knowledge with dm-crypt, but why this would be
useful? Just want to understand the bottleneck, that's all.
> Cheers,
> Ahmad
/Jarkko
On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > Hello,
> >
> > I've been looking into how a migration to using trusted/encrypted
> > keys would look like (particularly with dm-crypt).
> >
> > Currently, it seems the the only way is to re-encrypt the
> > partitions because trusted/encrypted keys always generate their
> > payloads from RNG.
> >
> > If instead there was a key command to initialize a new
> > trusted/encrypted key with a user provided value, users could use
> > whatever mechanism they used beforehand to get a plaintext key and
> > use that to initialize a new trusted/encrypted key. From there on,
> > the key will be like any other trusted/encrypted key and not be
> > disclosed again to userspace.
> >
> > What are your thoughts on this? Would an API like
> >
> > keyctl add trusted dmcrypt-key 'set <content>' # user-supplied
> > content
> >
> > be acceptable?
>
> Maybe it's the lack of knowledge with dm-crypt, but why this would be
> useful? Just want to understand the bottleneck, that's all.
There was a recent patch to dm-crypt to add encrypted key support:
27f5411a718c ("dm crypt: support using encrypted keys"). The
implementation requires the actual disk encryption master key to be in
the payload. Most people don't want to change that key because it
involves re-encrypting the whole disk (usually what people mean when
they say "key" for dm-crypt is a passphrase that decrypts this master
key from a keyslot in the metadata, which is why you can change your
passphrase without changing the underlying encryption).
However, once we get the trusted key rework upstream, we do have a
solution: The key format becomes interoperable with the
openssl_tpm2_engine and we can now do seal_tpm2_data on any payload and
the kernel will accept it.
James
On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > Hello,
> >
> > I've been looking into how a migration to using trusted/encrypted keys
> > would look like (particularly with dm-crypt).
> >
> > Currently, it seems the the only way is to re-encrypt the partitions
> > because trusted/encrypted keys always generate their payloads from
> > RNG.
> >
> > If instead there was a key command to initialize a new trusted/encrypted
> > key with a user provided value, users could use whatever mechanism they
> > used beforehand to get a plaintext key and use that to initialize a new
> > trusted/encrypted key. From there on, the key will be like any other
> > trusted/encrypted key and not be disclosed again to userspace.
> >
> > What are your thoughts on this? Would an API like
> >
> > keyctl add trusted dmcrypt-key 'set <content>' # user-supplied content
> >
> > be acceptable?
>
> Maybe it's the lack of knowledge with dm-crypt, but why this would be
> useful? Just want to understand the bottleneck, that's all.
We upstreamed "trusted" & "encrypted" keys together in order to address
this sort of problem. Instead of directly using a "trusted" key for
persistent file signatures being stored as xattrs, the "encrypted" key
provides one level of indirection. The "encrypted" key may be
encrypted/decrypted with either a TPM based "trusted" key or with a
"user" type symmetric key[1].
Instead of modifying "trusted" keys, use a "user" type "encrypted" key.
Mimi
[1] The ima-evm-utils README contains EVM examples of "trusted" and
"user" based "encrypted" keys.
On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > Hello,
> > >
> > > I've been looking into how a migration to using trusted/encrypted keys
> > > would look like (particularly with dm-crypt).
> > >
> > > Currently, it seems the the only way is to re-encrypt the partitions
> > > because trusted/encrypted keys always generate their payloads from
> > > RNG.
> > >
> > > If instead there was a key command to initialize a new trusted/encrypted
> > > key with a user provided value, users could use whatever mechanism they
> > > used beforehand to get a plaintext key and use that to initialize a new
> > > trusted/encrypted key. From there on, the key will be like any other
> > > trusted/encrypted key and not be disclosed again to userspace.
> > >
> > > What are your thoughts on this? Would an API like
> > >
> > > keyctl add trusted dmcrypt-key 'set <content>' # user-supplied content
> > >
> > > be acceptable?
> >
> > Maybe it's the lack of knowledge with dm-crypt, but why this would be
> > useful? Just want to understand the bottleneck, that's all.
Our goal in this case is to move away from having the dm-crypt key material
accessible to user-space on embedded devices. For an existing dm-crypt volume,
this key is fixed. A key can be loaded into user key type and used by dm-crypt
(cryptsetup can already do it this way). But at this point, you can still do
'keyctl read' on that key, exposing the key material to user space.
Currently, with both encrypted and trusted keys, you can only generate new
random keys, not import existing key material.
James Bottomley mentioned in the other reply that the key format will become
compatible with the openssl_tpm2_engine, which would provide a workaround. This
wouldn't work with OP-TEE-based trusted keys (see Sumit Garg's series), though.
> We upstreamed "trusted" & "encrypted" keys together in order to address
> this sort of problem. Instead of directly using a "trusted" key for
> persistent file signatures being stored as xattrs, the "encrypted" key
> provides one level of indirection. The "encrypted" key may be
> encrypted/decrypted with either a TPM based "trusted" key or with a
> "user" type symmetric key[1].
>
> Instead of modifying "trusted" keys, use a "user" type "encrypted" key.
I don't see how this would help. When using dm-crypt with an encrypted key, I
can't use my existing key material.
Except for the migration aspect, trusted keys seem ideal. Only a single exported
blob needs to be stored and can only be loaded/used again on the same (trusted)
system. Userspace cannot extract the key material.
To get to this point on systems in the field without re-encryption of the whole
storage, only the initial trusted/encrypted key creation would need to allow
passing in existing key material.
> Mimi
>
> [1] The ima-evm-utils README contains EVM examples of "trusted" and
> "user" based "encrypted" keys.
I assume you refer to
https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/README#l143
"Generate EVM encrypted keys" and "Generate EVM trusted keys (TPM based)"?
In both cases, the key used by EVM is a *newly generated* random key. The only
difference is whether it's encrypted to a user key or a (random) trusted key.
Best regards
Jan
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Sun, 2021-01-31 at 15:14 +0100, Jan L?bbe wrote:
> On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
<snip>
> >
> > [1] The ima-evm-utils README contains EVM examples of "trusted" and
> > "user" based "encrypted" keys.
>
> I assume you refer to
> https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/README#l143
> "Generate EVM encrypted keys" and "Generate EVM trusted keys (TPM based)"?
>
> In both cases, the key used by EVM is a *newly generated* random key. The only
> difference is whether it's encrypted to a user key or a (random) trusted key.
The "encrypted" asymmetric key data doesn't change, "update" just
changes the key under which it is encrypted/decrypted.
Usage::
keyctl add encrypted name "new [format] key-type:master-key-name
keylen"
ring
keyctl add encrypted name "load hex_blob" ring
keyctl update keyid "update key-type:master-key-name"
Mimi
On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > Hello,
> > > >
> > > > I've been looking into how a migration to using
> > > > trusted/encrypted keys would look like (particularly with dm-
> > > > crypt).
> > > >
> > > > Currently, it seems the the only way is to re-encrypt the
> > > > partitions because trusted/encrypted keys always generate their
> > > > payloads from RNG.
> > > >
> > > > If instead there was a key command to initialize a new
> > > > trusted/encrypted key with a user provided value, users could
> > > > use whatever mechanism they used beforehand to get a plaintext
> > > > key and use that to initialize a new trusted/encrypted key.
> > > > From there on, the key will be like any other trusted/encrypted
> > > > key and not be disclosed again to userspace.
> > > >
> > > > What are your thoughts on this? Would an API like
> > > >
> > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > supplied content
> > > >
> > > > be acceptable?
> > >
> > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > would be useful? Just want to understand the bottleneck, that's
> > > all.
>
> Our goal in this case is to move away from having the dm-crypt key
> material accessible to user-space on embedded devices. For an
> existing dm-crypt volume, this key is fixed. A key can be loaded into
> user key type and used by dm-crypt (cryptsetup can already do it this
> way). But at this point, you can still do 'keyctl read' on that key,
> exposing the key material to user space.
>
> Currently, with both encrypted and trusted keys, you can only
> generate new random keys, not import existing key material.
>
> James Bottomley mentioned in the other reply that the key format will
> become compatible with the openssl_tpm2_engine, which would provide a
> workaround. This wouldn't work with OP-TEE-based trusted keys (see
> Sumit Garg's series), though.
Assuming OP-TEE has the same use model as the TPM, someone will
eventually realise the need for interoperable key formats between key
consumers and then it will work in the same way once the kernel gets
updated to speak whatever format they come up with.
> > We upstreamed "trusted" & "encrypted" keys together in order to
> > address this sort of problem. Instead of directly using a
> > "trusted" key for persistent file signatures being stored as
> > xattrs, the "encrypted" key provides one level of
> > indirection. The "encrypted" key may be encrypted/decrypted with
> > either a TPM based "trusted" key or with a "user" type symmetric
> > key[1].
> >
> > Instead of modifying "trusted" keys, use a "user" type "encrypted"
> > key.
>
> I don't see how this would help. When using dm-crypt with an
> encrypted key, I can't use my existing key material.
>
> Except for the migration aspect, trusted keys seem ideal. Only a
> single exported blob needs to be stored and can only be loaded/used
> again on the same (trusted) system. Userspace cannot extract the key
> material.
Yes, that's what I was thinking ... especially when you can add policy
to the keys, which includes PCR locking. Part of the problem is that
changing policy, which you have to do if something happens to update
the PCR values, is technically a migration, so your trusted keys for
dm-crypt are really going to have to be migrateable.
> To get to this point on systems in the field without re-encryption of
> the whole storage, only the initial trusted/encrypted key creation
> would need to allow passing in existing key material.
What about a third option: why not make dm-crypt store the master key
it uses as an encrypted key (if a parent trusted key is available)?
That way you'd be able to extract the encrypted form of the key as
root, but wouldn't be able to extract the actual master key.
James
Jan Lübbe <[email protected]> wrote:
> ... But at this point, you can still do 'keyctl read' on that key, exposing
> the key material to user space.
I wonder if it would help to provide a keyctl function to mark a key as being
permanently unreadable - so that it overrides the READ permission bit.
Alternatively, you can disable READ and SETATTR permission - but that then
prevents you from removing other perms if you want to :-/
David
On Sun, 2021-01-31 at 09:29 -0500, Mimi Zohar wrote:
> On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
>
> <snip>
>
> > >
> > > [1] The ima-evm-utils README contains EVM examples of "trusted" and
> > > "user" based "encrypted" keys.
> >
> > I assume you refer to
> > https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/README#l143
> > "Generate EVM encrypted keys" and "Generate EVM trusted keys (TPM based)"?
> >
> > In both cases, the key used by EVM is a *newly generated* random key. The only
> > difference is whether it's encrypted to a user key or a (random) trusted key.
>
> The "encrypted" asymmetric key data doesn't change, "update" just
> changes the key under which it is encrypted/decrypted.
>
> Usage::
>
> keyctl add encrypted name "new [format] key-type:master-key-name keylen"
> ring
> keyctl add encrypted name "load hex_blob" ring
'load' (as I understand the code) only accepts an encrypted blob.
So the only way I see to have an encrypted key with a non-random key data would
be:
- create a random temporary master key and load a copy as a user key
- encrypt the chosen key data with the temporary master key (using a new
userspace reimplementation of the kernel encrypted key blob format)
- use keyctl add encrypted dmcrypt "load <encrypted blob>" <keyring>
- create new trusted master key (OP-TEE or CAAM in our case) as
- use keyctl update to switch to the new trusted master key
- use keyctl pipe on the trusted and encrypted keys and store both for loading
on later boots
If we'd support importing a pre-existing key into a trusted or encrypted key,
we'd do instead:
- use keyctl add trusted dmcrypt "import <unencrypted key data>"
- use keyctl pipe on the trusted key and store it for loading on later boots
This way, users wouldn't need to care which backend is used by trusted keys
(TPM/OP-TEE/CAAM/...). That would make use-cases where a random key is not
suitable as straight-forward as the those where a random key is OK.
Best regards
Jan
> keyctl update keyid "update key-type:master-key-name"
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Mon, 2021-02-01 at 11:36 +0000, David Howells wrote:
> Jan Lübbe <[email protected]> wrote:
>
> > ... But at this point, you can still do 'keyctl read' on that key, exposing
> > the key material to user space.
>
> I wonder if it would help to provide a keyctl function to mark a key as being
> permanently unreadable - so that it overrides the READ permission bit.
>
> Alternatively, you can disable READ and SETATTR permission - but that then
> prevents you from removing other perms if you want to :-/
That would mean using user type keys, right? Then we'd still have the core
problem how a master key can be protected against simply reading it from
flash/disk, as it would be unencrypted in this scenario.
Maybe a bit of background:
We're looking at the trusted/encrypted keys because we want to store the key
material in an encrypted format, only loadable into the same system where they
were generated and only if that's in a trusted state (to solve the master key
problem above).
This binding can be done with trusted keys via a TPM (and soon with Sumit's OP-
TEE backend, or later based on SoC-specific hardware like NXP's CAAM). In the
OP-TEE/CAAM case, the bootloader would ensure that the backend can only be used
when booting a correctly authenticated kernel.
Of course, that's not as flexible as TPMs with a custom policy, but much simpler
and a good fit for many embedded use-cases.
Best regards,
Jan Lübbe
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Mon, 2021-02-01 at 16:31 +0100, Jan L?bbe wrote:
> On Sun, 2021-01-31 at 09:29 -0500, Mimi Zohar wrote:
> > On Sun, 2021-01-31 at 15:14 +0100, Jan L?bbe wrote:
> > > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> >
> > <snip>
> >
> > > >
> > > > [1] The ima-evm-utils README contains EVM examples of "trusted" and
> > > > "user" based "encrypted" keys.
> > >
> > > I assume you refer to
> > > https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/README#l143
> > > "Generate EVM encrypted keys" and "Generate EVM trusted keys (TPM based)"?
> > >
> > > In both cases, the key used by EVM is a *newly generated* random key. The only
> > > difference is whether it's encrypted to a user key or a (random) trusted key.
> >
> > The "encrypted" asymmetric key data doesn't change, "update" just
> > changes the key under which it is encrypted/decrypted.
> >
> > Usage::
> >
> > keyctl add encrypted name "new [format] key-type:master-key-name keylen"
> > ring
> > keyctl add encrypted name "load hex_blob" ring
>
> 'load' (as I understand the code) only accepts an encrypted blob.
>
> So the only way I see to have an encrypted key with a non-random key data would
> be:
> - create a random temporary master key and load a copy as a user key
> - encrypt the chosen key data with the temporary master key (using a new
> userspace reimplementation of the kernel encrypted key blob format)
> - use keyctl add encrypted dmcrypt "load <encrypted blob>" <keyring>
> - create new trusted master key (OP-TEE or CAAM in our case) as
> - use keyctl update to switch to the new trusted master key
> - use keyctl pipe on the trusted and encrypted keys and store both for loading
> on later boots
>
> If we'd support importing a pre-existing key into a trusted or encrypted key,
> we'd do instead:
> - use keyctl add trusted dmcrypt "import <unencrypted key data>"
> - use keyctl pipe on the trusted key and store it for loading on later boots
>
> This way, users wouldn't need to care which backend is used by trusted keys
> (TPM/OP-TEE/CAAM/...). That would make use-cases where a random key is not
> suitable as straight-forward as the those where a random key is OK.
As I said above, the "encrypted" key update doesn't change the key data
used for encrypting/decrypting storage in the dm-crypt case, it just
updates the key under which it is encrypted/signed.
Yes, the reason for using an encrypted "trusted" key, as opposed to an
encrypted "user" key, is that the "trusted" key is encrypted/decrypted
by the TPM and never exposed to userspace in the clear.
It doesn't sound like you're wanting to update the storage key in the
field, just the key used to encrypt/decrypt that key. So I'm still not
clear as to why you would want an initial non-random encrypted key.
Providing that key on the command line certaining isn't a good idea.
Mimi
On Mon, 2021-02-01 at 11:11 -0500, Mimi Zohar wrote:
> On Mon, 2021-02-01 at 16:31 +0100, Jan Lübbe wrote:
> > On Sun, 2021-01-31 at 09:29 -0500, Mimi Zohar wrote:
<snip>
> > > Usage::
> > >
> > > keyctl add encrypted name "new [format] key-type:master-key-name keylen"
> > > ring
> > > keyctl add encrypted name "load hex_blob" ring
> >
> > 'load' (as I understand the code) only accepts an encrypted blob.
> >
> > So the only way I see to have an encrypted key with a non-random key data would
> > be:
> > - create a random temporary master key and load a copy as a user key
> > - encrypt the chosen key data with the temporary master key (using a new
> > userspace reimplementation of the kernel encrypted key blob format)
> > - use keyctl add encrypted dmcrypt "load <encrypted blob>" <keyring>
> > - create new trusted master key (OP-TEE or CAAM in our case) as
> > - use keyctl update to switch to the new trusted master key
> > - use keyctl pipe on the trusted and encrypted keys and store both for loading
> > on later boots
> >
> > If we'd support importing a pre-existing key into a trusted or encrypted key,
> > we'd do instead:
> > - use keyctl add trusted dmcrypt "import <unencrypted key data>"
> > - use keyctl pipe on the trusted key and store it for loading on later boots
> >
> > This way, users wouldn't need to care which backend is used by trusted keys
> > (TPM/OP-TEE/CAAM/...). That would make use-cases where a random key is not
> > suitable as straight-forward as the those where a random key is OK.
>
> As I said above, the "encrypted" key update doesn't change the key data
> used for encrypting/decrypting storage in the dm-crypt case, it just
> updates the key under which it is encrypted/signed.
Yes, that's clear. I only used it to demonstrate how a workaround for importing
key material into an encrypted key could look like.
> Yes, the reason for using an encrypted "trusted" key, as opposed to an
> encrypted "user" key, is that the "trusted" key is encrypted/decrypted
> by the TPM and never exposed to userspace in the clear.
Yes, and that's the main reason I'd like to use trusted keys with dm-crypt: a
much lower chance of exposing this key somewhere it could be extracted.
> It doesn't sound like you're wanting to update the storage key in the
> field, just the key used to encrypt/decrypt that key. So I'm still not
> clear as to why you would want an initial non-random encrypted key.
> Providing that key on the command line certaining isn't a good idea.
Some of our customers have systems in the field which use non-mainline patches
for access to the CAAM [1], which also have the downside of exposing the
decrypted key material directly to userspace. In that thread you suggested to
use trusted keys instead. With Sumit's work that rework is finally within reach.
:)
In those systems, we have data that's encrypted with a pre-existing dm-crypt or
ecryptfs key. As we update those systems in the field to newer kernels, we want
to get rid of those custom patches, but can't reencrypt everything.
So the approach would be to perform a one-time migration when updating a device:
- use our old interface to decrypt the key and 'import' it into a trusted key
- use keyctl pipe and save the re-encrypted key to disk
- destroy the old encrypted key
After this migration, the key material is no longer available to userspace (only
to dm-crypt).
Another use-case for supporting key import that we want to support is analysis
of broken devices returned from the field:
- generate an encryption key per device in the factory
- encrypt it to a private key in escrow and archive it for later use
- import it into a trusted key on the device
- keyctl pipe it to a file on the device for use on boot
Later, when you need to do an analysis, you can get the key from escrow even if
the device cannot boot any longer.
Regards,
Jan
[1] https://lore.kernel.org/linux-crypto/[email protected]/
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Jan Lübbe <[email protected]> wrote:
> > > ... But at this point, you can still do 'keyctl read' on that key, exposing
> > > the key material to user space.
> >
> > I wonder if it would help to provide a keyctl function to mark a key as being
> > permanently unreadable - so that it overrides the READ permission bit.
> >
> > Alternatively, you can disable READ and SETATTR permission - but that then
> > prevents you from removing other perms if you want to :-/
>
> That would mean using user type keys, right? Then we'd still have the core
> problem how a master key can be protected against simply reading it from
> flash/disk, as it would be unencrypted in this scenario.
It would apply to any type of key or keyring on which it was set. It would
cause keyctl_read() on a flagged key to return EPERM.
David
On Mon, 2021-02-01 at 17:38 +0100, Jan L?bbe wrote:
> On Mon, 2021-02-01 at 11:11 -0500, Mimi Zohar wrote:
> > On Mon, 2021-02-01 at 16:31 +0100, Jan L?bbe wrote:
> > > On Sun, 2021-01-31 at 09:29 -0500, Mimi Zohar wrote:
> <snip>
> > > > Usage::
> > > >
> > > > keyctl add encrypted name "new [format] key-type:master-key-name keylen"
> > > > ring
> > > > keyctl add encrypted name "load hex_blob" ring
> > >
> > > 'load' (as I understand the code) only accepts an encrypted blob.
> > >
> > > So the only way I see to have an encrypted key with a non-random key data would
> > > be:
> > > - create a random temporary master key and load a copy as a user key
> > > - encrypt the chosen key data with the temporary master key (using a new
> > > userspace reimplementation of the kernel encrypted key blob format)
> > > - use keyctl add encrypted dmcrypt "load <encrypted blob>" <keyring>
> > > - create new trusted master key (OP-TEE or CAAM in our case) as
> > > - use keyctl update to switch to the new trusted master key
> > > - use keyctl pipe on the trusted and encrypted keys and store both for loading
> > > on later boots
> > >
> > > If we'd support importing a pre-existing key into a trusted or encrypted key,
> > > we'd do instead:
> > > - use keyctl add trusted dmcrypt "import <unencrypted key data>"
> > > - use keyctl pipe on the trusted key and store it for loading on later boots
> > >
> > > This way, users wouldn't need to care which backend is used by trusted keys
> > > (TPM/OP-TEE/CAAM/...). That would make use-cases where a random key is not
> > > suitable as straight-forward as the those where a random key is OK.
> >
> > As I said above, the "encrypted" key update doesn't change the key data
> > used for encrypting/decrypting storage in the dm-crypt case, it just
> > updates the key under which it is encrypted/signed.
>
> Yes, that's clear. I only used it to demonstrate how a workaround for importing
> key material into an encrypted key could look like.
>
> > Yes, the reason for using an encrypted "trusted" key, as opposed to an
> > encrypted "user" key, is that the "trusted" key is encrypted/decrypted
> > by the TPM and never exposed to userspace in the clear.
>
> Yes, and that's the main reason I'd like to use trusted keys with dm-crypt: a
> much lower chance of exposing this key somewhere it could be extracted.
>
> > It doesn't sound like you're wanting to update the storage key in the
> > field, just the key used to encrypt/decrypt that key. So I'm still not
> > clear as to why you would want an initial non-random encrypted key.
> > Providing that key on the command line certaining isn't a good idea.
>
> Some of our customers have systems in the field which use non-mainline patches
> for access to the CAAM [1], which also have the downside of exposing the
> decrypted key material directly to userspace. In that thread you suggested to
> use trusted keys instead. With Sumit's work that rework is finally within reach.
> :)
>
>
> In those systems, we have data that's encrypted with a pre-existing dm-crypt or
> ecryptfs key. As we update those systems in the field to newer kernels, we want
> to get rid of those custom patches, but can't reencrypt everything.
>
> So the approach would be to perform a one-time migration when updating a device:
> - use our old interface to decrypt the key and 'import' it into a trusted key
> - use keyctl pipe and save the re-encrypted key to disk
> - destroy the old encrypted key
> After this migration, the key material is no longer available to userspace (only
> to dm-crypt).
>
>
> Another use-case for supporting key import that we want to support is analysis
> of broken devices returned from the field:
> - generate an encryption key per device in the factory
> - encrypt it to a private key in escrow and archive it for later use
> - import it into a trusted key on the device
> - keyctl pipe it to a file on the device for use on boot
>
> Later, when you need to do an analysis, you can get the key from escrow even if
> the device cannot boot any longer.
The first use case doesn't sound like a valid reason for upstreaming
such support. It's a one time update to migrate everyone to a newer
kernel. That you can carry independently of upstream. In terms of the
second use case, do you really want the ability and the resulting
responsibility of being able to decrypt user's data? Please think
this through carefully, before you decide you really want/need this
feature.
thanks,
Mimi
Hi Jan,
On Sun, 31 Jan 2021 at 23:40, James Bottomley <[email protected]> wrote:
>
> On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > > Hello,
> > > > >
> > > > > I've been looking into how a migration to using
> > > > > trusted/encrypted keys would look like (particularly with dm-
> > > > > crypt).
> > > > >
> > > > > Currently, it seems the the only way is to re-encrypt the
> > > > > partitions because trusted/encrypted keys always generate their
> > > > > payloads from RNG.
> > > > >
> > > > > If instead there was a key command to initialize a new
> > > > > trusted/encrypted key with a user provided value, users could
> > > > > use whatever mechanism they used beforehand to get a plaintext
> > > > > key and use that to initialize a new trusted/encrypted key.
> > > > > From there on, the key will be like any other trusted/encrypted
> > > > > key and not be disclosed again to userspace.
> > > > >
> > > > > What are your thoughts on this? Would an API like
> > > > >
> > > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > > supplied content
> > > > >
> > > > > be acceptable?
> > > >
> > > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > > would be useful? Just want to understand the bottleneck, that's
> > > > all.
> >
> > Our goal in this case is to move away from having the dm-crypt key
> > material accessible to user-space on embedded devices. For an
> > existing dm-crypt volume, this key is fixed. A key can be loaded into
> > user key type and used by dm-crypt (cryptsetup can already do it this
> > way). But at this point, you can still do 'keyctl read' on that key,
> > exposing the key material to user space.
> >
> > Currently, with both encrypted and trusted keys, you can only
> > generate new random keys, not import existing key material.
> >
> > James Bottomley mentioned in the other reply that the key format will
> > become compatible with the openssl_tpm2_engine, which would provide a
> > workaround. This wouldn't work with OP-TEE-based trusted keys (see
> > Sumit Garg's series), though.
>
> Assuming OP-TEE has the same use model as the TPM, someone will
> eventually realise the need for interoperable key formats between key
> consumers and then it will work in the same way once the kernel gets
> updated to speak whatever format they come up with.
IIUC, James re-work for TPM trusted keys is to allow loading of sealed
trusted keys directly via user-space (with proper authorization) into
the kernel keyring.
I think similar should be achievable with OP-TEE (via extending pseudo
TA [1]) as well to allow restricted user-space access (with proper
authorization) to generate sealed trusted key blob that should be
interoperable with the kernel. Currently OP-TEE exposes trusted key
interfaces for kernel users only.
[1] https://github.com/OP-TEE/optee_os/blob/master/ta/trusted_keys/entry.c
-Sumit
>
> > > We upstreamed "trusted" & "encrypted" keys together in order to
> > > address this sort of problem. Instead of directly using a
> > > "trusted" key for persistent file signatures being stored as
> > > xattrs, the "encrypted" key provides one level of
> > > indirection. The "encrypted" key may be encrypted/decrypted with
> > > either a TPM based "trusted" key or with a "user" type symmetric
> > > key[1].
> > >
> > > Instead of modifying "trusted" keys, use a "user" type "encrypted"
> > > key.
> >
> > I don't see how this would help. When using dm-crypt with an
> > encrypted key, I can't use my existing key material.
> >
> > Except for the migration aspect, trusted keys seem ideal. Only a
> > single exported blob needs to be stored and can only be loaded/used
> > again on the same (trusted) system. Userspace cannot extract the key
> > material.
>
> Yes, that's what I was thinking ... especially when you can add policy
> to the keys, which includes PCR locking. Part of the problem is that
> changing policy, which you have to do if something happens to update
> the PCR values, is technically a migration, so your trusted keys for
> dm-crypt are really going to have to be migrateable.
>
> > To get to this point on systems in the field without re-encryption of
> > the whole storage, only the initial trusted/encrypted key creation
> > would need to allow passing in existing key material.
>
> What about a third option: why not make dm-crypt store the master key
> it uses as an encrypted key (if a parent trusted key is available)?
> That way you'd be able to extract the encrypted form of the key as
> root, but wouldn't be able to extract the actual master key.
>
> James
>
>
On Tue, 2021-02-02 at 17:45 +0530, Sumit Garg wrote:
> Hi Jan,
>
> On Sun, 31 Jan 2021 at 23:40, James Bottomley <[email protected]> wrote:
> >
> > On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > > > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > > > Hello,
> > > > > >
> > > > > > I've been looking into how a migration to using
> > > > > > trusted/encrypted keys would look like (particularly with dm-
> > > > > > crypt).
> > > > > >
> > > > > > Currently, it seems the the only way is to re-encrypt the
> > > > > > partitions because trusted/encrypted keys always generate their
> > > > > > payloads from RNG.
> > > > > >
> > > > > > If instead there was a key command to initialize a new
> > > > > > trusted/encrypted key with a user provided value, users could
> > > > > > use whatever mechanism they used beforehand to get a plaintext
> > > > > > key and use that to initialize a new trusted/encrypted key.
> > > > > > From there on, the key will be like any other trusted/encrypted
> > > > > > key and not be disclosed again to userspace.
> > > > > >
> > > > > > What are your thoughts on this? Would an API like
> > > > > >
> > > > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > > > supplied content
> > > > > >
> > > > > > be acceptable?
> > > > >
> > > > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > > > would be useful? Just want to understand the bottleneck, that's
> > > > > all.
> > >
> > > Our goal in this case is to move away from having the dm-crypt key
> > > material accessible to user-space on embedded devices. For an
> > > existing dm-crypt volume, this key is fixed. A key can be loaded into
> > > user key type and used by dm-crypt (cryptsetup can already do it this
> > > way). But at this point, you can still do 'keyctl read' on that key,
> > > exposing the key material to user space.
> > >
> > > Currently, with both encrypted and trusted keys, you can only
> > > generate new random keys, not import existing key material.
> > >
> > > James Bottomley mentioned in the other reply that the key format will
> > > become compatible with the openssl_tpm2_engine, which would provide a
> > > workaround. This wouldn't work with OP-TEE-based trusted keys (see
> > > Sumit Garg's series), though.
> >
> > Assuming OP-TEE has the same use model as the TPM, someone will
> > eventually realise the need for interoperable key formats between key
> > consumers and then it will work in the same way once the kernel gets
> > updated to speak whatever format they come up with.
>
> IIUC, James re-work for TPM trusted keys is to allow loading of sealed
> trusted keys directly via user-space (with proper authorization) into
> the kernel keyring.
>
> I think similar should be achievable with OP-TEE (via extending pseudo
> TA [1]) as well to allow restricted user-space access (with proper
> authorization) to generate sealed trusted key blob that should be
> interoperable with the kernel. Currently OP-TEE exposes trusted key
> interfaces for kernel users only.
What is the security benefit of having the key blob creation in user-space
instead of in the kernel? Key import is a standard operation in HSMs or PKCS#11
tokens.
I mainly see the downside of having to add another API to access the underlying
functionality (be it trusted key TA or the NXP CAAM HW *) and requiring
platform-specific userspace code.
This CAAM specific API (in out-of-tree patches) was exactly the part I was
trying to get rid of. ;)
Regards,
Jan
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Tue, 2 Feb 2021 at 18:04, Jan Lübbe <[email protected]> wrote:
>
> On Tue, 2021-02-02 at 17:45 +0530, Sumit Garg wrote:
> > Hi Jan,
> >
> > On Sun, 31 Jan 2021 at 23:40, James Bottomley <[email protected]> wrote:
> > >
> > > On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > > > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > > > > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > > > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > > > > Hello,
> > > > > > >
> > > > > > > I've been looking into how a migration to using
> > > > > > > trusted/encrypted keys would look like (particularly with dm-
> > > > > > > crypt).
> > > > > > >
> > > > > > > Currently, it seems the the only way is to re-encrypt the
> > > > > > > partitions because trusted/encrypted keys always generate their
> > > > > > > payloads from RNG.
> > > > > > >
> > > > > > > If instead there was a key command to initialize a new
> > > > > > > trusted/encrypted key with a user provided value, users could
> > > > > > > use whatever mechanism they used beforehand to get a plaintext
> > > > > > > key and use that to initialize a new trusted/encrypted key.
> > > > > > > From there on, the key will be like any other trusted/encrypted
> > > > > > > key and not be disclosed again to userspace.
> > > > > > >
> > > > > > > What are your thoughts on this? Would an API like
> > > > > > >
> > > > > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > > > > supplied content
> > > > > > >
> > > > > > > be acceptable?
> > > > > >
> > > > > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > > > > would be useful? Just want to understand the bottleneck, that's
> > > > > > all.
> > > >
> > > > Our goal in this case is to move away from having the dm-crypt key
> > > > material accessible to user-space on embedded devices. For an
> > > > existing dm-crypt volume, this key is fixed. A key can be loaded into
> > > > user key type and used by dm-crypt (cryptsetup can already do it this
> > > > way). But at this point, you can still do 'keyctl read' on that key,
> > > > exposing the key material to user space.
> > > >
> > > > Currently, with both encrypted and trusted keys, you can only
> > > > generate new random keys, not import existing key material.
> > > >
> > > > James Bottomley mentioned in the other reply that the key format will
> > > > become compatible with the openssl_tpm2_engine, which would provide a
> > > > workaround. This wouldn't work with OP-TEE-based trusted keys (see
> > > > Sumit Garg's series), though.
> > >
> > > Assuming OP-TEE has the same use model as the TPM, someone will
> > > eventually realise the need for interoperable key formats between key
> > > consumers and then it will work in the same way once the kernel gets
> > > updated to speak whatever format they come up with.
> >
> > IIUC, James re-work for TPM trusted keys is to allow loading of sealed
> > trusted keys directly via user-space (with proper authorization) into
> > the kernel keyring.
> >
> > I think similar should be achievable with OP-TEE (via extending pseudo
> > TA [1]) as well to allow restricted user-space access (with proper
> > authorization) to generate sealed trusted key blob that should be
> > interoperable with the kernel. Currently OP-TEE exposes trusted key
> > interfaces for kernel users only.
>
> What is the security benefit of having the key blob creation in user-space
> instead of in the kernel? Key import is a standard operation in HSMs or PKCS#11
> tokens.
User authentication, AFAIK most of the HSMs or PKCS#11 require that
for key import. But IIUC, your suggested approach to load plain key
into kernel keyring and say it's *trusted* without any user
authentication, would it really be a trusted key? What prevents a
rogue user from making his key as the dm-crypt trusted key?
>
> I mainly see the downside of having to add another API to access the underlying
> functionality (be it trusted key TA or the NXP CAAM HW *) and requiring
> platform-specific userspace code.
I am not sure why you would call the standardized TEE interface [1] to
be platform-specific, it is meant to be platform agnostic. And I think
we can have openssl_tee_engine on similar lines as the
openssl_tpm2_engine.
[1] https://globalplatform.org/specs-library/tee-client-api-specification/
-Sumit
>
> This CAAM specific API (in out-of-tree patches) was exactly the part I was
> trying to get rid of. ;)
>
> Regards,
> Jan
>
> --
> Pengutronix e.K. | |
> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
On Wed, 2021-02-03 at 17:20 +0530, Sumit Garg wrote:
> On Tue, 2 Feb 2021 at 18:04, Jan Lübbe <[email protected]> wrote:
> >
> > On Tue, 2021-02-02 at 17:45 +0530, Sumit Garg wrote:
> > > Hi Jan,
> > >
> > > On Sun, 31 Jan 2021 at 23:40, James Bottomley <[email protected]> wrote:
> > > >
> > > > On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > > > > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > > > > > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > > > > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > > > > > Hello,
> > > > > > > >
> > > > > > > > I've been looking into how a migration to using
> > > > > > > > trusted/encrypted keys would look like (particularly with dm-
> > > > > > > > crypt).
> > > > > > > >
> > > > > > > > Currently, it seems the the only way is to re-encrypt the
> > > > > > > > partitions because trusted/encrypted keys always generate their
> > > > > > > > payloads from RNG.
> > > > > > > >
> > > > > > > > If instead there was a key command to initialize a new
> > > > > > > > trusted/encrypted key with a user provided value, users could
> > > > > > > > use whatever mechanism they used beforehand to get a plaintext
> > > > > > > > key and use that to initialize a new trusted/encrypted key.
> > > > > > > > From there on, the key will be like any other trusted/encrypted
> > > > > > > > key and not be disclosed again to userspace.
> > > > > > > >
> > > > > > > > What are your thoughts on this? Would an API like
> > > > > > > >
> > > > > > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > > > > > supplied content
> > > > > > > >
> > > > > > > > be acceptable?
> > > > > > >
> > > > > > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > > > > > would be useful? Just want to understand the bottleneck, that's
> > > > > > > all.
> > > > >
> > > > > Our goal in this case is to move away from having the dm-crypt key
> > > > > material accessible to user-space on embedded devices. For an
> > > > > existing dm-crypt volume, this key is fixed. A key can be loaded into
> > > > > user key type and used by dm-crypt (cryptsetup can already do it this
> > > > > way). But at this point, you can still do 'keyctl read' on that key,
> > > > > exposing the key material to user space.
> > > > >
> > > > > Currently, with both encrypted and trusted keys, you can only
> > > > > generate new random keys, not import existing key material.
> > > > >
> > > > > James Bottomley mentioned in the other reply that the key format will
> > > > > become compatible with the openssl_tpm2_engine, which would provide a
> > > > > workaround. This wouldn't work with OP-TEE-based trusted keys (see
> > > > > Sumit Garg's series), though.
> > > >
> > > > Assuming OP-TEE has the same use model as the TPM, someone will
> > > > eventually realise the need for interoperable key formats between key
> > > > consumers and then it will work in the same way once the kernel gets
> > > > updated to speak whatever format they come up with.
> > >
> > > IIUC, James re-work for TPM trusted keys is to allow loading of sealed
> > > trusted keys directly via user-space (with proper authorization) into
> > > the kernel keyring.
> > >
> > > I think similar should be achievable with OP-TEE (via extending pseudo
> > > TA [1]) as well to allow restricted user-space access (with proper
> > > authorization) to generate sealed trusted key blob that should be
> > > interoperable with the kernel. Currently OP-TEE exposes trusted key
> > > interfaces for kernel users only.
> >
> > What is the security benefit of having the key blob creation in user-space
> > instead of in the kernel? Key import is a standard operation in HSMs or PKCS#11
> > tokens.
>
> User authentication, AFAIK most of the HSMs or PKCS#11 require that
> for key import. But IIUC, your suggested approach to load plain key
> into kernel keyring and say it's *trusted* without any user
> authentication, would it really be a trusted key? What prevents a
> rogue user from making his key as the dm-crypt trusted key?
There is user authentication at the level of key rings. So an untrusted user
cannot load or link keys they have no write permission for.
As we already have user type keys, which don't have these restrictions and are
accepted by most subsystems, any use of kernel keyrings must already make sure
that the proper keys are used.
With asymmetric keys we have trusted key *rings*:
# keyctl show %:.secondary_trusted_keys
Keyring
638775388 ---lswrv 0 0 keyring: .secondary_trusted_keys
1071890135 ---lswrv 0 0 \_ keyring: .builtin_trusted_keys
816294887 ---lswrv 0 0 \_ asymmetric: Debian Secure Boot CA: 6ccece7e4c6c0d1f6149f3dd27dfcc5cbb419ea1
630436721 ---lswrv 0 0 \_ asymmetric: Debian Secure Boot Signer 2020: 00b55eb3b9
Here, a key is trusted because of it's presence in a keyring, not because it has
a specific type. For example, fs-verity uses this mechanism as well.
For the trusted key *type*, my understanding is that trusted refers to only
being able to load and access them in specific "trusted" system states (via TPM
PRC, TEE initialization via secure boot or SoC specific hardware status checks).
So for example protecting against loading a data-encryption key into an unsigned
kernel.
> > I mainly see the downside of having to add another API to access the underlying
> > functionality (be it trusted key TA or the NXP CAAM HW *) and requiring
> > platform-specific userspace code.
>
> I am not sure why you would call the standardized TEE interface [1] to
> be platform-specific, it is meant to be platform agnostic. And I think
> we can have openssl_tee_engine on similar lines as the
> openssl_tpm2_engine.
Sorry, I meant platform-specific in the sense that some platforms use TPMs,
while others use TEEs. The trusted key type was also suggested several times as
the correct abstraction for SoC-specific key encapsulation hardware (instead of
custom interfaces), so there will likely be platforms which don't have a TPM or
TEE, but still trusted keys.
Regards
Jan
> [1] https://globalplatform.org/specs-library/tee-client-api-specification/
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Wed, 3 Feb 2021 at 19:16, Jan Lübbe <[email protected]> wrote:
>
> On Wed, 2021-02-03 at 17:20 +0530, Sumit Garg wrote:
> > On Tue, 2 Feb 2021 at 18:04, Jan Lübbe <[email protected]> wrote:
> > >
> > > On Tue, 2021-02-02 at 17:45 +0530, Sumit Garg wrote:
> > > > Hi Jan,
> > > >
> > > > On Sun, 31 Jan 2021 at 23:40, James Bottomley <[email protected]> wrote:
> > > > >
> > > > > On Sun, 2021-01-31 at 15:14 +0100, Jan Lübbe wrote:
> > > > > > On Sun, 2021-01-31 at 07:09 -0500, Mimi Zohar wrote:
> > > > > > > On Sat, 2021-01-30 at 19:53 +0200, Jarkko Sakkinen wrote:
> > > > > > > > On Thu, 2021-01-28 at 18:31 +0100, Ahmad Fatoum wrote:
> > > > > > > > > Hello,
> > > > > > > > >
> > > > > > > > > I've been looking into how a migration to using
> > > > > > > > > trusted/encrypted keys would look like (particularly with dm-
> > > > > > > > > crypt).
> > > > > > > > >
> > > > > > > > > Currently, it seems the the only way is to re-encrypt the
> > > > > > > > > partitions because trusted/encrypted keys always generate their
> > > > > > > > > payloads from RNG.
> > > > > > > > >
> > > > > > > > > If instead there was a key command to initialize a new
> > > > > > > > > trusted/encrypted key with a user provided value, users could
> > > > > > > > > use whatever mechanism they used beforehand to get a plaintext
> > > > > > > > > key and use that to initialize a new trusted/encrypted key.
> > > > > > > > > From there on, the key will be like any other trusted/encrypted
> > > > > > > > > key and not be disclosed again to userspace.
> > > > > > > > >
> > > > > > > > > What are your thoughts on this? Would an API like
> > > > > > > > >
> > > > > > > > > keyctl add trusted dmcrypt-key 'set <content>' # user-
> > > > > > > > > supplied content
> > > > > > > > >
> > > > > > > > > be acceptable?
> > > > > > > >
> > > > > > > > Maybe it's the lack of knowledge with dm-crypt, but why this
> > > > > > > > would be useful? Just want to understand the bottleneck, that's
> > > > > > > > all.
> > > > > >
> > > > > > Our goal in this case is to move away from having the dm-crypt key
> > > > > > material accessible to user-space on embedded devices. For an
> > > > > > existing dm-crypt volume, this key is fixed. A key can be loaded into
> > > > > > user key type and used by dm-crypt (cryptsetup can already do it this
> > > > > > way). But at this point, you can still do 'keyctl read' on that key,
> > > > > > exposing the key material to user space.
> > > > > >
> > > > > > Currently, with both encrypted and trusted keys, you can only
> > > > > > generate new random keys, not import existing key material.
> > > > > >
> > > > > > James Bottomley mentioned in the other reply that the key format will
> > > > > > become compatible with the openssl_tpm2_engine, which would provide a
> > > > > > workaround. This wouldn't work with OP-TEE-based trusted keys (see
> > > > > > Sumit Garg's series), though.
> > > > >
> > > > > Assuming OP-TEE has the same use model as the TPM, someone will
> > > > > eventually realise the need for interoperable key formats between key
> > > > > consumers and then it will work in the same way once the kernel gets
> > > > > updated to speak whatever format they come up with.
> > > >
> > > > IIUC, James re-work for TPM trusted keys is to allow loading of sealed
> > > > trusted keys directly via user-space (with proper authorization) into
> > > > the kernel keyring.
> > > >
> > > > I think similar should be achievable with OP-TEE (via extending pseudo
> > > > TA [1]) as well to allow restricted user-space access (with proper
> > > > authorization) to generate sealed trusted key blob that should be
> > > > interoperable with the kernel. Currently OP-TEE exposes trusted key
> > > > interfaces for kernel users only.
> > >
> > > What is the security benefit of having the key blob creation in user-space
> > > instead of in the kernel? Key import is a standard operation in HSMs or PKCS#11
> > > tokens.
> >
> > User authentication, AFAIK most of the HSMs or PKCS#11 require that
> > for key import. But IIUC, your suggested approach to load plain key
> > into kernel keyring and say it's *trusted* without any user
> > authentication, would it really be a trusted key? What prevents a
> > rogue user from making his key as the dm-crypt trusted key?
>
> There is user authentication at the level of key rings. So an untrusted user
> cannot load or link keys they have no write permission for.
Here, I meant user authentication to the trust source (TPM or a TEE)
which provides assurance for a key to be trusted. So what happens in
case of user-space compromises (an untrusted user gaining root
access)?
>
> As we already have user type keys, which don't have these restrictions and are
> accepted by most subsystems, any use of kernel keyrings must already make sure
> that the proper keys are used.
>
The major value add of trusted keys over user keys is this trust
assurance provided by the underlying trust source.
>
> With asymmetric keys we have trusted key *rings*:
> # keyctl show %:.secondary_trusted_keys
> Keyring
> 638775388 ---lswrv 0 0 keyring: .secondary_trusted_keys
> 1071890135 ---lswrv 0 0 \_ keyring: .builtin_trusted_keys
> 816294887 ---lswrv 0 0 \_ asymmetric: Debian Secure Boot CA: 6ccece7e4c6c0d1f6149f3dd27dfcc5cbb419ea1
> 630436721 ---lswrv 0 0 \_ asymmetric: Debian Secure Boot Signer 2020: 00b55eb3b9
> Here, a key is trusted because of it's presence in a keyring, not because it has
> a specific type. For example, fs-verity uses this mechanism as well.
>
>
> For the trusted key *type*, my understanding is that trusted refers to only
> being able to load and access them in specific "trusted" system states (via TPM
> PRC, TEE initialization via secure boot or SoC specific hardware status checks).
> So for example protecting against loading a data-encryption key into an unsigned
> kernel.
Along with that trusted keys assures protection against any
unauthorized user access to plain key payload.
>
> > > I mainly see the downside of having to add another API to access the underlying
> > > functionality (be it trusted key TA or the NXP CAAM HW *) and requiring
> > > platform-specific userspace code.
> >
> > I am not sure why you would call the standardized TEE interface [1] to
> > be platform-specific, it is meant to be platform agnostic. And I think
> > we can have openssl_tee_engine on similar lines as the
> > openssl_tpm2_engine.
>
> Sorry, I meant platform-specific in the sense that some platforms use TPMs,
> while others use TEEs. The trusted key type was also suggested several times as
> the correct abstraction for SoC-specific key encapsulation hardware (instead of
> custom interfaces), so there will likely be platforms which don't have a TPM or
> TEE, but still trusted keys.
>
Agree and for that particular reason we are trying to add an
abstraction layer in trusted keys subsystem so that other trust
sources apart from TPM or TEE can be supported as well.
-Sumit
> Regards
> Jan
>
> > [1] https://globalplatform.org/specs-library/tee-client-api-specification/
> >
>
>
> --
> Pengutronix e.K. | |
> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
On Mon, 2021-02-01 at 14:46 -0500, Mimi Zohar wrote:
> On Mon, 2021-02-01 at 17:38 +0100, Jan Lübbe wrote:
> > On Mon, 2021-02-01 at 11:11 -0500, Mimi Zohar wrote:
> > > On Mon, 2021-02-01 at 16:31 +0100, Jan Lübbe wrote:
> > > > On Sun, 2021-01-31 at 09:29 -0500, Mimi Zohar wrote:
> > <snip>
> > > > > Usage::
> > > > >
> > > > > keyctl add encrypted name "new [format] key-type:master-key-name keylen"
> > > > > ring
> > > > > keyctl add encrypted name "load hex_blob" ring
> > > >
> > > > 'load' (as I understand the code) only accepts an encrypted blob.
> > > >
> > > > So the only way I see to have an encrypted key with a non-random key data would
> > > > be:
> > > > - create a random temporary master key and load a copy as a user key
> > > > - encrypt the chosen key data with the temporary master key (using a new
> > > > userspace reimplementation of the kernel encrypted key blob format)
> > > > - use keyctl add encrypted dmcrypt "load <encrypted blob>" <keyring>
> > > > - create new trusted master key (OP-TEE or CAAM in our case) as
> > > > - use keyctl update to switch to the new trusted master key
> > > > - use keyctl pipe on the trusted and encrypted keys and store both for loading
> > > > on later boots
> > > >
> > > > If we'd support importing a pre-existing key into a trusted or encrypted key,
> > > > we'd do instead:
> > > > - use keyctl add trusted dmcrypt "import <unencrypted key data>"
> > > > - use keyctl pipe on the trusted key and store it for loading on later boots
> > > >
> > > > This way, users wouldn't need to care which backend is used by trusted keys
> > > > (TPM/OP-TEE/CAAM/...). That would make use-cases where a random key is not
> > > > suitable as straight-forward as the those where a random key is OK.
> > >
> > > As I said above, the "encrypted" key update doesn't change the key data
> > > used for encrypting/decrypting storage in the dm-crypt case, it just
> > > updates the key under which it is encrypted/signed.
> >
> > Yes, that's clear. I only used it to demonstrate how a workaround for importing
> > key material into an encrypted key could look like.
> >
> > > Yes, the reason for using an encrypted "trusted" key, as opposed to an
> > > encrypted "user" key, is that the "trusted" key is encrypted/decrypted
> > > by the TPM and never exposed to userspace in the clear.
> >
> > Yes, and that's the main reason I'd like to use trusted keys with dm-crypt: a
> > much lower chance of exposing this key somewhere it could be extracted.
> >
> > > It doesn't sound like you're wanting to update the storage key in the
> > > field, just the key used to encrypt/decrypt that key. So I'm still not
> > > clear as to why you would want an initial non-random encrypted key.
> > > Providing that key on the command line certaining isn't a good idea.
> >
> > Some of our customers have systems in the field which use non-mainline patches
> > for access to the CAAM [1], which also have the downside of exposing the
> > decrypted key material directly to userspace. In that thread you suggested to
> > use trusted keys instead. With Sumit's work that rework is finally within reach.
> > :)
> >
> >
> > In those systems, we have data that's encrypted with a pre-existing dm-crypt or
> > ecryptfs key. As we update those systems in the field to newer kernels, we want
> > to get rid of those custom patches, but can't reencrypt everything.
> >
> > So the approach would be to perform a one-time migration when updating a device:
> > - use our old interface to decrypt the key and 'import' it into a trusted key
> > - use keyctl pipe and save the re-encrypted key to disk
> > - destroy the old encrypted key
> > After this migration, the key material is no longer available to userspace (only
> > to dm-crypt).
> >
> >
> > Another use-case for supporting key import that we want to support is analysis
> > of broken devices returned from the field:
> > - generate an encryption key per device in the factory
> > - encrypt it to a private key in escrow and archive it for later use
> > - import it into a trusted key on the device
> > - keyctl pipe it to a file on the device for use on boot
> >
> > Later, when you need to do an analysis, you can get the key from escrow even if
> > the device cannot boot any longer.
>
> The first use case doesn't sound like a valid reason for upstreaming
> such support. It's a one time update to migrate everyone to a newer
> kernel. That you can carry independently of upstream. In terms of the
> second use case, do you really want the ability and the resulting
> responsibility of being able to decrypt user's data? Please think
> this through carefully, before you decide you really want/need this
> feature.
As it seems that this feature would not be appropriate for all use-cases and
threat models, I wonder if making it optional would be acceptable. Something
like:
config TRUSTED_KEYS_IMPORT
bool "Allow creating TRUSTED KEYS from existing key material"
depends on TRUSTED_KEYS
help
This option adds support for creating new trusted keys from existing
key material supplied by userspace, instead of using random numbers.
As with random trusted keys, userspace cannot extract the plain-text
key material again and will only ever see encrypted blobs.
This option should *only* be enabled for use in a trusted
environment (such as during debugging/development or in a secured
factory). Also, consider using 'keyctl padd' instead of 'keyctl add'
to avoid exposing the plain-text key on the process command line.
If you are unsure as to whether this is required, answer N.
Best regards,
Jan
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Mon, 2021-02-08 at 15:38 +0100, Jan L?bbe wrote:
> As it seems that this feature would not be appropriate for all use-cases and
> threat models, I wonder if making it optional would be acceptable. Something
> like:
>
> config TRUSTED_KEYS_IMPORT
To me "IMPORT" implies from a trusted source, which this is not.
Perhaps "UNSAFE_IMPORT", "DEBUGGING_IMPORT, "DEVELOPMENT_IMPORT", ...
Defining a Kconfig with any of these names and the other changes below,
makes it very clear using predefined key data is not recommended. My
concern with extending trusted keys to new trust sources is the
implication that the security/integrity is equivalent to the existing
discrete TPM.
> bool "Allow creating TRUSTED KEYS from existing key material"
> depends on TRUSTED_KEYS
Missing "default n"
> help
> This option adds support for creating new trusted keys from existing
> key material supplied by userspace, instead of using random numbers.
> As with random trusted keys, userspace cannot extract the plain-text
Once defined, as with random trusted keys, userspace cannot ...
> key material again and will only ever see encrypted blobs.
>
> This option should *only* be enabled for use in a trusted
> environment (such as during debugging/development or in a secured
> factory). Also, consider using 'keyctl padd' instead of 'keyctl add'
Even the "secured factory" is not a good idea. Please limit the usage
to debugging/development.
> to avoid exposing the plain-text key on the process command line.
>
> If you are unsure as to whether this is required, answer N.
The above would be fine.
thanks,
Mimi
On Mon, 2021-02-08 at 16:50 -0500, Mimi Zohar wrote:
> On Mon, 2021-02-08 at 15:38 +0100, Jan Lübbe wrote:
>
> > As it seems that this feature would not be appropriate for all use-cases and
> > threat models, I wonder if making it optional would be acceptable. Something
> > like:
> >
> > config TRUSTED_KEYS_IMPORT
>
> To me "IMPORT" implies from a trusted source, which this is not.
> Perhaps "UNSAFE_IMPORT", "DEBUGGING_IMPORT, "DEVELOPMENT_IMPORT", ...
>
> Defining a Kconfig with any of these names and the other changes below,
> makes it very clear using predefined key data is not recommended. My
> concern with extending trusted keys to new trust sources is the
> implication that the security/integrity is equivalent to the existing
> discrete TPM.
>
> > bool "Allow creating TRUSTED KEYS from existing key material"
> > depends on TRUSTED_KEYS
>
> Missing "default n"
According to Documentation/kbuild/kconfig-language.rst: "The default value
deliberately defaults to 'n' in order to avoid bloating the build.". So an
explicit "default n" should not be needed. I'll add it though, for now.
> > help
> > This option adds support for creating new trusted keys from
> > existing
> > key material supplied by userspace, instead of using random
> > numbers.
> > As with random trusted keys, userspace cannot extract the plain-
> > text
>
> Once defined, as with random trusted keys, userspace cannot ...
>
> > key material again and will only ever see encrypted blobs.
> >
> >
> > This option should *only* be enabled for use in a trusted
> > environment (such as during debugging/development or in a secured
> > factory). Also, consider using 'keyctl padd' instead of 'keyctl
> > add'
>
> Even the "secured factory" is not a good idea. Please limit the usage
> to debugging/development.
>
> > to avoid exposing the plain-text key on the process command line.
> >
> > If you are unsure as to whether this is required, answer N.
>
> The above would be fine.
OK, that would result in:
config TRUSTED_KEYS_DEVELOPMENT_IMPORT
bool "Allow creating TRUSTED KEYS from existing key material for development"
depends on TRUSTED_KEYS
default n
help
This option adds support for creating new trusted keys from
existing key material supplied by userspace, instead of using
random numbers. Once defined, as with random trusted keys,
userspace cannot extract the plain-text key material again
and will only ever see encrypted blobs.
This option should *only* be enabled for debugging/development.
Also, consider using 'keyctl padd' instead of 'keyctl add' to
avoid exposing the plain-text key on the process command line.
If you are unsure as to whether this is required, answer N.
Thanks,
Jan
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |