linux-surface / surface-pro-x

Tracking and meta repository for Surface Pro X support.
81 stars 6 forks source link

Support for TrEE Services #37

Open qzed opened 2 years ago

qzed commented 2 years ago

On the Pro X (and likely other Qualcomm devices), various services are provided via the Trusted Execution Environment (TrEE) and TrustZone (TZ) Apps. In particular, access to EFI variables is provided via such a service, as is the TPM, HDCP, and more. On Windows, this is managed by the QcTrEE8180.sys driver.

qzed commented 2 years ago

Services based on .inf file:

qzed commented 2 years ago

Likely relevant files from the qcom/auto tree:

Also interesting:

qzed commented 2 years ago

Regarding UEFI variables: The TZ-App responsible for handling this can be found at fs6:\TZAPPS\uefisec.mbn.

qzed commented 2 years ago

As far as I can tell: TZ-Apps can be loaded dynamically from the OS via a SMC call (TzOsAppLoad/TzOsAppLoadFromFile/TzOsAppUnload) . Some apps are loaded at boot by the firmware. Those seem to be qcom.tz.tpm, qcom.tz.uefisecapp, and qcom.tz.mssecapp. These names are unique service/app names, which seem to be dynamically mapped to app IDs, required for communication. More specifically, there is a special category of SMC calls for communication with TZ-apps (TzAppSend, TzAppSendEx), to which the ID needs to be passed so that the call is correctly addressed to that respective app.

The ID has to be queried dynamically by providing the unique name (TzOsLookupApplicationId).

In addition, it looks like some services can (request to) talk to other services via the TrEE driver as well. In particular, the UEFI and filesystem services (and others) seem to provide such an interface.

qzed commented 2 years ago

The UEFI service interface is defined at https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/km/treevariableservice.h#L35.

qzed commented 2 years ago

In addition to the above, there seem to be two types: SecureServices and OsServices. The .inf file of the driver lists dependencies of SecureServices on OsServices. For example, the UEFI variable service has a dependency on the RpmbOsService (PRMB meaning replay-protected memory block).

In particular, that means that the UEFI variable service depends on an OS provided mechanism for accessing the UEFI key store. On UFS based devices (e.g. Flex 5G), that seems to be provided via partitions on the UFS storage, whereas on the Pro X it looks like this is stored in a SPI NOR flash. So we would probably need support for that first.

I briefly assumed that UEFI might provide stub UEFI Runtime Service functions calling into the UEFI variable service, but that seems unlikely: As far as I can tell, the secure environment cannot initiate communication itself. Instead, the OS initiates all communications. For example, to query a UEFI variable, the OS would (likely) initiate communication, which then leads to the secure service returning a "partial/incomplete" status from the SCM call and a request for some callback/os-service execution. The OS driver handles this and then continues the original command until "complete" is returned.

qzed commented 2 years ago

Found in a partition dump from UEFI: SecParti.cfg.txt. Seems to list secure file system partitions.

qzed commented 2 years ago

Some interesting documents:

qzed commented 2 years ago

We now have a driver (more like an interface) for the basic communication with TrEE apps / TZ-OS and a driver for the UEFI Secure App / EFIVarService. While the SCM calls can apparently request callbacks/listeners to be invoked and return incomplete, this was not necessary for uefisecapp.

Support for the TPM handled via another secure application (qcom.tz.tpm / TPMService). Apart from that, there's a bunch of content-protection stuff and then there are mssecapp, winsecapp, and some secure kernel extension and services. I'm not entirely sure yet what they're all about.