mbox series

[0/4] firmware: Add support for Qualcomm UEFI Secure Application

Message ID 20220723224949.1089973-1-luzmaximilian@gmail.com
Headers show
Series firmware: Add support for Qualcomm UEFI Secure Application | expand

Message

Maximilian Luz July 23, 2022, 10:49 p.m. UTC
On modern Qualcomm platforms, access to EFI variables is restricted to
the secure world / TrustZone, i.e. the Trusted Execution Environment
(TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
therefore need to talk to the UEFI Secure Application (uefisecapp),
residing in the TrEE.

This series adds support for accessing EFI variables on those platforms.

To do this, we first need to add some SCM call functions used to manage
and talk to Secure Applications. A very small subset of this interface
is added in the second patch (whereas the first one exports the required
functions for that). Interface specifications are extracted from [1].
While this does not (yet) support re-entrant SCM calls (including
callbacks and listeners), this is enough to talk to the aforementioned
uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
Yoga C630 devices).

The third patch adds a client driver for uefisecapp, installing the
respective efivar operations. The application interface has been reverse
engineered from the Windows QcTrEE8180.sys driver.

Apart from uefisecapp, there are more Secure Applications running that
we might want to support in the future. For example, on the Surface Pro
X (sc8180x-based), the TPM is also managed via one.

I'm not sure whether this should go to drivers/firmware or to
drivers/soc/qcom. I've put this into firmware as all of this is
essentially an interface to the secure firmware running in the TrustZone
(and SCM stuff is handled here already), but please let me know if I
should move this.

Regards,
Max

[1]: https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/auto-kernel.lnx.4.14.c34/drivers/misc/qseecom.c

Maximilian Luz (4):
  firmware: qcom_scm: Export SCM call functions
  firmware: Add support for Qualcomm Trusted Execution Environment SCM
    calls
  firmware: Add support for Qualcomm UEFI Secure Application
  dt-bindings: firmware: Add Qualcomm UEFI Secure Application client

 .../firmware/qcom,tee-uefisecapp.yaml         |  38 +
 MAINTAINERS                                   |  14 +
 drivers/firmware/Kconfig                      |  20 +
 drivers/firmware/Makefile                     |   2 +
 drivers/firmware/qcom_scm.c                   | 118 ++-
 drivers/firmware/qcom_scm.h                   |  47 --
 drivers/firmware/qcom_tee.c                   | 213 +++++
 drivers/firmware/qcom_tee_uefisecapp.c        | 761 ++++++++++++++++++
 include/linux/qcom_scm.h                      |  49 ++
 include/linux/qcom_tee.h                      | 179 ++++
 10 files changed, 1355 insertions(+), 86 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/firmware/qcom,tee-uefisecapp.yaml
 create mode 100644 drivers/firmware/qcom_tee.c
 create mode 100644 drivers/firmware/qcom_tee_uefisecapp.c
 create mode 100644 include/linux/qcom_tee.h

Comments

Rob Herring July 25, 2022, 7:27 p.m. UTC | #1
On Sun, Jul 24, 2022 at 12:49:45AM +0200, Maximilian Luz wrote:
> On modern Qualcomm platforms, access to EFI variables is restricted to
> the secure world / TrustZone, i.e. the Trusted Execution Environment
> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
> therefore need to talk to the UEFI Secure Application (uefisecapp),
> residing in the TrEE.

The whole point of UEFI is providing a standard interface. Why can't the 
UEFI implementation call the TEE itself?

I'm not sure custom interfaces is something we want.


> This series adds support for accessing EFI variables on those platforms.
> 
> To do this, we first need to add some SCM call functions used to manage
> and talk to Secure Applications. A very small subset of this interface
> is added in the second patch (whereas the first one exports the required
> functions for that). Interface specifications are extracted from [1].
> While this does not (yet) support re-entrant SCM calls (including
> callbacks and listeners), this is enough to talk to the aforementioned
> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
> Yoga C630 devices).

What does Windows do on these devices? I'm surprised something like this 
would fly with Microsoft.

Rob
Maximilian Luz July 25, 2022, 8:16 p.m. UTC | #2
On 7/25/22 21:27, Rob Herring wrote:
> On Sun, Jul 24, 2022 at 12:49:45AM +0200, Maximilian Luz wrote:
>> On modern Qualcomm platforms, access to EFI variables is restricted to
>> the secure world / TrustZone, i.e. the Trusted Execution Environment
>> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
>> therefore need to talk to the UEFI Secure Application (uefisecapp),
>> residing in the TrEE.
> 
> The whole point of UEFI is providing a standard interface. Why can't the
> UEFI implementation call the TEE itself?
> 
> I'm not sure custom interfaces is something we want.

Unfortunately, I'm not a Qualcomm engineer and in no way affiliated with
them. So I probably can't convince them otherwise. Believe me, I'd like
to :/

First: The uefisecapp-driver is based on reverse-engineering. So please
take things below with a grain of salt, I may be wrong. I've tried to
lay this out in a bit more detail in patch 3, but I'll try to be more
precise here:

For some reason unknown to me, Qualcomm decided to lock away UEFI
variable access via their TrEE framework for applications running in the
TrustZone (or whatever that is exactly). To call to TrEE applications
(like uefisecapp), they use SCM calls. Those SCM calls unfortunately can
be a bit more complex. As far as I can tell, you essentially call to
some hypervisor in the TrustZone which redistributes them (if necessary)
to the respective application. Their downstream driver for that is at
[1] and supports callbacks and re-entrant calls. As far as I can tell,
the latter means that you can't run multiple SCM calls in parallel (at
least not to that TzOS/TrEE interface) and can only ever have one
"client" performing them.

And as you can only ever have one entity performing those SCM calls, you
cannot have both UEFI and the kernel doing them. To me, it seems to be a
deliberate decision by Qualcomm to return EFI_UNSUPPORTED from the
GetVariable etc. calls after exiting boot services. They do work just
fine before that. Essentially exiting boot services transfers ownership
of that SCM interface from UEFI to the kernel.

Note: uefisecapp is also not the only TrEE application in use by those
kinds of devices. For example, on the SC8180X based Surface Pro X that
I'm using, there are at least an app for the TPM, a bunch of apps for
HDCP, some winsecapp, and as far as I can tell also other cryptographic
interfaces. I've tried to collect my findings about those in [2].

>> This series adds support for accessing EFI variables on those platforms.
>>
>> To do this, we first need to add some SCM call functions used to manage
>> and talk to Secure Applications. A very small subset of this interface
>> is added in the second patch (whereas the first one exports the required
>> functions for that). Interface specifications are extracted from [1].
>> While this does not (yet) support re-entrant SCM calls (including
>> callbacks and listeners), this is enough to talk to the aforementioned
>> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
>> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
>> Yoga C630 devices).
> 
> What does Windows do on these devices? I'm surprised something like this
> would fly with Microsoft.

It looks like Microsoft accepts this. They even seem to have some sort
of interface for EFI variables via trusted execution environments: [3].
This is essentially what the QcTrEE8180.sys driver I've reverse
engineered this from seems to provide.

So unless there's some way to make EFI variables work via the standard
functions that I've missed, I don't see any alternatives. I think it's
fairly unlikely that we can convince Qualcomm to make their UEFI
implementation behave properly (variables are not the only issue, it
seems that other functions are either partially or completely broken in
some way or another...) and then also push updates for a bunch of
devices (e.g. the Lenovo C630 also using this stuff is discontinued, as
far as I can tell).

I am open to suggestions though...

Note that this series also doesn't really introduce a new interface for
EFI variables themselves to the kernel. It relies on the existing
efivars_register() / efivars_unregister() functions and the interface
provided by them to enable access to EFI variables. So we already do
have a "workaround" for broken UEFI variable access in the kernel.

Regards,
Max

[1]: https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/auto-kernel.lnx.4.14.c34/drivers/misc/qseecom.c
[2]: https://github.com/linux-surface/surface-pro-x/issues/37
[3]: https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.16299.0/km/treevariableservice.h#L11-L12
Srinivas Kandagatla Aug. 2, 2022, 11:51 a.m. UTC | #3
Hi Maximilian,

On 23/07/2022 23:49, Maximilian Luz wrote:
> On modern Qualcomm platforms, access to EFI variables is restricted to
> the secure world / TrustZone, i.e. the Trusted Execution Environment
> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
> therefore need to talk to the UEFI Secure Application (uefisecapp),
> residing in the TrEE.
> 
> This series adds support for accessing EFI variables on those platforms.
> 
> To do this, we first need to add some SCM call functions used to manage
> and talk to Secure Applications. A very small subset of this interface
> is added in the second patch (whereas the first one exports the required
> functions for that). Interface specifications are extracted from [1].
> While this does not (yet) support re-entrant SCM calls (including
> callbacks and listeners), this is enough to talk to the aforementioned
> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
> Yoga C630 devices).
> 
> The third patch adds a client driver for uefisecapp, installing the
> respective efivar operations. The application interface has been reverse
> engineered from the Windows QcTrEE8180.sys driver.
> 
> Apart from uefisecapp, there are more Secure Applications running that
> we might want to support in the future. For example, on the Surface Pro
> X (sc8180x-based), the TPM is also managed via one.
> 
> I'm not sure whether this should go to drivers/firmware or to
> drivers/soc/qcom. I've put this into firmware as all of this is
> essentially an interface to the secure firmware running in the TrustZone
> (and SCM stuff is handled here already), but please let me know if I
> should move this.

 From what I see so far is that this is adapted from downstream qseecom 
driver, this approach could work for a limited usecases but not 
scalable, as we cannot add drivers for each Qualcomm specific TA in kernel.
This has to be handled in much generic way using Linux TEE framework, 
and let the userspace side deal with TA specific bits.

AFAIU, Qualcomm is moving away from qseecom interface to new smc-invoke 
interface, most of Qualcomm SoCs starting from SDM660 already have 
support to this.

This interface provides a better abstracted IPC mechanism to talk to TA. 
Most of these TA specific interfaces are packed in closed userspace source.
Having said that QTEE smcinvoke driver can be modeled as a proper TEE 
driver with Userspace driving the TA specific bits using existing tee uapis.
This also brings in other features like loading, Listeners aka 
callbacks, secure memory allocations..etc.

In the past, I have tried to do a prototype of this smcinvoke driver as 
a proper tee driver, incase you are interested patches are at 
https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=tracking-qcomlt-qcomtee
Plan is to discuss with Qualcomm and send it for upstream review.


I think its worth exploring if uefisecapp can talk smcinvoke.
I can ping Qualcomm engineers to see if that is doable.


thanks,
Srini


> 
> Regards,
> Max
> 
> [1]: https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/auto-kernel.lnx.4.14.c34/drivers/misc/qseecom.c
> 
> Maximilian Luz (4):
>    firmware: qcom_scm: Export SCM call functions
>    firmware: Add support for Qualcomm Trusted Execution Environment SCM
>      calls
>    firmware: Add support for Qualcomm UEFI Secure Application
>    dt-bindings: firmware: Add Qualcomm UEFI Secure Application client
> 
>   .../firmware/qcom,tee-uefisecapp.yaml         |  38 +
>   MAINTAINERS                                   |  14 +
>   drivers/firmware/Kconfig                      |  20 +
>   drivers/firmware/Makefile                     |   2 +
>   drivers/firmware/qcom_scm.c                   | 118 ++-
>   drivers/firmware/qcom_scm.h                   |  47 --
>   drivers/firmware/qcom_tee.c                   | 213 +++++
>   drivers/firmware/qcom_tee_uefisecapp.c        | 761 ++++++++++++++++++
>   include/linux/qcom_scm.h                      |  49 ++
>   include/linux/qcom_tee.h                      | 179 ++++
>   10 files changed, 1355 insertions(+), 86 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/firmware/qcom,tee-uefisecapp.yaml
>   create mode 100644 drivers/firmware/qcom_tee.c
>   create mode 100644 drivers/firmware/qcom_tee_uefisecapp.c
>   create mode 100644 include/linux/qcom_tee.h
>
Maximilian Luz Aug. 2, 2022, 1:22 p.m. UTC | #4
On 8/2/22 13:51, Srinivas Kandagatla wrote:
> Hi Maximilian,
> 
> On 23/07/2022 23:49, Maximilian Luz wrote:
>> On modern Qualcomm platforms, access to EFI variables is restricted to
>> the secure world / TrustZone, i.e. the Trusted Execution Environment
>> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
>> therefore need to talk to the UEFI Secure Application (uefisecapp),
>> residing in the TrEE.
>>
>> This series adds support for accessing EFI variables on those platforms.
>>
>> To do this, we first need to add some SCM call functions used to manage
>> and talk to Secure Applications. A very small subset of this interface
>> is added in the second patch (whereas the first one exports the required
>> functions for that). Interface specifications are extracted from [1].
>> While this does not (yet) support re-entrant SCM calls (including
>> callbacks and listeners), this is enough to talk to the aforementioned
>> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
>> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
>> Yoga C630 devices).
>>
>> The third patch adds a client driver for uefisecapp, installing the
>> respective efivar operations. The application interface has been reverse
>> engineered from the Windows QcTrEE8180.sys driver.
>>
>> Apart from uefisecapp, there are more Secure Applications running that
>> we might want to support in the future. For example, on the Surface Pro
>> X (sc8180x-based), the TPM is also managed via one.
>>
>> I'm not sure whether this should go to drivers/firmware or to
>> drivers/soc/qcom. I've put this into firmware as all of this is
>> essentially an interface to the secure firmware running in the TrustZone
>> (and SCM stuff is handled here already), but please let me know if I
>> should move this.
> 
>  From what I see so far is that this is adapted from downstream qseecom driver, this approach could work for a limited usecases but not scalable, as we cannot add drivers for each Qualcomm specific TA in kernel.
> This has to be handled in much generic way using Linux TEE framework, and let the userspace side deal with TA specific bits.

I generally agree with the sentiment, however UEFI variables should IMHO be
handled by the kernel. Moving handling of those to userspace breaks things like
EFI-based pstore and efivarfs. The latter will in turn break some user-space
tools (most notably efibootmgr used by e.g. GRUB and I think fwupdmgr which
needs to set some capsule variables). Ideally, we would find a way to not break
these, i.e. have them work out-of-the-box.

A similar argumentation might apply to the TPM app.

> AFAIU, Qualcomm is moving away from qseecom interface to new smc-invoke interface, most of Qualcomm SoCs starting from SDM660 already have support to this.
> 
> This interface provides a better abstracted IPC mechanism to talk to TA. Most of these TA specific interfaces are packed in closed userspace source.
> Having said that QTEE smcinvoke driver can be modeled as a proper TEE driver with Userspace driving the TA specific bits using existing tee uapis.
> This also brings in other features like loading, Listeners aka callbacks, secure memory allocations..etc.
> 
> In the past, I have tried to do a prototype of this smcinvoke driver as a proper tee driver, incase you are interested patches are at https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=tracking-qcomlt-qcomtee
> Plan is to discuss with Qualcomm and send it for upstream review.

Thanks for this information! So as far as I understand it, this is currently an
interface to user-space only, i.e. does not allow in-kernel drivers for apps?
It would be great if this could then be extended to handle (the bare minimum
of) in-kernel drivers (i.e. only things that the kernel itself needs, like EFI
variables). Alternatively, I'm happy to hear suggestions on how we not break
the aforementioned things while moving handling off to userspace.

> I think its worth exploring if uefisecapp can talk smcinvoke.
> I can ping Qualcomm engineers to see if that is doable.

I think that would be great! Thanks!

Regards,
Max
Ard Biesheuvel Aug. 2, 2022, 2:02 p.m. UTC | #5
On Tue, 2 Aug 2022 at 15:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
>
>
> On 8/2/22 13:51, Srinivas Kandagatla wrote:
> > Hi Maximilian,
> >
> > On 23/07/2022 23:49, Maximilian Luz wrote:
> >> On modern Qualcomm platforms, access to EFI variables is restricted to
> >> the secure world / TrustZone, i.e. the Trusted Execution Environment
> >> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
> >> therefore need to talk to the UEFI Secure Application (uefisecapp),
> >> residing in the TrEE.
> >>
> >> This series adds support for accessing EFI variables on those platforms.
> >>
> >> To do this, we first need to add some SCM call functions used to manage
> >> and talk to Secure Applications. A very small subset of this interface
> >> is added in the second patch (whereas the first one exports the required
> >> functions for that). Interface specifications are extracted from [1].
> >> While this does not (yet) support re-entrant SCM calls (including
> >> callbacks and listeners), this is enough to talk to the aforementioned
> >> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
> >> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
> >> Yoga C630 devices).
> >>
> >> The third patch adds a client driver for uefisecapp, installing the
> >> respective efivar operations. The application interface has been reverse
> >> engineered from the Windows QcTrEE8180.sys driver.
> >>
> >> Apart from uefisecapp, there are more Secure Applications running that
> >> we might want to support in the future. For example, on the Surface Pro
> >> X (sc8180x-based), the TPM is also managed via one.
> >>
> >> I'm not sure whether this should go to drivers/firmware or to
> >> drivers/soc/qcom. I've put this into firmware as all of this is
> >> essentially an interface to the secure firmware running in the TrustZone
> >> (and SCM stuff is handled here already), but please let me know if I
> >> should move this.
> >
> >  From what I see so far is that this is adapted from downstream qseecom driver, this approach could work for a limited usecases but not scalable, as we cannot add drivers for each Qualcomm specific TA in kernel.
> > This has to be handled in much generic way using Linux TEE framework, and let the userspace side deal with TA specific bits.
>
> I generally agree with the sentiment, however UEFI variables should IMHO be
> handled by the kernel. Moving handling of those to userspace breaks things like
> EFI-based pstore and efivarfs. The latter will in turn break some user-space
> tools (most notably efibootmgr used by e.g. GRUB and I think fwupdmgr which
> needs to set some capsule variables). Ideally, we would find a way to not break
> these, i.e. have them work out-of-the-box.
>

Only capsule-on-disk requires SetVariable() at runtime, and I doubt
whether these platforms implement any of that.

> A similar argumentation might apply to the TPM app.
>

There is a difference, though - the TPM is modeled as a device and
runtime access to it is implemented as a device driver, which is only
accessed from user space.

> > AFAIU, Qualcomm is moving away from qseecom interface to new smc-invoke interface, most of Qualcomm SoCs starting from SDM660 already have support to this.
> >
> > This interface provides a better abstracted IPC mechanism to talk to TA. Most of these TA specific interfaces are packed in closed userspace source.
> > Having said that QTEE smcinvoke driver can be modeled as a proper TEE driver with Userspace driving the TA specific bits using existing tee uapis.
> > This also brings in other features like loading, Listeners aka callbacks, secure memory allocations..etc.
> >
> > In the past, I have tried to do a prototype of this smcinvoke driver as a proper tee driver, incase you are interested patches are at https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=tracking-qcomlt-qcomtee
> > Plan is to discuss with Qualcomm and send it for upstream review.
>
> Thanks for this information! So as far as I understand it, this is currently an
> interface to user-space only, i.e. does not allow in-kernel drivers for apps?
> It would be great if this could then be extended to handle (the bare minimum
> of) in-kernel drivers (i.e. only things that the kernel itself needs, like EFI
> variables). Alternatively, I'm happy to hear suggestions on how we not break
> the aforementioned things while moving handling off to userspace.
>
> > I think its worth exploring if uefisecapp can talk smcinvoke.
> > I can ping Qualcomm engineers to see if that is doable.
>
> I think that would be great! Thanks!
>
> Regards,
> Max
Maximilian Luz Aug. 2, 2022, 7:11 p.m. UTC | #6
On 8/2/22 16:02, Ard Biesheuvel wrote:
> On Tue, 2 Aug 2022 at 15:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:

[...]

>> I generally agree with the sentiment, however UEFI variables should IMHO be
>> handled by the kernel. Moving handling of those to userspace breaks things like
>> EFI-based pstore and efivarfs. The latter will in turn break some user-space
>> tools (most notably efibootmgr used by e.g. GRUB and I think fwupdmgr which
>> needs to set some capsule variables). Ideally, we would find a way to not break
>> these, i.e. have them work out-of-the-box.
>>
> 
> Only capsule-on-disk requires SetVariable() at runtime, and I doubt
> whether these platforms implement any of that.
> 
>> A similar argumentation might apply to the TPM app.
>>
> 
> There is a difference, though - the TPM is modeled as a device and
> runtime access to it is implemented as a device driver, which is only
> accessed from user space.

Ah, thanks for that info! I wasn't sure about that last part.

But we'd still need _something_ in the kernel. All the common software
using TPMs would expect the TPM to be present as /dev/tpmX. So, while it
doesn't have to be a full secure-app driver, we'd need at least some way
to manage a TPM device from user-space (unless we want to tell all
software using TPMs to just support some non-standard thing instead).

For EFI variables, something similar might be possible (i.e. running
efivar operations through a user-space driver), but that will break
pstore in the times it's most usable (i.e. when no user-space exists or
things are sufficiently broken that we can't run things through it any
more).

And then (at least for me) there's the question whether that all seems
sound: Sure, we can maintain some userspace-daemon outside the kernel,
but if it is common enough (i.e. not a one-off used only by some single
vendor and model) and can be easily implemented in the kernel, why not?
Moving it to userspace makes things more complex. You'll need new
userspace APIs (as mentioned above, if you don't want to force all
existing software to adapt to some non-standard thing) and you need to
tell users to install and set up some daemon(s) (making it yet more
difficult to produce a single proper install media that works well on
all the common AArch64 or WoA platforms). All the while you still need
to maintain essentially the same piece of code (whether it is inside or
outside of the kernel), so you don't really win anything there either.

Regards,
Max
Sumit Garg Sept. 2, 2022, 7:26 a.m. UTC | #7
Hi Maximilian,

On 02/08/22 18:52, Maximilian Luz wrote:
>
>
> On 8/2/22 13:51, Srinivas Kandagatla wrote:
>> Hi Maximilian,
>>
>> On 23/07/2022 23:49, Maximilian Luz wrote:
>>> On modern Qualcomm platforms, access to EFI variables is restricted to
>>> the secure world / TrustZone, i.e. the Trusted Execution Environment
>>> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
>>> therefore need to talk to the UEFI Secure Application (uefisecapp),
>>> residing in the TrEE.
>>>
>>> This series adds support for accessing EFI variables on those 
>>> platforms.
>>>
>>> To do this, we first need to add some SCM call functions used to manage
>>> and talk to Secure Applications. A very small subset of this interface
>>> is added in the second patch (whereas the first one exports the 
>>> required
>>> functions for that). Interface specifications are extracted from [1].
>>> While this does not (yet) support re-entrant SCM calls (including
>>> callbacks and listeners), this is enough to talk to the aforementioned
>>> uefisecapp on a couple of platforms (I've tested this on a Surface 
>>> Pro X
>>> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
>>> Yoga C630 devices).
>>>
>>> The third patch adds a client driver for uefisecapp, installing the
>>> respective efivar operations. The application interface has been 
>>> reverse
>>> engineered from the Windows QcTrEE8180.sys driver.
>>>
>>> Apart from uefisecapp, there are more Secure Applications running that
>>> we might want to support in the future. For example, on the Surface Pro
>>> X (sc8180x-based), the TPM is also managed via one.
>>>
>>> I'm not sure whether this should go to drivers/firmware or to
>>> drivers/soc/qcom. I've put this into firmware as all of this is
>>> essentially an interface to the secure firmware running in the 
>>> TrustZone
>>> (and SCM stuff is handled here already), but please let me know if I
>>> should move this.
>>
>>  From what I see so far is that this is adapted from downstream 
>> qseecom driver, this approach could work for a limited usecases but 
>> not scalable, as we cannot add drivers for each Qualcomm specific TA 
>> in kernel.
>> This has to be handled in much generic way using Linux TEE framework, 
>> and let the userspace side deal with TA specific bits.
>
> I generally agree with the sentiment, however UEFI variables should 
> IMHO be
> handled by the kernel. Moving handling of those to userspace breaks 
> things like
> EFI-based pstore and efivarfs. The latter will in turn break some 
> user-space
> tools (most notably efibootmgr used by e.g. GRUB and I think fwupdmgr 
> which
> needs to set some capsule variables). Ideally, we would find a way to 
> not break
> these, i.e. have them work out-of-the-box.
>
> A similar argumentation might apply to the TPM app.

