lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAMRc=MdO=vPrvvonJPJ=1Lp0vFTRBtsEBUS5aqWp4yMqUtgfzw@mail.gmail.com>
Date: Tue, 25 Mar 2025 21:23:09 +0100
From: Bartosz Golaszewski <brgl@...ev.pl>
To: Herbert Xu <herbert@...dor.apana.org.au>, Kees Cook <kees@...nel.org>, 
	Jens Wiklander <jens.wiklander@...aro.org>, Joakim Bech <joakim.bech@...aro.org>
Cc: "open list:HARDWARE RANDOM NUMBER GENERATOR CORE" <linux-crypto@...r.kernel.org>, 
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>, 
	Srinivas Kandagatla <srinivas.kandagatla@...aro.org>, Daniel Perez-Zoghbi <dperezzo@...cinc.com>, 
	Gaurav Kashyap <gaurkash@....qualcomm.com>, Udit Tiwari <utiwari@....qualcomm.com>, 
	Md Sadre Alam <mdalam@....qualcomm.com>, Amirreza Zarrabi <quic_azarrabi@...cinc.com>
Subject: Extending the kernel crypto uAPI to support decryption into secure buffers

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/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