public inbox for linux-crypto@vger.kernel.org
 help / color / mirror / Atom feed
* Extending the kernel crypto uAPI to support decryption into secure buffers
@ 2025-03-25 20:23 Bartosz Golaszewski
  2025-03-26 16:59 ` Eric Biggers
  0 siblings, 1 reply; 3+ messages in thread
From: Bartosz Golaszewski @ 2025-03-25 20:23 UTC (permalink / raw)
  To: Herbert Xu, Kees Cook, Jens Wiklander, Joakim Bech
  Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE,
	Linux Kernel Mailing List, Srinivas Kandagatla,
	Daniel Perez-Zoghbi, Gaurav Kashyap, Udit Tiwari, Md Sadre Alam,
	Amirreza Zarrabi

Hi Herbert et al!

There are many out-of-tree implementations of DRM stacks (Widevine or
otherwise) by several vendors out there but so far there's none using
mainline kernel exclusively.

Now that Jens' work[1] on restricted DMA buffers is pretty far along
as is the QTEE implementation from Amirreza, most pieces seem to be
close to falling into place and I'd like to tackl
e the task of implementing Widevine for Qualcomm platforms on linux.

I know that talk is cheap but before I show any actual code, I'd like
to first discuss the potential extensions to the kernel crypto uAPI
that this work would require.

First: why would we need any changes to the crypto uAPI at all? After
all other existing implementations typically go around it and talk
directly to the TrustZone. That's right but IMO t
here's some benefit of factoring out the common low-level elements
behind a well-known abstraction layer. Especially since TA
implementations may differ. Also: in the case of the Qualcom
m trusted OS, the single-threaded implementation makes it preferable
to offload only a limited set of operations to the TA to not keep it
overly busy so a dedicated kernel driver can han
dle most of the crypto engine's functionality on the linux side.

And in general being able to decrypt into secure buffers may benefit
other use-cases too.

There are at least two points that need addressing in the crypto uAPI.

1. Support for secure keys.

This can be approached in two ways:

- We may expect users to already have generated the secure keys from
user-space directly over the TEE interface, retrieve some kind of a
handle (secure key index, wrapped key, TBD) and p
ass it down to the crypto framework via setsockopt().

We'd probably need to add a new optname: ALG_SET_SECURE_KEY or
ALG_SELECT_SECURE_KEY or even ALG_SELECT_KEY in order to differentiate
from the raw keys passed alongside ALG_SET_KEY.

The underlying crypto driver would then have to be able to select the
key from the TZ. In this scenario the crypto core assumes the keys are
already programmed in the secure enclave and
it's just a matter of selecting the right one.

- We may also prefer to do everything via the crypto uAPI, including
generating secure keys. This has the benefit of adding a nice
abstraction layer for various trusted OS implementation
s which differ from one vendor to another.

To that end we'd need to introduce a new af_alg_type instance that
would allow us to manage secure keys via setsockopt() or
read()/write() in addition to the above.

An example user-space side would look like this:

struct sockaddr_alg sa = {
   .salg_family = AF_ALG,
   .salg_type = "securekey",
   .salg_name = "qtee", /* Qualcomm TEE implementation */
};

sock = socket(...);
bind(...);
fd = accept(sock, ...);
header->cmsg_level = SOL_ALG;
header->cmsg_type = ALG_GENERATE_KEY;
sendmsg()

2. Decrypting data into secure buffers.

Here we'd need two things:

- passing file descriptors associated with secure buffers to the crypto API

Other than using setsockopt() to select the secure key, selecting a
symmetric cypher wouldn't differ from raw implementations but the
message we're sending over sendmsg() would need to c
ontain another entry that would contain the file descriptor associated
with the secure buffer. To that end I imagine adding a new socket
option code: ALG_SET_MEM_FD.

- one-way decryption into the secure buffer

This would mean that the write() of encrypted data into the socket
would not be paired with a corresponding read() of the decrypted data
back into user-space. Instead, we'd need a mechan
ism of getting notified that the decryption completed (successfully or
with an error). That could be achieved by polling the socket for
POLLIN | POLLERR. A read() on such a descriptor wo
uld return -EOPNOTSUPP.

Please let me know your thoughts on this and whether any of the above
even makes sense. If it's not a terrible approach, I will start
working on a functional PoC. Please note, that I'm n
ot very well versed in linux crypto so I may very well be talking
nonsense. In that case any advice is welcome.

Thanks,
Bartosz

[1] https://lore.kernel.org/all/20250305130634.1850178-1-jens.wiklander@linaro.org/
[2] https://lore.kernel.org/lkml/20250202-qcom-tee-using-tee-ss-without-mem-obj-v2-0-297eacd0d34f@quicinc.com/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Extending the kernel crypto uAPI to support decryption into secure buffers
  2025-03-25 20:23 Extending the kernel crypto uAPI to support decryption into secure buffers Bartosz Golaszewski
@ 2025-03-26 16:59 ` Eric Biggers
  2025-03-28 10:56   ` Bartosz Golaszewski
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Biggers @ 2025-03-26 16:59 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Herbert Xu, Kees Cook, Jens Wiklander, Joakim Bech,
	open list:HARDWARE RANDOM NUMBER GENERATOR CORE,
	Linux Kernel Mailing List, Srinivas Kandagatla,
	Daniel Perez-Zoghbi, Gaurav Kashyap, Udit Tiwari, Md Sadre Alam,
	Amirreza Zarrabi

On Tue, Mar 25, 2025 at 09:23:09PM +0100, Bartosz Golaszewski wrote:
> Hi Herbert et al!
> 
> There are many out-of-tree implementations of DRM stacks (Widevine or
> otherwise) by several vendors out there but so far there's none using
> mainline kernel exclusively.
> 
> Now that Jens' work[1] on restricted DMA buffers is pretty far along
> as is the QTEE implementation from Amirreza, most pieces seem to be
> close to falling into place and I'd like to tackl
> e the task of implementing Widevine for Qualcomm platforms on linux.
> 
> I know that talk is cheap but before I show any actual code, I'd like
> to first discuss the potential extensions to the kernel crypto uAPI
> that this work would require.
> 
> First: why would we need any changes to the crypto uAPI at all? After
> all other existing implementations typically go around it and talk
> directly to the TrustZone. That's right but IMO t
> here's some benefit of factoring out the common low-level elements
> behind a well-known abstraction layer. Especially since TA
> implementations may differ. Also: in the case of the Qualcom
> m trusted OS, the single-threaded implementation makes it preferable
> to offload only a limited set of operations to the TA to not keep it
> overly busy so a dedicated kernel driver can han
> dle most of the crypto engine's functionality on the linux side.
> 
> And in general being able to decrypt into secure buffers may benefit
> other use-cases too.
> 
> There are at least two points that need addressing in the crypto uAPI.
> 
> 1. Support for secure keys.
> 
> This can be approached in two ways:
> 
> - We may expect users to already have generated the secure keys from
> user-space directly over the TEE interface, retrieve some kind of a
> handle (secure key index, wrapped key, TBD) and p
> ass it down to the crypto framework via setsockopt().
> 
> We'd probably need to add a new optname: ALG_SET_SECURE_KEY or
> ALG_SELECT_SECURE_KEY or even ALG_SELECT_KEY in order to differentiate
> from the raw keys passed alongside ALG_SET_KEY.
> 
> The underlying crypto driver would then have to be able to select the
> key from the TZ. In this scenario the crypto core assumes the keys are
> already programmed in the secure enclave and
> it's just a matter of selecting the right one.
> 
> - We may also prefer to do everything via the crypto uAPI, including
> generating secure keys. This has the benefit of adding a nice
> abstraction layer for various trusted OS implementation
> s which differ from one vendor to another.
> 
> To that end we'd need to introduce a new af_alg_type instance that
> would allow us to manage secure keys via setsockopt() or
> read()/write() in addition to the above.
> 
> An example user-space side would look like this:
> 
> struct sockaddr_alg sa = {
>    .salg_family = AF_ALG,
>    .salg_type = "securekey",
>    .salg_name = "qtee", /* Qualcomm TEE implementation */
> };
> 
> sock = socket(...);
> bind(...);
> fd = accept(sock, ...);
> header->cmsg_level = SOL_ALG;
> header->cmsg_type = ALG_GENERATE_KEY;
> sendmsg()
> 
> 2. Decrypting data into secure buffers.
> 
> Here we'd need two things:
> 
> - passing file descriptors associated with secure buffers to the crypto API
> 
> Other than using setsockopt() to select the secure key, selecting a
> symmetric cypher wouldn't differ from raw implementations but the
> message we're sending over sendmsg() would need to c
> ontain another entry that would contain the file descriptor associated
> with the secure buffer. To that end I imagine adding a new socket
> option code: ALG_SET_MEM_FD.
> 
> - one-way decryption into the secure buffer
> 
> This would mean that the write() of encrypted data into the socket
> would not be paired with a corresponding read() of the decrypted data
> back into user-space. Instead, we'd need a mechan
> ism of getting notified that the decryption completed (successfully or
> with an error). That could be achieved by polling the socket for
> POLLIN | POLLERR. A read() on such a descriptor wo
> uld return -EOPNOTSUPP.
> 
> Please let me know your thoughts on this and whether any of the above
> even makes sense. If it's not a terrible approach, I will start
> working on a functional PoC. Please note, that I'm n
> ot very well versed in linux crypto so I may very well be talking
> nonsense. In that case any advice is welcome.
> 
> Thanks,
> Bartosz
> 
> [1] https://lore.kernel.org/all/20250305130634.1850178-1-jens.wiklander@linaro.org/
> [2] https://lore.kernel.org/lkml/20250202-qcom-tee-using-tee-ss-without-mem-obj-v2-0-297eacd0d34f@quicinc.com/

What would you get out of building this on top of AF_ALG, vs. building a new
UAPI from scratch?  There seem to be an awful lot of differences between what
this needs and what AF_ALG does.

- Eric

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Extending the kernel crypto uAPI to support decryption into secure buffers
  2025-03-26 16:59 ` Eric Biggers