See below, there is already an existing TPM app driver [2] in kernel 
although the app is based on OP-TEE.

>
>> AFAIU, Qualcomm is moving away from qseecom interface to new 
>> smc-invoke interface, most of Qualcomm SoCs starting from SDM660 
>> already have support to this.
>>
>> This interface provides a better abstracted IPC mechanism to talk to 
>> TA. Most of these TA specific interfaces are packed in closed 
>> userspace source.
>> Having said that QTEE smcinvoke driver can be modeled as a proper TEE 
>> driver with Userspace driving the TA specific bits using existing tee 
>> uapis.
>> This also brings in other features like loading, Listeners aka 
>> callbacks, secure memory allocations..etc.
>>
>> In the past, I have tried to do a prototype of this smcinvoke driver 
>> as a proper tee driver, incase you are interested patches are at 
>> https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=tracking-qcomlt-qcomtee
>> Plan is to discuss with Qualcomm and send it for upstream review.
>
> Thanks for this information! So as far as I understand it, this is 
> currently an
> interface to user-space only, i.e. does not allow in-kernel drivers 
> for apps?

The Linux TEE framework already provides an in-kernel interface to TEE 
as well via TEE bus [1]. There are already multiple kernel drivers [2] 
[3] [4] [5] [6] [7] using it. So an EFI driver can be an addition to that.

Now coming on to TEE implementations, the drivers I mentioned are based 
on OP-TEE where devices are queried/enumerated during OP-TEE probe here 
[8]. So in similar manner QTEE smcinvoke driver should be able to 
register devices on the TEE bus.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/staging/tee.rst#n56

[2] drivers/char/tpm/tpm_ftpm_tee.c

[3] drivers/char/hw_random/optee-rng.c

[4] drivers/firmware/arm_scmi/optee.c

[5] security/keys/trusted-keys/trusted_tee.c

[6] drivers/firmware/broadcom/tee_bnxt_fw.c

[7] drivers/rtc/rtc-optee.c

[8] drivers/tee/optee/device.c

-Sumit

PS. TBH, I haven't looked into detail workings for the QTEE smcinvoke 
driver.

> It would be great if this could then be extended to handle (the bare 
> minimum
> of) in-kernel drivers (i.e. only things that the kernel itself needs, 
> like EFI
> variables). Alternatively, I'm happy to hear suggestions on how we not 
> break
> the aforementioned things while moving handling off to userspace.
>
>> I think its worth exploring if uefisecapp can talk smcinvoke.
>> I can ping Qualcomm engineers to see if that is doable.
>
> I think that would be great! Thanks!
>
> Regards,
> Max
>
Maximilian Luz Sept. 2, 2022, 1:18 p.m. UTC | #8
Hi,

On 9/2/22 09:26, Sumit Garg wrote:
> Hi Maximilian,
> 
> On 02/08/22 18:52, Maximilian Luz wrote:

[...]

>> Thanks for this information! So as far as I understand it, this is currently an
>> interface to user-space only, i.e. does not allow in-kernel drivers for apps?
> 
> The Linux TEE framework already provides an in-kernel interface to TEE as well via TEE bus [1]. There are already multiple kernel drivers [2] [3] [4] [5] [6] [7] using it. So an EFI driver can be an addition to that.
> 
> Now coming on to TEE implementations, the drivers I mentioned are based on OP-TEE where devices are queried/enumerated during OP-TEE probe here [8]. So in similar manner QTEE smcinvoke driver should be able to register devices on the TEE bus.
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/staging/tee.rst#n56
> 
> [2] drivers/char/tpm/tpm_ftpm_tee.c
> 
> [3] drivers/char/hw_random/optee-rng.c
> 
> [4] drivers/firmware/arm_scmi/optee.c
> 
> [5] security/keys/trusted-keys/trusted_tee.c
> 
> [6] drivers/firmware/broadcom/tee_bnxt_fw.c
> 
> [7] drivers/rtc/rtc-optee.c
> 
> [8] drivers/tee/optee/device.c

Thanks for those links!

I think it would indeed be good if we could make it work via that
interface and I guess that should generally be possible. As far as I can
see, the biggest problem might be that the current firmware doesn't seem
to use UUIDs, so I guess we might need to emulate them somehow.

It would be great if someone with some actual knowledge of the firmware
used on those devices could have a look at this and provide some
insights.

My plan for now is to hold off on the UEFI variable driver until we have
a (proper) TEE driver, which unfortunately might be a bit out of my
depth. I'm happy to help out in any way I can though.

Regards,
Max
Sumit Garg Sept. 5, 2022, 6:50 a.m. UTC | #9
+ TEE ML

On Fri, 2 Sept 2022 at 18:48, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> Hi,
>
> On 9/2/22 09:26, Sumit Garg wrote:
> > Hi Maximilian,
> >
> > On 02/08/22 18:52, Maximilian Luz wrote:
>
> [...]
>
> >> Thanks for this information! So as far as I understand it, this is currently an
> >> interface to user-space only, i.e. does not allow in-kernel drivers for apps?
> >
> > The Linux TEE framework already provides an in-kernel interface to TEE as well via TEE bus [1]. There are already multiple kernel drivers [2] [3] [4] [5] [6] [7] using it. So an EFI driver can be an addition to that.
> >
> > Now coming on to TEE implementations, the drivers I mentioned are based on OP-TEE where devices are queried/enumerated during OP-TEE probe here [8]. So in similar manner QTEE smcinvoke driver should be able to register devices on the TEE bus.
> >
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/staging/tee.rst#n56
> >
> > [2] drivers/char/tpm/tpm_ftpm_tee.c
> >
> > [3] drivers/char/hw_random/optee-rng.c
> >
> > [4] drivers/firmware/arm_scmi/optee.c
> >
> > [5] security/keys/trusted-keys/trusted_tee.c
> >
> > [6] drivers/firmware/broadcom/tee_bnxt_fw.c
> >
> > [7] drivers/rtc/rtc-optee.c
> >
> > [8] drivers/tee/optee/device.c
>
> Thanks for those links!
>
> I think it would indeed be good if we could make it work via that
> interface and I guess that should generally be possible. As far as I can
> see, the biggest problem might be that the current firmware doesn't seem
> to use UUIDs, so I guess we might need to emulate them somehow.
>

Okay, so I had a brief look at your driver to get an idea how QTEE
identifies its trusted/secure applications. AFAIU, it uses constant
strings as follows:

#define QCTEE_UEFISEC_APP_NAME "qcom.tz.uefisecapp"

I think we should be able to extend the TEE bus concept to accept
constant strings as device IDs as well. So if a driver wants to
support both OP-TEE and QTEE based apps then it can put corresponding
identifiers (UUID or a constant string) in the TEE device match ID
table. This way we should be able to support other TEE implementations
as I think any other identifier apart from UUID can be represented as
a constant string.

If anyone else has any better then feel free to discuss.

-Sumit

> It would be great if someone with some actual knowledge of the firmware
> used on those devices could have a look at this and provide some
> insights.
>
> My plan for now is to hold off on the UEFI variable driver until we have
> a (proper) TEE driver, which unfortunately might be a bit out of my
> depth. I'm happy to help out in any way I can though.
>
> Regards,
> Max
Srinivas Kandagatla Nov. 23, 2022, 11:22 a.m. UTC | #10
Hi Max,

On 02/08/2022 14:22, Maximilian Luz wrote:
> 
> 
> On 8/2/22 13:51, Srinivas Kandagatla wrote:
>> Hi Maximilian,
>>
>> On 23/07/2022 23:49, Maximilian Luz wrote:
>>> On modern Qualcomm platforms, access to EFI variables is restricted to
>>> the secure world / TrustZone, i.e. the Trusted Execution Environment
>>> (TrEE or TEE) as Qualcomm seems to call it. To access EFI variables, we
>>> therefore need to talk to the UEFI Secure Application (uefisecapp),
>>> residing in the TrEE.
>>>
>>> This series adds support for accessing EFI variables on those platforms.
>>>
>>> To do this, we first need to add some SCM call functions used to manage
>>> and talk to Secure Applications. A very small subset of this interface
>>> is added in the second patch (whereas the first one exports the required
>>> functions for that). Interface specifications are extracted from [1].
>>> While this does not (yet) support re-entrant SCM calls (including
>>> callbacks and listeners), this is enough to talk to the aforementioned
>>> uefisecapp on a couple of platforms (I've tested this on a Surface Pro X
>>> and heard reports from Lenovo Flex 5G, Lenovo Thinkpad x13s, and Lenovo
>>> Yoga C630 devices).
>>>
>>> The third patch adds a client driver for uefisecapp, installing the
>>> respective efivar operations. The application interface has been reverse
>>> engineered from the Windows QcTrEE8180.sys driver.
>>>
>>> Apart from uefisecapp, there are more Secure Applications running that
>>> we might want to support in the future. For example, on the Surface Pro
>>> X (sc8180x-based), the TPM is also managed via one.
>>>
>>> I'm not sure whether this should go to drivers/firmware or to
>>> drivers/soc/qcom. I've put this into firmware as all of this is
>>> essentially an interface to the secure firmware running in the TrustZone
>>> (and SCM stuff is handled here already), but please let me know if I
>>> should move this.
>>
>>  From what I see so far is that this is adapted from downstream 
>> qseecom driver, this approach could work for a limited usecases but 
>> not scalable, as we cannot add drivers for each Qualcomm specific TA 
>> in kernel.
>> This has to be handled in much generic way using Linux TEE framework, 
>> and let the userspace side deal with TA specific bits.
> 
> I generally agree with the sentiment, however UEFI variables should IMHO be
> handled by the kernel. Moving handling of those to userspace breaks 
> things like
> EFI-based pstore and efivarfs. The latter will in turn break some 
> user-space
> tools (most notably efibootmgr used by e.g. GRUB and I think fwupdmgr which
> needs to set some capsule variables). Ideally, we would find a way to 
> not break
> these, i.e. have them work out-of-the-box.
> 
> A similar argumentation might apply to the TPM app.
> 
>> AFAIU, Qualcomm is moving away from qseecom interface to new 
>> smc-invoke interface, most of Qualcomm SoCs starting from SDM660 
>> already have support to this.
>>
>> This interface provides a better abstracted IPC mechanism to talk to 
>> TA. Most of these TA specific interfaces are packed in closed 
>> userspace source.
>> Having said that QTEE smcinvoke driver can be modeled as a proper TEE 
>> driver with Userspace driving the TA specific bits using existing tee 
>> uapis.
>> This also brings in other features like loading, Listeners aka 
>> callbacks, secure memory allocations..etc.
>>
>> In the past, I have tried to do a prototype of this smcinvoke driver 
>> as a proper tee driver, incase you are interested patches are at 
>> https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=tracking-qcomlt-qcomtee
>> Plan is to discuss with Qualcomm and send it for upstream review.
> 
> Thanks for this information! So as far as I understand it, this is 
> currently an
> interface to user-space only, i.e. does not allow in-kernel drivers for 
> apps?
> It would be great if this could then be extended to handle (the bare 
> minimum
> of) in-kernel drivers (i.e. only things that the kernel itself needs, 
> like EFI
> variables). Alternatively, I'm happy to hear suggestions on how we not 
> break
> the aforementioned things while moving handling off to userspace.
> 
>> I think its worth exploring if uefisecapp can talk smcinvoke.
>> I can ping Qualcomm engineers to see if that is doable.
> 
> I think that would be great! Thanks!
Sorry for such a long delay to reply to this,

here is what I have.

Access to TA using SCM calls remain valid and it will continue to work 
till SM8550 and probably after that if the TA is *NOT* loaded using 
smcinvoke for some reasons.

But overall by default on all new SoCs after sm8550 all the access to TA 
is only done via smcinvoke, and the underlying scm call that are used in 
this patchset will not be supported anymore.

 From SM8550, we will need to move this driver to a proper TEE client 
kernel driver.

So, with that in mind, I would suggest that we carefully name the 
compatibles based on SoC rather than generic ones.


--srini




> 
> Regards,
> Max
Maximilian Luz Nov. 23, 2022, 12:05 p.m. UTC | #11
Hi,

On 11/23/22 12:22, Srinivas Kandagatla wrote:
> Hi Max,
> 
> On 02/08/2022 14:22, Maximilian Luz wrote:
>>
>>
>> On 8/2/22 13:51, Srinivas Kandagatla wrote:

[...]

>>> I think its worth exploring if uefisecapp can talk smcinvoke.
>>> I can ping Qualcomm engineers to see if that is doable.
>>
>> I think that would be great! Thanks!
> Sorry for such a long delay to reply to this,
> 
> here is what I have.
> 
> Access to TA using SCM calls remain valid and it will continue to work till SM8550 and probably after that if the TA is *NOT* loaded using smcinvoke for some reasons.
> 
> But overall by default on all new SoCs after sm8550 all the access to TA is only done via smcinvoke, and the underlying scm call that are used in this patchset will not be supported anymore.
> 
>  From SM8550, we will need to move this driver to a proper TEE client kernel driver.
> 
> So, with that in mind, I would suggest that we carefully name the compatibles based on SoC rather than generic ones.

Thanks! That makes sense.

Regards,
Max