@ 2025-03-28 10:56   ` Bartosz Golaszewski
  0 siblings, 0 replies; 3+ messages in thread
From: Bartosz Golaszewski @ 2025-03-28 10:56 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Herbert Xu, Kees Cook, Jens Wiklander, Joakim Bech,
	open list:HARDWARE RANDOM NUMBER GENERATOR CORE,
	Linux Kernel Mailing List, Srinivas Kandagatla,
	Daniel Perez-Zoghbi, Gaurav Kashyap, Udit Tiwari, Md Sadre Alam,
	Amirreza Zarrabi

On Wed, Mar 26, 2025 at 5:59 PM Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Tue, Mar 25, 2025 at 09:23:09PM +0100, Bartosz Golaszewski wrote:
> >
> > There are many out-of-tree implementations of DRM stacks (Widevine or
> > otherwise) by several vendors out there but so far there's none using
> > mainline kernel exclusively.
> >
> > Now that Jens' work[1] on restricted DMA buffers is pretty far along
> > as is the QTEE implementation from Amirreza, most pieces seem to be
> > close to falling into place and I'd like to tackl
> > e the task of implementing Widevine for Qualcomm platforms on linux.
> >
> > I know that talk is cheap but before I show any actual code, I'd like
> > to first discuss the potential extensions to the kernel crypto uAPI
> > that this work would require.
> >
>
> What would you get out of building this on top of AF_ALG, vs. building a new
> UAPI from scratch?  There seem to be an awful lot of differences between what
> this needs and what AF_ALG does.
>

I don't have much against building it from scratch. If anything, I
would love me a green-field kernel development instead of tweaking
existing code, it would probably make the work much more enjoyable.

But if I'm being honest, it's hard to tell whether there are more
differences than similarities. A big part of the existing crypto code
- especially the driver boiler-plate - could potentially be reused as
could the existing netlink infrastructure for setsockopt() and
write().

That being said: if I were to design a new interface for this, I would
probably not go with netlink and instead provide a regular character
device (let's say: /dev/secure_crypto) with a set of ioctls() for key,
cipher and general management and support for write() for data
decryption. IMO socket() interface is so much more clunky than
chardev.

Bartosz

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-03-28 10:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-25 20:23 Extending the kernel crypto uAPI to support decryption into secure buffers Bartosz Golaszewski
2025-03-26 16:59 ` Eric Biggers
2025-03-28 10:56   ` Bartosz Golaszewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox