* [PATCH v1 0/2] Add OP-TEE based hwrng driver @ 2018-12-27 11:07 Sumit Garg 2018-12-27 11:07 ` [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property Sumit Garg 2018-12-27 11:07 ` [PATCH v1 2/2] hwrng: add OP-TEE based rng driver Sumit Garg 0 siblings, 2 replies; 25+ messages in thread From: Sumit Garg @ 2018-12-27 11:07 UTC (permalink / raw) To: linux-crypto, devicetree Cc: mpm, herbert, robh+dt, mark.rutland, arnd, gregkh, jens.wiklander, daniel.thompson, ard.biesheuvel, bhsharma, tee-dev, Sumit Garg On ARM SoC's with TrustZone enabled, peripherals like entropy sources might not be accessible to normal world (linux in this case) and rather accessible to secure world (OP-TEE in this case) only. So this driver aims to provides a generic interface to OP-TEE based random number generator service. Example case is Developerbox based on Socionext's Synquacer SoC [1] which provides 7 thermal sensors accessible from secure world only which could be used as entropy sources (thermal/measurement noise). [1] https://www.96boards.org/product/developerbox/ Sumit Garg (2): dt/bindings: add bindings for optional optee rng-uuid property hwrng: add OP-TEE based rng driver .../bindings/arm/firmware/linaro,optee-tz.txt | 4 + MAINTAINERS | 5 + drivers/char/hw_random/Kconfig | 15 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++ 5 files changed, 298 insertions(+) create mode 100644 drivers/char/hw_random/optee-rng.c -- 2.7.4 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2018-12-27 11:07 [PATCH v1 0/2] Add OP-TEE based hwrng driver Sumit Garg @ 2018-12-27 11:07 ` Sumit Garg 2018-12-27 13:39 ` Ard Biesheuvel 2018-12-27 11:07 ` [PATCH v1 2/2] hwrng: add OP-TEE based rng driver Sumit Garg 1 sibling, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-27 11:07 UTC (permalink / raw) To: linux-crypto, devicetree Cc: mpm, herbert, robh+dt, mark.rutland, arnd, gregkh, jens.wiklander, daniel.thompson, ard.biesheuvel, bhsharma, tee-dev, Sumit Garg Add bindings for OP-TEE based optional hardware random number generator identifier property. It could be used on ARM based devices where entropy source is not accessible to normal world (linux in this case). Signed-off-by: Sumit Garg <sumit.garg@linaro.org> --- Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt index d38834c..e3a4c35 100644 --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. "hvc" : HVC #0, with the register assignments specified in drivers/tee/optee/optee_smc.h +- rng-uuid : Optional OP-TEE based RNG service identifier in case + hardware entropy source is not accesible to normal world + (Linux). Example: @@ -27,5 +30,6 @@ Example: optee { compatible = "linaro,optee-tz"; method = "smc"; + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; }; }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2018-12-27 11:07 ` [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property Sumit Garg @ 2018-12-27 13:39 ` Ard Biesheuvel 2018-12-28 9:11 ` Sumit Garg 2019-01-03 16:20 ` Rob Herring 0 siblings, 2 replies; 25+ messages in thread From: Ard Biesheuvel @ 2018-12-27 13:39 UTC (permalink / raw) To: Sumit Garg Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > Add bindings for OP-TEE based optional hardware random number > generator identifier property. It could be used on ARM based devices > where entropy source is not accessible to normal world (linux in this > case). > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > --- > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > index d38834c..e3a4c35 100644 > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > "hvc" : HVC #0, with the register assignments specified > in drivers/tee/optee/optee_smc.h > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > + hardware entropy source is not accesible to normal world > + (Linux). > > > Example: > @@ -27,5 +30,6 @@ Example: > optee { > compatible = "linaro,optee-tz"; > method = "smc"; > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; If OP-TEE is going to expose devices in this way, it should be modeled more like a bus driver, i.e., sub-nodes that represent the devices, with compatible strings, and perhaps even 'reg' properties for the UUIDs. > }; > }; > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2018-12-27 13:39 ` Ard Biesheuvel @ 2018-12-28 9:11 ` Sumit Garg 2019-01-03 17:14 ` Daniel Thompson 2019-01-03 16:20 ` Rob Herring 1 sibling, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-28 9:11 UTC (permalink / raw) To: Ard Biesheuvel Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Add bindings for OP-TEE based optional hardware random number > > generator identifier property. It could be used on ARM based devices > > where entropy source is not accessible to normal world (linux in this > > case). > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > --- > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > index d38834c..e3a4c35 100644 > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > "hvc" : HVC #0, with the register assignments specified > > in drivers/tee/optee/optee_smc.h > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > + hardware entropy source is not accesible to normal world > > + (Linux). > > > > > > Example: > > @@ -27,5 +30,6 @@ Example: > > optee { > > compatible = "linaro,optee-tz"; > > method = "smc"; > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > If OP-TEE is going to expose devices in this way, it should be modeled > more like a bus driver, i.e., sub-nodes that represent the devices, > with compatible strings, and perhaps even 'reg' properties for the > UUIDs. > This is something Daniel also suggested during our discussion. But we agreed to discuss in upstream to get more feedback. I think generic TEE should be modelled as a bus driver with devices identified via UUIDs, probably queried from underline implementations like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it supports. Then this list of device UUIDs can be compared against child driver's UUID as part of match callback during driver registration. Also the child driver could maintain list of device UUIDs which it supports. If we go via this approach we may not require device tree entry for corresponding device UUIDs. -Sumit > > }; > > }; > > -- > > 2.7.4 > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2018-12-28 9:11 ` Sumit Garg @ 2019-01-03 17:14 ` Daniel Thompson 2019-01-04 6:39 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Daniel Thompson @ 2019-01-03 17:14 UTC (permalink / raw) To: Sumit Garg Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Bhupesh Sharma, tee-dev On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Add bindings for OP-TEE based optional hardware random number > > > generator identifier property. It could be used on ARM based devices > > > where entropy source is not accessible to normal world (linux in this > > > case). > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > --- > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > 1 file changed, 4 insertions(+) > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > index d38834c..e3a4c35 100644 > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > "hvc" : HVC #0, with the register assignments specified > > > in drivers/tee/optee/optee_smc.h > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > + hardware entropy source is not accesible to normal world > > > + (Linux). > > > > > > > > > Example: > > > @@ -27,5 +30,6 @@ Example: > > > optee { > > > compatible = "linaro,optee-tz"; > > > method = "smc"; > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > more like a bus driver, i.e., sub-nodes that represent the devices, > > with compatible strings, and perhaps even 'reg' properties for the > > UUIDs. > > > > This is something Daniel also suggested during our discussion. But we > agreed to discuss in upstream to get more feedback. > > I think generic TEE should be modelled as a bus driver with devices > identified via UUIDs, probably queried from underline implementations > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > supports. Then this list of device UUIDs can be compared against child > driver's UUID as part of match callback during driver registration. > Also the child driver could maintain list of device UUIDs which it > supports. > > If we go via this approach we may not require device tree entry for > corresponding device UUIDs. That's pretty much aligned with my thinking. Having said that I had wondered whether all TEEs would be prepared to describe the set of available UUIDs since AFAIK UUID enumeration isn't part of the GlobalPlatform standards so it is not implemented by GP based TEEs (such as OP-TEE). Is it feasible to extend OP-TEE to enumerate the available UUIDs? If nothing else can it provide an (optional) pseudo TA to provide such a service? Personally I'd be OK with a kernel TEE bus infrastructure that mandated such a service (e.g. a TEE that does not provide the service can only interact with TEE from userspace). Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-03 17:14 ` Daniel Thompson @ 2019-01-04 6:39 ` Sumit Garg 2019-01-04 11:01 ` Jens Wiklander 0 siblings, 1 reply; 25+ messages in thread From: Sumit Garg @ 2019-01-04 6:39 UTC (permalink / raw) To: Daniel Thompson Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Bhupesh Sharma, tee-dev On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > generator identifier property. It could be used on ARM based devices > > > > where entropy source is not accessible to normal world (linux in this > > > > case). > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > --- > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > 1 file changed, 4 insertions(+) > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > index d38834c..e3a4c35 100644 > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > "hvc" : HVC #0, with the register assignments specified > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > + hardware entropy source is not accesible to normal world > > > > + (Linux). > > > > > > > > > > > > Example: > > > > @@ -27,5 +30,6 @@ Example: > > > > optee { > > > > compatible = "linaro,optee-tz"; > > > > method = "smc"; > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > with compatible strings, and perhaps even 'reg' properties for the > > > UUIDs. > > > > > > > This is something Daniel also suggested during our discussion. But we > > agreed to discuss in upstream to get more feedback. > > > > I think generic TEE should be modelled as a bus driver with devices > > identified via UUIDs, probably queried from underline implementations > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > supports. Then this list of device UUIDs can be compared against child > > driver's UUID as part of match callback during driver registration. > > Also the child driver could maintain list of device UUIDs which it > > supports. > > > > If we go via this approach we may not require device tree entry for > > corresponding device UUIDs. > > That's pretty much aligned with my thinking. > > Having said that I had wondered whether all TEEs would be prepared to > describe the set of available UUIDs since AFAIK UUID enumeration isn't > part of the GlobalPlatform standards so it is not implemented by GP > based TEEs (such as OP-TEE). > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > If nothing else can it provide an (optional) pseudo TA to provide such a > service? Personally I'd be OK with a kernel TEE bus infrastructure that > mandated such a service (e.g. a TEE that does not provide the service > can only interact with TEE from userspace). > Following is the kernel interface for OP-TEE device enumeration that I would like to propose: /* * Get next OP-TEE based kernel device * * Secure world can provide support for resident kernel devices/services * as pseudo/early trusted applications. So this function is used to * enumerate OP-TEE based kernel devices. * * Call register usage: * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE * a1-6 Not used * a7 Hypervisor Client ID register * * Possible return values: * * OP-TEE OS returns next device UUID. * a0 OPTEE_SMC_RETURN_OK * a1-4 Device UUID * a5-7 Preserved * * OP-TEE OS does not recognize this function. * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION * a1-7 Preserved * * OP-TEE OS done with device enumeration. * a0 OPTEE_SMC_RETURN_ENOTAVAIL * a1-7 Preserved */ #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 #define OPTEE_SMC_GET_NEXT_DEVICE \ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to detect particular pseudo/early TA as a kernel device during enumeration. -Sumit > > Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-04 6:39 ` Sumit Garg @ 2019-01-04 11:01 ` Jens Wiklander 2019-01-04 12:01 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Jens Wiklander @ 2019-01-04 11:01 UTC (permalink / raw) To: Sumit Garg Cc: Daniel Thompson, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > generator identifier property. It could be used on ARM based devices > > > > > where entropy source is not accessible to normal world (linux in this > > > > > case). > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > --- > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > index d38834c..e3a4c35 100644 > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > + hardware entropy source is not accesible to normal world > > > > > + (Linux). > > > > > > > > > > > > > > > Example: > > > > > @@ -27,5 +30,6 @@ Example: > > > > > optee { > > > > > compatible = "linaro,optee-tz"; > > > > > method = "smc"; > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > UUIDs. > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > agreed to discuss in upstream to get more feedback. > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > identified via UUIDs, probably queried from underline implementations > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > supports. Then this list of device UUIDs can be compared against child > > > driver's UUID as part of match callback during driver registration. > > > Also the child driver could maintain list of device UUIDs which it > > > supports. > > > > > > If we go via this approach we may not require device tree entry for > > > corresponding device UUIDs. > > > > That's pretty much aligned with my thinking. > > > > Having said that I had wondered whether all TEEs would be prepared to > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > part of the GlobalPlatform standards so it is not implemented by GP > > based TEEs (such as OP-TEE). > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > If nothing else can it provide an (optional) pseudo TA to provide such a > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > mandated such a service (e.g. a TEE that does not provide the service > > can only interact with TEE from userspace). > > > > Following is the kernel interface for OP-TEE device enumeration that I > would like to propose: > > /* > * Get next OP-TEE based kernel device > * > * Secure world can provide support for resident kernel devices/services > * as pseudo/early trusted applications. So this function is used to > * enumerate OP-TEE based kernel devices. > * > * Call register usage: > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > * a1-6 Not used > * a7 Hypervisor Client ID register > * > * Possible return values: > * > * OP-TEE OS returns next device UUID. > * a0 OPTEE_SMC_RETURN_OK > * a1-4 Device UUID > * a5-7 Preserved > * > * OP-TEE OS does not recognize this function. > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > * a1-7 Preserved > * > * OP-TEE OS done with device enumeration. > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > * a1-7 Preserved > */ > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > #define OPTEE_SMC_GET_NEXT_DEVICE \ > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > detect particular pseudo/early TA as a kernel device during > enumeration. I'd rather provide this enumeration via a pseudo TA, to keep the SMC interface as small as possible. The pseudo TA can be optional, if it's not available then there's no need to try to instantiate any dependent drivers either. - Jens > > -Sumit > > > > > Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-04 11:01 ` Jens Wiklander @ 2019-01-04 12:01 ` Sumit Garg 2019-01-04 13:03 ` Jens Wiklander 0 siblings, 1 reply; 25+ messages in thread From: Sumit Garg @ 2019-01-04 12:01 UTC (permalink / raw) To: Jens Wiklander Cc: Daniel Thompson, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Fri, 4 Jan 2019 at 16:31, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > > generator identifier property. It could be used on ARM based devices > > > > > > where entropy source is not accessible to normal world (linux in this > > > > > > case). > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > --- > > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > index d38834c..e3a4c35 100644 > > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > > + hardware entropy source is not accesible to normal world > > > > > > + (Linux). > > > > > > > > > > > > > > > > > > Example: > > > > > > @@ -27,5 +30,6 @@ Example: > > > > > > optee { > > > > > > compatible = "linaro,optee-tz"; > > > > > > method = "smc"; > > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > > UUIDs. > > > > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > > agreed to discuss in upstream to get more feedback. > > > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > > identified via UUIDs, probably queried from underline implementations > > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > > supports. Then this list of device UUIDs can be compared against child > > > > driver's UUID as part of match callback during driver registration. > > > > Also the child driver could maintain list of device UUIDs which it > > > > supports. > > > > > > > > If we go via this approach we may not require device tree entry for > > > > corresponding device UUIDs. > > > > > > That's pretty much aligned with my thinking. > > > > > > Having said that I had wondered whether all TEEs would be prepared to > > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > > part of the GlobalPlatform standards so it is not implemented by GP > > > based TEEs (such as OP-TEE). > > > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > > If nothing else can it provide an (optional) pseudo TA to provide such a > > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > > mandated such a service (e.g. a TEE that does not provide the service > > > can only interact with TEE from userspace). > > > > > > > Following is the kernel interface for OP-TEE device enumeration that I > > would like to propose: > > > > /* > > * Get next OP-TEE based kernel device > > * > > * Secure world can provide support for resident kernel devices/services > > * as pseudo/early trusted applications. So this function is used to > > * enumerate OP-TEE based kernel devices. > > * > > * Call register usage: > > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > > * a1-6 Not used > > * a7 Hypervisor Client ID register > > * > > * Possible return values: > > * > > * OP-TEE OS returns next device UUID. > > * a0 OPTEE_SMC_RETURN_OK > > * a1-4 Device UUID > > * a5-7 Preserved > > * > > * OP-TEE OS does not recognize this function. > > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > > * a1-7 Preserved > > * > > * OP-TEE OS done with device enumeration. > > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > > * a1-7 Preserved > > */ > > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > > #define OPTEE_SMC_GET_NEXT_DEVICE \ > > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > > detect particular pseudo/early TA as a kernel device during > > enumeration. > > I'd rather provide this enumeration via a pseudo TA, to keep the SMC > interface as small as possible. The pseudo TA can be optional, if it's > not available then there's no need to try to instantiate any dependent > drivers either. > I did thought about having a pseudo TA but following are some negatives to this approach: 1. Where do we specify UUID for this pseudo TA? Should it come from devicetree? 2. Adds whole TEE call sequence (ctx, session, shared memory etc.) during "optee_probe". 3. This pseudo TA would be exposed to user-space as well. I am not sure if we would like user-space to access kernel device specific info. -Sumit > - Jens > > > > > -Sumit > > > > > > > > Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-04 12:01 ` Sumit Garg @ 2019-01-04 13:03 ` Jens Wiklander 2019-01-07 5:32 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Jens Wiklander @ 2019-01-04 13:03 UTC (permalink / raw) To: Sumit Garg Cc: Daniel Thompson, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Fri, Jan 4, 2019 at 1:02 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > On Fri, 4 Jan 2019 at 16:31, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > > > generator identifier property. It could be used on ARM based devices > > > > > > > where entropy source is not accessible to normal world (linux in this > > > > > > > case). > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > --- > > > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > index d38834c..e3a4c35 100644 > > > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > > > + hardware entropy source is not accesible to normal world > > > > > > > + (Linux). > > > > > > > > > > > > > > > > > > > > > Example: > > > > > > > @@ -27,5 +30,6 @@ Example: > > > > > > > optee { > > > > > > > compatible = "linaro,optee-tz"; > > > > > > > method = "smc"; > > > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > > > UUIDs. > > > > > > > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > > > agreed to discuss in upstream to get more feedback. > > > > > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > > > identified via UUIDs, probably queried from underline implementations > > > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > > > supports. Then this list of device UUIDs can be compared against child > > > > > driver's UUID as part of match callback during driver registration. > > > > > Also the child driver could maintain list of device UUIDs which it > > > > > supports. > > > > > > > > > > If we go via this approach we may not require device tree entry for > > > > > corresponding device UUIDs. > > > > > > > > That's pretty much aligned with my thinking. > > > > > > > > Having said that I had wondered whether all TEEs would be prepared to > > > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > > > part of the GlobalPlatform standards so it is not implemented by GP > > > > based TEEs (such as OP-TEE). > > > > > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > > > If nothing else can it provide an (optional) pseudo TA to provide such a > > > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > > > mandated such a service (e.g. a TEE that does not provide the service > > > > can only interact with TEE from userspace). > > > > > > > > > > Following is the kernel interface for OP-TEE device enumeration that I > > > would like to propose: > > > > > > /* > > > * Get next OP-TEE based kernel device > > > * > > > * Secure world can provide support for resident kernel devices/services > > > * as pseudo/early trusted applications. So this function is used to > > > * enumerate OP-TEE based kernel devices. > > > * > > > * Call register usage: > > > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > > > * a1-6 Not used > > > * a7 Hypervisor Client ID register > > > * > > > * Possible return values: > > > * > > > * OP-TEE OS returns next device UUID. > > > * a0 OPTEE_SMC_RETURN_OK > > > * a1-4 Device UUID > > > * a5-7 Preserved > > > * > > > * OP-TEE OS does not recognize this function. > > > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > > > * a1-7 Preserved > > > * > > > * OP-TEE OS done with device enumeration. > > > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > > > * a1-7 Preserved > > > */ > > > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > > > #define OPTEE_SMC_GET_NEXT_DEVICE \ > > > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > > > > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > > > detect particular pseudo/early TA as a kernel device during > > > enumeration. > > > > I'd rather provide this enumeration via a pseudo TA, to keep the SMC > > interface as small as possible. The pseudo TA can be optional, if it's > > not available then there's no need to try to instantiate any dependent > > drivers either. > > > > I did thought about having a pseudo TA but following are some > negatives to this approach: > 1. Where do we specify UUID for this pseudo TA? Should it come from devicetree? This should be a well known UUID, provided in the .h file describing the TA. > 2. Adds whole TEE call sequence (ctx, session, shared memory etc.) > during "optee_probe". Yes, is that a problem? > 3. This pseudo TA would be exposed to user-space as well. I am not > sure if we would like user-space to access kernel device specific > info. Doesn't matter, that's not a secret. We can assume that an attacker already know the UUID of whatever TA it will target. - Jens > > -Sumit > > > - Jens > > > > > > > > -Sumit > > > > > > > > > > > Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-04 13:03 ` Jens Wiklander @ 2019-01-07 5:32 ` Sumit Garg 2019-01-07 5:59 ` Ard Biesheuvel 0 siblings, 1 reply; 25+ messages in thread From: Sumit Garg @ 2019-01-07 5:32 UTC (permalink / raw) To: Jens Wiklander Cc: Daniel Thompson, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Fri, 4 Jan 2019 at 18:33, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > On Fri, Jan 4, 2019 at 1:02 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Fri, 4 Jan 2019 at 16:31, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > > > > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > > > > generator identifier property. It could be used on ARM based devices > > > > > > > > where entropy source is not accessible to normal world (linux in this > > > > > > > > case). > > > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > --- > > > > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > index d38834c..e3a4c35 100644 > > > > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > > > > + hardware entropy source is not accesible to normal world > > > > > > > > + (Linux). > > > > > > > > > > > > > > > > > > > > > > > > Example: > > > > > > > > @@ -27,5 +30,6 @@ Example: > > > > > > > > optee { > > > > > > > > compatible = "linaro,optee-tz"; > > > > > > > > method = "smc"; > > > > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > > > > UUIDs. > > > > > > > > > > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > > > > agreed to discuss in upstream to get more feedback. > > > > > > > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > > > > identified via UUIDs, probably queried from underline implementations > > > > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > > > > supports. Then this list of device UUIDs can be compared against child > > > > > > driver's UUID as part of match callback during driver registration. > > > > > > Also the child driver could maintain list of device UUIDs which it > > > > > > supports. > > > > > > > > > > > > If we go via this approach we may not require device tree entry for > > > > > > corresponding device UUIDs. > > > > > > > > > > That's pretty much aligned with my thinking. > > > > > > > > > > Having said that I had wondered whether all TEEs would be prepared to > > > > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > > > > part of the GlobalPlatform standards so it is not implemented by GP > > > > > based TEEs (such as OP-TEE). > > > > > > > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > > > > If nothing else can it provide an (optional) pseudo TA to provide such a > > > > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > > > > mandated such a service (e.g. a TEE that does not provide the service > > > > > can only interact with TEE from userspace). > > > > > > > > > > > > > Following is the kernel interface for OP-TEE device enumeration that I > > > > would like to propose: > > > > > > > > /* > > > > * Get next OP-TEE based kernel device > > > > * > > > > * Secure world can provide support for resident kernel devices/services > > > > * as pseudo/early trusted applications. So this function is used to > > > > * enumerate OP-TEE based kernel devices. > > > > * > > > > * Call register usage: > > > > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > > > > * a1-6 Not used > > > > * a7 Hypervisor Client ID register > > > > * > > > > * Possible return values: > > > > * > > > > * OP-TEE OS returns next device UUID. > > > > * a0 OPTEE_SMC_RETURN_OK > > > > * a1-4 Device UUID > > > > * a5-7 Preserved > > > > * > > > > * OP-TEE OS does not recognize this function. > > > > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > > > > * a1-7 Preserved > > > > * > > > > * OP-TEE OS done with device enumeration. > > > > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > > > > * a1-7 Preserved > > > > */ > > > > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > > > > #define OPTEE_SMC_GET_NEXT_DEVICE \ > > > > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > > > > > > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > > > > detect particular pseudo/early TA as a kernel device during > > > > enumeration. > > > > > > I'd rather provide this enumeration via a pseudo TA, to keep the SMC > > > interface as small as possible. The pseudo TA can be optional, if it's > > > not available then there's no need to try to instantiate any dependent > > > drivers either. > > > > > > > I did thought about having a pseudo TA but following are some > > negatives to this approach: > > 1. Where do we specify UUID for this pseudo TA? Should it come from devicetree? > > This should be a well known UUID, provided in the .h file describing the TA. > Ok. > > 2. Adds whole TEE call sequence (ctx, session, shared memory etc.) > > during "optee_probe". > > Yes, is that a problem? > Not a problem but simply fast call interface is comparatively quicker. > > 3. This pseudo TA would be exposed to user-space as well. I am not > > sure if we would like user-space to access kernel device specific > > info. > > Doesn't matter, that's not a secret. We can assume that an attacker > already know the UUID of whatever TA it will target. > Okay then as per your suggestion will implement enumeration via pseudo TA approach. -Sumit > - Jens > > > > > -Sumit > > > > > - Jens > > > > > > > > > > > -Sumit > > > > > > > > > > > > > > Daniel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-07 5:32 ` Sumit Garg @ 2019-01-07 5:59 ` Ard Biesheuvel 2019-01-07 6:46 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Ard Biesheuvel @ 2019-01-07 5:59 UTC (permalink / raw) To: Sumit Garg Cc: Jens Wiklander, Daniel Thompson, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Mon, 7 Jan 2019 at 06:32, Sumit Garg <sumit.garg@linaro.org> wrote: > > On Fri, 4 Jan 2019 at 18:33, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > On Fri, Jan 4, 2019 at 1:02 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > On Fri, 4 Jan 2019 at 16:31, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > > > On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > > > > > > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > > > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > > > > > generator identifier property. It could be used on ARM based devices > > > > > > > > > where entropy source is not accessible to normal world (linux in this > > > > > > > > > case). > > > > > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > > --- > > > > > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > index d38834c..e3a4c35 100644 > > > > > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > > > > > + hardware entropy source is not accesible to normal world > > > > > > > > > + (Linux). > > > > > > > > > > > > > > > > > > > > > > > > > > > Example: > > > > > > > > > @@ -27,5 +30,6 @@ Example: > > > > > > > > > optee { > > > > > > > > > compatible = "linaro,optee-tz"; > > > > > > > > > method = "smc"; > > > > > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > > > > > UUIDs. > > > > > > > > > > > > > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > > > > > agreed to discuss in upstream to get more feedback. > > > > > > > > > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > > > > > identified via UUIDs, probably queried from underline implementations > > > > > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > > > > > supports. Then this list of device UUIDs can be compared against child > > > > > > > driver's UUID as part of match callback during driver registration. > > > > > > > Also the child driver could maintain list of device UUIDs which it > > > > > > > supports. > > > > > > > > > > > > > > If we go via this approach we may not require device tree entry for > > > > > > > corresponding device UUIDs. > > > > > > > > > > > > That's pretty much aligned with my thinking. > > > > > > > > > > > > Having said that I had wondered whether all TEEs would be prepared to > > > > > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > > > > > part of the GlobalPlatform standards so it is not implemented by GP > > > > > > based TEEs (such as OP-TEE). > > > > > > > > > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > > > > > If nothing else can it provide an (optional) pseudo TA to provide such a > > > > > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > > > > > mandated such a service (e.g. a TEE that does not provide the service > > > > > > can only interact with TEE from userspace). > > > > > > > > > > > > > > > > Following is the kernel interface for OP-TEE device enumeration that I > > > > > would like to propose: > > > > > > > > > > /* > > > > > * Get next OP-TEE based kernel device > > > > > * > > > > > * Secure world can provide support for resident kernel devices/services > > > > > * as pseudo/early trusted applications. So this function is used to > > > > > * enumerate OP-TEE based kernel devices. > > > > > * > > > > > * Call register usage: > > > > > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > > > > > * a1-6 Not used > > > > > * a7 Hypervisor Client ID register > > > > > * > > > > > * Possible return values: > > > > > * > > > > > * OP-TEE OS returns next device UUID. > > > > > * a0 OPTEE_SMC_RETURN_OK > > > > > * a1-4 Device UUID > > > > > * a5-7 Preserved > > > > > * > > > > > * OP-TEE OS does not recognize this function. > > > > > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > > > > > * a1-7 Preserved > > > > > * > > > > > * OP-TEE OS done with device enumeration. > > > > > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > > > > > * a1-7 Preserved > > > > > */ > > > > > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > > > > > #define OPTEE_SMC_GET_NEXT_DEVICE \ > > > > > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > > > > > > > > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > > > > > detect particular pseudo/early TA as a kernel device during > > > > > enumeration. > > > > > > > > I'd rather provide this enumeration via a pseudo TA, to keep the SMC > > > > interface as small as possible. The pseudo TA can be optional, if it's > > > > not available then there's no need to try to instantiate any dependent > > > > drivers either. > > > > > > > > > > I did thought about having a pseudo TA but following are some > > > negatives to this approach: > > > 1. Where do we specify UUID for this pseudo TA? Should it come from devicetree? > > > > This should be a well known UUID, provided in the .h file describing the TA. > > > > Ok. > > > > 2. Adds whole TEE call sequence (ctx, session, shared memory etc.) > > > during "optee_probe". > > > > Yes, is that a problem? > > > > Not a problem but simply fast call interface is comparatively quicker. > > > > 3. This pseudo TA would be exposed to user-space as well. I am not > > > sure if we would like user-space to access kernel device specific > > > info. > > > > Doesn't matter, that's not a secret. We can assume that an attacker > > already know the UUID of whatever TA it will target. > > > > Okay then as per your suggestion will implement enumeration via pseudo > TA approach. > But this also requires some kind of well-known GUID for the RNG function, no? ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2019-01-07 5:59 ` Ard Biesheuvel @ 2019-01-07 6:46 ` Sumit Garg 0 siblings, 0 replies; 25+ messages in thread From: Sumit Garg @ 2019-01-07 6:46 UTC (permalink / raw) To: Ard Biesheuvel Cc: Jens Wiklander, Daniel Thompson, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Bhupesh Sharma, tee-dev On Mon, 7 Jan 2019 at 11:29, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > On Mon, 7 Jan 2019 at 06:32, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Fri, 4 Jan 2019 at 18:33, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > On Fri, Jan 4, 2019 at 1:02 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > On Fri, 4 Jan 2019 at 16:31, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > > > > > On Fri, Jan 4, 2019 at 7:39 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > On Thu, 3 Jan 2019 at 22:44, Daniel Thompson <daniel.thompson@linaro.org> wrote: > > > > > > > > > > > > > > On Fri, Dec 28, 2018 at 02:41:01PM +0530, Sumit Garg wrote: > > > > > > > > On Thu, 27 Dec 2018 at 19:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > > > > > Add bindings for OP-TEE based optional hardware random number > > > > > > > > > > generator identifier property. It could be used on ARM based devices > > > > > > > > > > where entropy source is not accessible to normal world (linux in this > > > > > > > > > > case). > > > > > > > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > > > --- > > > > > > > > > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > > > > > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > > index d38834c..e3a4c35 100644 > > > > > > > > > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > > > > > > > > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > > > > > > > > > "hvc" : HVC #0, with the register assignments specified > > > > > > > > > > in drivers/tee/optee/optee_smc.h > > > > > > > > > > > > > > > > > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > > > > > > > > > + hardware entropy source is not accesible to normal world > > > > > > > > > > + (Linux). > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Example: > > > > > > > > > > @@ -27,5 +30,6 @@ Example: > > > > > > > > > > optee { > > > > > > > > > > compatible = "linaro,optee-tz"; > > > > > > > > > > method = "smc"; > > > > > > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > > > > > > > > > > > > > > If OP-TEE is going to expose devices in this way, it should be modeled > > > > > > > > > more like a bus driver, i.e., sub-nodes that represent the devices, > > > > > > > > > with compatible strings, and perhaps even 'reg' properties for the > > > > > > > > > UUIDs. > > > > > > > > > > > > > > > > > > > > > > > > > This is something Daniel also suggested during our discussion. But we > > > > > > > > agreed to discuss in upstream to get more feedback. > > > > > > > > > > > > > > > > I think generic TEE should be modelled as a bus driver with devices > > > > > > > > identified via UUIDs, probably queried from underline implementations > > > > > > > > like OP-TEE regarding which resident devices (pseudo-TA UUIDs) it > > > > > > > > supports. Then this list of device UUIDs can be compared against child > > > > > > > > driver's UUID as part of match callback during driver registration. > > > > > > > > Also the child driver could maintain list of device UUIDs which it > > > > > > > > supports. > > > > > > > > > > > > > > > > If we go via this approach we may not require device tree entry for > > > > > > > > corresponding device UUIDs. > > > > > > > > > > > > > > That's pretty much aligned with my thinking. > > > > > > > > > > > > > > Having said that I had wondered whether all TEEs would be prepared to > > > > > > > describe the set of available UUIDs since AFAIK UUID enumeration isn't > > > > > > > part of the GlobalPlatform standards so it is not implemented by GP > > > > > > > based TEEs (such as OP-TEE). > > > > > > > > > > > > > > Is it feasible to extend OP-TEE to enumerate the available UUIDs? > > > > > > > If nothing else can it provide an (optional) pseudo TA to provide such a > > > > > > > service? Personally I'd be OK with a kernel TEE bus infrastructure that > > > > > > > mandated such a service (e.g. a TEE that does not provide the service > > > > > > > can only interact with TEE from userspace). > > > > > > > > > > > > > > > > > > > Following is the kernel interface for OP-TEE device enumeration that I > > > > > > would like to propose: > > > > > > > > > > > > /* > > > > > > * Get next OP-TEE based kernel device > > > > > > * > > > > > > * Secure world can provide support for resident kernel devices/services > > > > > > * as pseudo/early trusted applications. So this function is used to > > > > > > * enumerate OP-TEE based kernel devices. > > > > > > * > > > > > > * Call register usage: > > > > > > * a0 SMC Function ID, OPTEE_SMC_GET_NEXT_DEVICE > > > > > > * a1-6 Not used > > > > > > * a7 Hypervisor Client ID register > > > > > > * > > > > > > * Possible return values: > > > > > > * > > > > > > * OP-TEE OS returns next device UUID. > > > > > > * a0 OPTEE_SMC_RETURN_OK > > > > > > * a1-4 Device UUID > > > > > > * a5-7 Preserved > > > > > > * > > > > > > * OP-TEE OS does not recognize this function. > > > > > > * a0 OPTEE_SMC_RETURN_UNKNOWN_FUNCTION > > > > > > * a1-7 Preserved > > > > > > * > > > > > > * OP-TEE OS done with device enumeration. > > > > > > * a0 OPTEE_SMC_RETURN_ENOTAVAIL > > > > > > * a1-7 Preserved > > > > > > */ > > > > > > #define OPTEE_SMC_FUNCID_GET_NEXT_DEVICE 15 > > > > > > #define OPTEE_SMC_GET_NEXT_DEVICE \ > > > > > > OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_NEXT_DEVICE) > > > > > > > > > > > > Also at OP-TEE end, we should add additional TA_FLAG_KERNEL_DEVICE to > > > > > > detect particular pseudo/early TA as a kernel device during > > > > > > enumeration. > > > > > > > > > > I'd rather provide this enumeration via a pseudo TA, to keep the SMC > > > > > interface as small as possible. The pseudo TA can be optional, if it's > > > > > not available then there's no need to try to instantiate any dependent > > > > > drivers either. > > > > > > > > > > > > > I did thought about having a pseudo TA but following are some > > > > negatives to this approach: > > > > 1. Where do we specify UUID for this pseudo TA? Should it come from devicetree? > > > > > > This should be a well known UUID, provided in the .h file describing the TA. > > > > > > > Ok. > > > > > > 2. Adds whole TEE call sequence (ctx, session, shared memory etc.) > > > > during "optee_probe". > > > > > > Yes, is that a problem? > > > > > > > Not a problem but simply fast call interface is comparatively quicker. > > > > > > 3. This pseudo TA would be exposed to user-space as well. I am not > > > > sure if we would like user-space to access kernel device specific > > > > info. > > > > > > Doesn't matter, that's not a secret. We can assume that an attacker > > > already know the UUID of whatever TA it will target. > > > > > > > Okay then as per your suggestion will implement enumeration via pseudo > > TA approach. > > > > But this also requires some kind of well-known GUID for the RNG function, no? I don't think so. For optee-rng driver I plan to use following rng_id_table (used during match callback) which could be populated with other platform specific RNG UUID/GUID later: struct tee_client_device_id rng_id_table[] = { {UUID_INIT(0xab7a617c, 0xb8e7, 0x4d8f, 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64)}, {} }; -Sumit ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property 2018-12-27 13:39 ` Ard Biesheuvel 2018-12-28 9:11 ` Sumit Garg @ 2019-01-03 16:20 ` Rob Herring 1 sibling, 0 replies; 25+ messages in thread From: Rob Herring @ 2019-01-03 16:20 UTC (permalink / raw) To: Ard Biesheuvel, Sumit Garg Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, Matt Mackall, Herbert Xu, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Thu, Dec 27, 2018 at 7:40 AM Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Add bindings for OP-TEE based optional hardware random number > > generator identifier property. It could be used on ARM based devices > > where entropy source is not accessible to normal world (linux in this > > case). > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > --- > > Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > index d38834c..e3a4c35 100644 > > --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt > > @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. > > "hvc" : HVC #0, with the register assignments specified > > in drivers/tee/optee/optee_smc.h > > > > +- rng-uuid : Optional OP-TEE based RNG service identifier in case > > + hardware entropy source is not accesible to normal world > > + (Linux). > > > > > > Example: > > @@ -27,5 +30,6 @@ Example: > > optee { > > compatible = "linaro,optee-tz"; > > method = "smc"; > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > If OP-TEE is going to expose devices in this way, it should be modeled > more like a bus driver, i.e., sub-nodes that represent the devices, > with compatible strings, and perhaps even 'reg' properties for the > UUIDs. Please, no. We have DT for things that are not discoverable. Make OP-TEE services/devices discoverable. We only need the OP-TEE node in the first place because sub-functions of the SMC-CC itself isn't discoverable. I suppose there could be some need to expose providers to consumer nodes in DT, but that's not the case here. Rob ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-27 11:07 [PATCH v1 0/2] Add OP-TEE based hwrng driver Sumit Garg 2018-12-27 11:07 ` [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property Sumit Garg @ 2018-12-27 11:07 ` Sumit Garg 2018-12-27 18:28 ` Ard Biesheuvel 1 sibling, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-27 11:07 UTC (permalink / raw) To: linux-crypto, devicetree Cc: mpm, herbert, robh+dt, mark.rutland, arnd, gregkh, jens.wiklander, daniel.thompson, ard.biesheuvel, bhsharma, tee-dev, Sumit Garg On ARM SoC's with TrustZone enabled, peripherals like entropy sources might not be accessible to normal world (linux in this case) and rather accessible to secure world (OP-TEE in this case) only. So this driver aims to provides a generic interface to OP-TEE based random number generator service. Signed-off-by: Sumit Garg <sumit.garg@linaro.org> --- MAINTAINERS | 5 + drivers/char/hw_random/Kconfig | 15 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ 4 files changed, 294 insertions(+) create mode 100644 drivers/char/hw_random/optee-rng.c diff --git a/MAINTAINERS b/MAINTAINERS index 0767f1d..fe0fb74 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> S: Maintained F: drivers/tee/optee/ +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER +M: Sumit Garg <sumit.garg@linaro.org> +S: Maintained +F: drivers/char/hw_random/optee-rng.c + OPA-VNIC DRIVER M: Dennis Dalessandro <dennis.dalessandro@intel.com> M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dac895d..25a7d8f 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS will be called exynos-trng. If unsure, say Y. + +config HW_RANDOM_OPTEE + tristate "OP-TEE based Random Number Generator support" + depends on OPTEE + default HW_RANDOM + help + This driver provides support for OP-TEE based Random Number + Generator on ARM SoCs where hardware entropy sources are not + accessible to normal world (Linux). + + To compile this driver as a module, choose M here: the module + will be called optee-rng. + + If unsure, say Y. + endif # HW_RANDOM config UML_RANDOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index e35ec3c..7c9ef4a 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c new file mode 100644 index 0000000..8c63730 --- /dev/null +++ b/drivers/char/hw_random/optee-rng.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Linaro Ltd. + */ + +#include <linux/delay.h> +#include <linux/of.h> +#include <linux/hw_random.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/tee_drv.h> +#include <linux/uuid.h> + +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 + +/* + * TA_CMD_GET_ENTROPY - Get Entropy from RNG + * + * param[0] (inout memref) - Entropy buffer memory reference + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed + */ +#define TA_CMD_GET_ENTROPY 0x0 + +/* + * TA_CMD_GET_RNG_INFO - Get RNG information + * + * param[0] (out value) - value.a: RNG data-rate in bytes per second + * value.b: Quality/Entropy per 1024 bit of data + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define TA_CMD_GET_RNG_INFO 0x1 + +#define MAX_ENTROPY_REQ_SZ (4 * 1024) + +static struct tee_context *ctx; +static struct tee_shm *entropy_shm_pool; +static u32 ta_rng_data_rate; +static u32 ta_rng_seesion_id; + +static size_t get_optee_rng_data(void *buf, size_t req_size) +{ + u32 ret = 0; + u8 *rng_data = NULL; + size_t rng_size = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_RNG function of Trusted App */ + inv_arg.func = TA_CMD_GET_ENTROPY; + inv_arg.session = ta_rng_seesion_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + param[0].u.memref.shm = entropy_shm_pool; + param[0].u.memref.size = req_size; + param[0].u.memref.shm_offs = 0; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", + inv_arg.ret); + return 0; + } + + rng_data = tee_shm_get_va(entropy_shm_pool, 0); + if (IS_ERR(rng_data)) { + pr_err("tee_shm_get_va failed\n"); + return 0; + } + + rng_size = param[0].u.memref.size; + memcpy(buf, rng_data, rng_size); + + return rng_size; +} + +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + u8 *data = buf; + size_t read = 0, rng_size = 0; + int timeout = 1; + + if (max > MAX_ENTROPY_REQ_SZ) + max = MAX_ENTROPY_REQ_SZ; + + while (read == 0) { + rng_size = get_optee_rng_data(data, (max - read)); + + data += rng_size; + read += rng_size; + + if (wait) { + if (timeout-- == 0) + return read; + msleep((1000 * (max - read)) / ta_rng_data_rate); + } else { + return read; + } + } + + return read; +} + +static int optee_rng_init(struct hwrng *rng) +{ + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + if (IS_ERR(entropy_shm_pool)) { + pr_err("tee_shm_alloc failed\n"); + return PTR_ERR(entropy_shm_pool); + } + + return 0; +} + +static void optee_rng_cleanup(struct hwrng *rng) +{ + tee_shm_free(entropy_shm_pool); +} + +static struct hwrng optee_rng = { + .name = "optee-rng", + .init = optee_rng_init, + .cleanup = optee_rng_cleanup, + .read = optee_rng_read, +}; + +static const struct of_device_id optee_match[] = { + { .compatible = "linaro,optee-tz" }, + {}, +}; + +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) +{ + struct device_node *fw_np; + struct device_node *np; + const char *uuid; + + /* Node is supposed to be below /firmware */ + fw_np = of_find_node_by_name(NULL, "firmware"); + if (!fw_np) + return -ENODEV; + + np = of_find_matching_node(fw_np, optee_match); + if (!np || !of_device_is_available(np)) + return -ENODEV; + + if (of_property_read_string(np, "rng-uuid", &uuid)) { + pr_warn("missing \"uuid\" property\n"); + return -ENXIO; + } + + if (uuid_parse(uuid, ta_rng_uuid)) { + pr_warn("incorrect rng ta uuid\n"); + return -EINVAL; + } + + return 0; +} + +static int get_optee_rng_info(void) +{ + u32 ret = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_RNG function of Trusted App */ + inv_arg.func = TA_CMD_GET_RNG_INFO; + inv_arg.session = ta_rng_seesion_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", + inv_arg.ret); + return -EINVAL; + } + + ta_rng_data_rate = param[0].u.value.a; + optee_rng.quality = param[0].u.value.b; + + return 0; +} + +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) +{ + if (ver->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + else + return 0; +} + +static int __init mod_init(void) +{ + int ret = 0, err = -ENODEV; + struct tee_ioctl_open_session_arg sess_arg = {0}; + uuid_t ta_rng_uuid = {0}; + + err = get_optee_rng_uuid(&ta_rng_uuid); + if (err) + return err; + + /* Open context with TEE driver */ + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); + if (IS_ERR(ctx)) + return -ENODEV; + + /* Open session with hwrng Trusted App */ + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; + sess_arg.num_params = 0; + + ret = tee_client_open_session(ctx, &sess_arg, NULL); + if ((ret < 0) || (sess_arg.ret != 0)) { + pr_err("tee_client_open_session failed, error: %x\n", + sess_arg.ret); + err = -EINVAL; + goto out_ctx; + } + ta_rng_seesion_id = sess_arg.session; + + err = get_optee_rng_info(); + if (err) + goto out_sess; + + err = hwrng_register(&optee_rng); + if (err) { + pr_err("registering failed (%d)\n", err); + goto out_sess; + } + + return 0; + +out_sess: + tee_client_close_session(ctx, ta_rng_seesion_id); +out_ctx: + tee_client_close_context(ctx); + + return err; +} + +static void __exit mod_exit(void) +{ + tee_client_close_session(ctx, ta_rng_seesion_id); + tee_client_close_context(ctx); + hwrng_unregister(&optee_rng); +} + +module_init(mod_init); +module_exit(mod_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); +MODULE_SOFTDEP("pre: optee"); -- 2.7.4 ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-27 11:07 ` [PATCH v1 2/2] hwrng: add OP-TEE based rng driver Sumit Garg @ 2018-12-27 18:28 ` Ard Biesheuvel 2018-12-28 9:58 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Ard Biesheuvel @ 2018-12-27 18:28 UTC (permalink / raw) To: Sumit Garg Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > might not be accessible to normal world (linux in this case) and rather > accessible to secure world (OP-TEE in this case) only. So this driver > aims to provides a generic interface to OP-TEE based random number > generator service. > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > --- > MAINTAINERS | 5 + > drivers/char/hw_random/Kconfig | 15 ++ > drivers/char/hw_random/Makefile | 1 + > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 294 insertions(+) > create mode 100644 drivers/char/hw_random/optee-rng.c > Hi Sumit, I am having some trouble with this driver. Even though the firmware manages to invoke the pseudo-TA, the kernel driver responds with [ 73.915971] tee_client_open_session failed, error: ffff0008 (note that I need to run teesupplicant or the insmod just hangs) Also, I have some concerns about the DT dependency (see my comment on the previous patch) I will cc you on some patches I have to expose OP-TEE via ACPI (as well as DT) as a platform device. I'd prefer it if we could do the same for this driver in one way or the other. > diff --git a/MAINTAINERS b/MAINTAINERS > index 0767f1d..fe0fb74 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > S: Maintained > F: drivers/tee/optee/ > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > +M: Sumit Garg <sumit.garg@linaro.org> > +S: Maintained > +F: drivers/char/hw_random/optee-rng.c > + > OPA-VNIC DRIVER > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > index dac895d..25a7d8f 100644 > --- a/drivers/char/hw_random/Kconfig > +++ b/drivers/char/hw_random/Kconfig > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > will be called exynos-trng. > > If unsure, say Y. > + > +config HW_RANDOM_OPTEE > + tristate "OP-TEE based Random Number Generator support" > + depends on OPTEE > + default HW_RANDOM > + help > + This driver provides support for OP-TEE based Random Number > + Generator on ARM SoCs where hardware entropy sources are not > + accessible to normal world (Linux). > + > + To compile this driver as a module, choose M here: the module > + will be called optee-rng. > + > + If unsure, say Y. > + > endif # HW_RANDOM > > config UML_RANDOM > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > index e35ec3c..7c9ef4a 100644 > --- a/drivers/char/hw_random/Makefile > +++ b/drivers/char/hw_random/Makefile > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > new file mode 100644 > index 0000000..8c63730 > --- /dev/null > +++ b/drivers/char/hw_random/optee-rng.c > @@ -0,0 +1,273 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Linaro Ltd. > + */ > + > +#include <linux/delay.h> > +#include <linux/of.h> > +#include <linux/hw_random.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/tee_drv.h> > +#include <linux/uuid.h> > + > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > + > +/* > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > + * > + * param[0] (inout memref) - Entropy buffer memory reference > + * param[1] unused > + * param[2] unused > + * param[3] unused > + * > + * Result: > + * TEE_SUCCESS - Invoke command success > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > + */ > +#define TA_CMD_GET_ENTROPY 0x0 > + > +/* > + * TA_CMD_GET_RNG_INFO - Get RNG information > + * > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > + * value.b: Quality/Entropy per 1024 bit of data > + * param[1] unused > + * param[2] unused > + * param[3] unused > + * > + * Result: > + * TEE_SUCCESS - Invoke command success > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > + */ > +#define TA_CMD_GET_RNG_INFO 0x1 > + > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > + > +static struct tee_context *ctx; > +static struct tee_shm *entropy_shm_pool; > +static u32 ta_rng_data_rate; > +static u32 ta_rng_seesion_id; session not seesion > + > +static size_t get_optee_rng_data(void *buf, size_t req_size) > +{ > + u32 ret = 0; > + u8 *rng_data = NULL; > + size_t rng_size = 0; > + struct tee_ioctl_invoke_arg inv_arg = {0}; > + struct tee_param param[4] = {0}; > + > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > + inv_arg.func = TA_CMD_GET_ENTROPY; > + inv_arg.session = ta_rng_seesion_id; > + inv_arg.num_params = 4; > + > + /* Fill invoke cmd params */ > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > + param[0].u.memref.shm = entropy_shm_pool; > + param[0].u.memref.size = req_size; > + param[0].u.memref.shm_offs = 0; > + > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > + if ((ret < 0) || (inv_arg.ret != 0)) { > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > + inv_arg.ret); > + return 0; > + } > + > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > + if (IS_ERR(rng_data)) { > + pr_err("tee_shm_get_va failed\n"); > + return 0; > + } > + > + rng_size = param[0].u.memref.size; > + memcpy(buf, rng_data, rng_size); > + > + return rng_size; > +} > + > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > +{ > + u8 *data = buf; > + size_t read = 0, rng_size = 0; > + int timeout = 1; > + > + if (max > MAX_ENTROPY_REQ_SZ) > + max = MAX_ENTROPY_REQ_SZ; > + > + while (read == 0) { > + rng_size = get_optee_rng_data(data, (max - read)); > + > + data += rng_size; > + read += rng_size; > + > + if (wait) { > + if (timeout-- == 0) > + return read; > + msleep((1000 * (max - read)) / ta_rng_data_rate); > + } else { > + return read; > + } > + } > + > + return read; > +} > + > +static int optee_rng_init(struct hwrng *rng) > +{ > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > + if (IS_ERR(entropy_shm_pool)) { > + pr_err("tee_shm_alloc failed\n"); > + return PTR_ERR(entropy_shm_pool); > + } > + > + return 0; > +} > + > +static void optee_rng_cleanup(struct hwrng *rng) > +{ > + tee_shm_free(entropy_shm_pool); > +} > + > +static struct hwrng optee_rng = { > + .name = "optee-rng", > + .init = optee_rng_init, > + .cleanup = optee_rng_cleanup, > + .read = optee_rng_read, > +}; > + > +static const struct of_device_id optee_match[] = { > + { .compatible = "linaro,optee-tz" }, > + {}, > +}; > + > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > +{ > + struct device_node *fw_np; > + struct device_node *np; > + const char *uuid; > + > + /* Node is supposed to be below /firmware */ > + fw_np = of_find_node_by_name(NULL, "firmware"); > + if (!fw_np) > + return -ENODEV; > + > + np = of_find_matching_node(fw_np, optee_match); > + if (!np || !of_device_is_available(np)) > + return -ENODEV; > + > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > + pr_warn("missing \"uuid\" property\n"); > + return -ENXIO; > + } > + So, duplicating all of this is really not a good idea. > + if (uuid_parse(uuid, ta_rng_uuid)) { > + pr_warn("incorrect rng ta uuid\n"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int get_optee_rng_info(void) > +{ > + u32 ret = 0; > + struct tee_ioctl_invoke_arg inv_arg = {0}; > + struct tee_param param[4] = {0}; > + > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > + inv_arg.func = TA_CMD_GET_RNG_INFO; > + inv_arg.session = ta_rng_seesion_id; > + inv_arg.num_params = 4; > + > + /* Fill invoke cmd params */ > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > + > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > + if ((ret < 0) || (inv_arg.ret != 0)) { > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > + inv_arg.ret); > + return -EINVAL; > + } > + > + ta_rng_data_rate = param[0].u.value.a; > + optee_rng.quality = param[0].u.value.b; > + > + return 0; > +} > + > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > +{ > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > + return 1; > + else > + return 0; > +} > + > +static int __init mod_init(void) > +{ > + int ret = 0, err = -ENODEV; > + struct tee_ioctl_open_session_arg sess_arg = {0}; > + uuid_t ta_rng_uuid = {0}; > + > + err = get_optee_rng_uuid(&ta_rng_uuid); > + if (err) > + return err; > + > + /* Open context with TEE driver */ > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > + if (IS_ERR(ctx)) > + return -ENODEV; > + > + /* Open session with hwrng Trusted App */ > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > + sess_arg.num_params = 0; > + > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > + if ((ret < 0) || (sess_arg.ret != 0)) { > + pr_err("tee_client_open_session failed, error: %x\n", > + sess_arg.ret); > + err = -EINVAL; > + goto out_ctx; > + } > + ta_rng_seesion_id = sess_arg.session; > + > + err = get_optee_rng_info(); > + if (err) > + goto out_sess; > + > + err = hwrng_register(&optee_rng); > + if (err) { > + pr_err("registering failed (%d)\n", err); > + goto out_sess; > + } > + > + return 0; > + > +out_sess: > + tee_client_close_session(ctx, ta_rng_seesion_id); > +out_ctx: > + tee_client_close_context(ctx); > + > + return err; > +} > + > +static void __exit mod_exit(void) > +{ > + tee_client_close_session(ctx, ta_rng_seesion_id); > + tee_client_close_context(ctx); > + hwrng_unregister(&optee_rng); > +} > + > +module_init(mod_init); > +module_exit(mod_exit); > + > +MODULE_LICENSE("GPL"); > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > +MODULE_SOFTDEP("pre: optee"); This is also an indicator that the API design needs some work. If the OP-TEE driver becomes a 'bus' driver of some sort, the child RNG device (which is what this driver should bind to) will only exist if a) the OP-TEE driver is loaded, and b) it has actually bound to the /firmware/optee node. > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-27 18:28 ` Ard Biesheuvel @ 2018-12-28 9:58 ` Sumit Garg 2018-12-28 10:38 ` Ard Biesheuvel 0 siblings, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-28 9:58 UTC (permalink / raw) To: Ard Biesheuvel Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev Thanks Ard for your comments. On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > might not be accessible to normal world (linux in this case) and rather > > accessible to secure world (OP-TEE in this case) only. So this driver > > aims to provides a generic interface to OP-TEE based random number > > generator service. > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > --- > > MAINTAINERS | 5 + > > drivers/char/hw_random/Kconfig | 15 ++ > > drivers/char/hw_random/Makefile | 1 + > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > 4 files changed, 294 insertions(+) > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > Hi Sumit, > > I am having some trouble with this driver. Even though the firmware > manages to invoke the pseudo-TA, the kernel driver responds with > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > Please double check UUID in device tree (probably via dtc dump). > (note that I need to run teesupplicant or the insmod just hangs) > Actually OP-TEE tries to find TA in following order: 1. early/pseudo TAs (resident). 2. Dynamic TAs (loaded at runtime). So if it doesn't find early/pseudo TAs then it tries to load dynamic TAs via tee-supplicant. It seems that its probably stuck in "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits for supplicant to fulfil the request. I think this should be resolved via TEE bus driver approach that I have proposed in previous patch. > Also, I have some concerns about the DT dependency (see my comment on > the previous patch) > I will cc you on some patches I have to expose OP-TEE via ACPI (as > well as DT) as a platform device. I'd prefer it if we could do the > same for this driver in one way or the other. > Probably via TEE bus driver approach we may get rid of DT or ACPI dependency. BTW, I will switch to platform device as it looks more appropriate. > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 0767f1d..fe0fb74 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > S: Maintained > > F: drivers/tee/optee/ > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > +M: Sumit Garg <sumit.garg@linaro.org> > > +S: Maintained > > +F: drivers/char/hw_random/optee-rng.c > > + > > OPA-VNIC DRIVER > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > index dac895d..25a7d8f 100644 > > --- a/drivers/char/hw_random/Kconfig > > +++ b/drivers/char/hw_random/Kconfig > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > will be called exynos-trng. > > > > If unsure, say Y. > > + > > +config HW_RANDOM_OPTEE > > + tristate "OP-TEE based Random Number Generator support" > > + depends on OPTEE > > + default HW_RANDOM > > + help > > + This driver provides support for OP-TEE based Random Number > > + Generator on ARM SoCs where hardware entropy sources are not > > + accessible to normal world (Linux). > > + > > + To compile this driver as a module, choose M here: the module > > + will be called optee-rng. > > + > > + If unsure, say Y. > > + > > endif # HW_RANDOM > > > > config UML_RANDOM > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > index e35ec3c..7c9ef4a 100644 > > --- a/drivers/char/hw_random/Makefile > > +++ b/drivers/char/hw_random/Makefile > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > new file mode 100644 > > index 0000000..8c63730 > > --- /dev/null > > +++ b/drivers/char/hw_random/optee-rng.c > > @@ -0,0 +1,273 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2018 Linaro Ltd. > > + */ > > + > > +#include <linux/delay.h> > > +#include <linux/of.h> > > +#include <linux/hw_random.h> > > +#include <linux/kernel.h> > > +#include <linux/module.h> > > +#include <linux/tee_drv.h> > > +#include <linux/uuid.h> > > + > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > + > > +/* > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > + * > > + * param[0] (inout memref) - Entropy buffer memory reference > > + * param[1] unused > > + * param[2] unused > > + * param[3] unused > > + * > > + * Result: > > + * TEE_SUCCESS - Invoke command success > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > + */ > > +#define TA_CMD_GET_ENTROPY 0x0 > > + > > +/* > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > + * > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > + * value.b: Quality/Entropy per 1024 bit of data > > + * param[1] unused > > + * param[2] unused > > + * param[3] unused > > + * > > + * Result: > > + * TEE_SUCCESS - Invoke command success > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > + */ > > +#define TA_CMD_GET_RNG_INFO 0x1 > > + > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > + > > +static struct tee_context *ctx; > > +static struct tee_shm *entropy_shm_pool; > > +static u32 ta_rng_data_rate; > > +static u32 ta_rng_seesion_id; > > session not seesion > Will fix. > > + > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > +{ > > + u32 ret = 0; > > + u8 *rng_data = NULL; > > + size_t rng_size = 0; > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > + struct tee_param param[4] = {0}; > > + > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > + inv_arg.session = ta_rng_seesion_id; > > + inv_arg.num_params = 4; > > + > > + /* Fill invoke cmd params */ > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > + param[0].u.memref.shm = entropy_shm_pool; > > + param[0].u.memref.size = req_size; > > + param[0].u.memref.shm_offs = 0; > > + > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > + inv_arg.ret); > > + return 0; > > + } > > + > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > + if (IS_ERR(rng_data)) { > > + pr_err("tee_shm_get_va failed\n"); > > + return 0; > > + } > > + > > + rng_size = param[0].u.memref.size; > > + memcpy(buf, rng_data, rng_size); > > + > > + return rng_size; > > +} > > + > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > +{ > > + u8 *data = buf; > > + size_t read = 0, rng_size = 0; > > + int timeout = 1; > > + > > + if (max > MAX_ENTROPY_REQ_SZ) > > + max = MAX_ENTROPY_REQ_SZ; > > + > > + while (read == 0) { > > + rng_size = get_optee_rng_data(data, (max - read)); > > + > > + data += rng_size; > > + read += rng_size; > > + > > + if (wait) { > > + if (timeout-- == 0) > > + return read; > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > + } else { > > + return read; > > + } > > + } > > + > > + return read; > > +} > > + > > +static int optee_rng_init(struct hwrng *rng) > > +{ > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > + if (IS_ERR(entropy_shm_pool)) { > > + pr_err("tee_shm_alloc failed\n"); > > + return PTR_ERR(entropy_shm_pool); > > + } > > + > > + return 0; > > +} > > + > > +static void optee_rng_cleanup(struct hwrng *rng) > > +{ > > + tee_shm_free(entropy_shm_pool); > > +} > > + > > +static struct hwrng optee_rng = { > > + .name = "optee-rng", > > + .init = optee_rng_init, > > + .cleanup = optee_rng_cleanup, > > + .read = optee_rng_read, > > +}; > > + > > +static const struct of_device_id optee_match[] = { > > + { .compatible = "linaro,optee-tz" }, > > + {}, > > +}; > > + > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > +{ > > + struct device_node *fw_np; > > + struct device_node *np; > > + const char *uuid; > > + > > + /* Node is supposed to be below /firmware */ > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > + if (!fw_np) > > + return -ENODEV; > > + > > + np = of_find_matching_node(fw_np, optee_match); > > + if (!np || !of_device_is_available(np)) > > + return -ENODEV; > > + > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > + pr_warn("missing \"uuid\" property\n"); > > + return -ENXIO; > > + } > > + > > So, duplicating all of this is really not a good idea. > Yeah, we may not need this in case we go via TEE bus driver approach. > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > + pr_warn("incorrect rng ta uuid\n"); > > + return -EINVAL; > > + } > > + > > + return 0; > > +} > > + > > +static int get_optee_rng_info(void) > > +{ > > + u32 ret = 0; > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > + struct tee_param param[4] = {0}; > > + > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > + inv_arg.session = ta_rng_seesion_id; > > + inv_arg.num_params = 4; > > + > > + /* Fill invoke cmd params */ > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > + > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > + inv_arg.ret); > > + return -EINVAL; > > + } > > + > > + ta_rng_data_rate = param[0].u.value.a; > > + optee_rng.quality = param[0].u.value.b; > > + > > + return 0; > > +} > > + > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > +{ > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > + return 1; > > + else > > + return 0; > > +} > > + > > +static int __init mod_init(void) > > +{ > > + int ret = 0, err = -ENODEV; > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > + uuid_t ta_rng_uuid = {0}; > > + > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > + if (err) > > + return err; > > + > > + /* Open context with TEE driver */ > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > + if (IS_ERR(ctx)) > > + return -ENODEV; > > + > > + /* Open session with hwrng Trusted App */ > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > + sess_arg.num_params = 0; > > + > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > + pr_err("tee_client_open_session failed, error: %x\n", > > + sess_arg.ret); > > + err = -EINVAL; > > + goto out_ctx; > > + } > > + ta_rng_seesion_id = sess_arg.session; > > + > > + err = get_optee_rng_info(); > > + if (err) > > + goto out_sess; > > + > > + err = hwrng_register(&optee_rng); > > + if (err) { > > + pr_err("registering failed (%d)\n", err); > > + goto out_sess; > > + } > > + > > + return 0; > > + > > +out_sess: > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > +out_ctx: > > + tee_client_close_context(ctx); > > + > > + return err; > > +} > > + > > +static void __exit mod_exit(void) > > +{ > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > + tee_client_close_context(ctx); > > + hwrng_unregister(&optee_rng); > > +} > > + > > +module_init(mod_init); > > +module_exit(mod_exit); > > + > > +MODULE_LICENSE("GPL"); > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > +MODULE_SOFTDEP("pre: optee"); > > This is also an indicator that the API design needs some work. If the > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > device (which is what this driver should bind to) will only exist if > a) the OP-TEE driver is loaded, and b) it has actually bound to the > /firmware/optee node. > Agree. > > -- > > 2.7.4 > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-28 9:58 ` Sumit Garg @ 2018-12-28 10:38 ` Ard Biesheuvel 2018-12-28 13:03 ` Sumit Garg 0 siblings, 1 reply; 25+ messages in thread From: Ard Biesheuvel @ 2018-12-28 10:38 UTC (permalink / raw) To: Sumit Garg Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > Thanks Ard for your comments. > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > might not be accessible to normal world (linux in this case) and rather > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > aims to provides a generic interface to OP-TEE based random number > > > generator service. > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > --- > > > MAINTAINERS | 5 + > > > drivers/char/hw_random/Kconfig | 15 ++ > > > drivers/char/hw_random/Makefile | 1 + > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > 4 files changed, 294 insertions(+) > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > Hi Sumit, > > > > I am having some trouble with this driver. Even though the firmware > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > Please double check UUID in device tree (probably via dtc dump). > I have added this to the DT: --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi @@ -583,6 +583,7 @@ compatible = "linaro,optee-tz"; method = "smc"; status = "disabled"; + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; }; }; }; > > (note that I need to run teesupplicant or the insmod just hangs) > > > > Actually OP-TEE tries to find TA in following order: > > 1. early/pseudo TAs (resident). > 2. Dynamic TAs (loaded at runtime). > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > TAs via tee-supplicant. It seems that its probably stuck in > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > for supplicant to fulfil the request. > > I think this should be resolved via TEE bus driver approach that I > have proposed in previous patch. > It would be useful if we could detect the absence of teesupplicant rather than wait indefinitely. Currenty, we cannot make the RNG driver a builtin due to this, so please add 'depends on m' as a dependency if we don't resolve this in the short term. > > Also, I have some concerns about the DT dependency (see my comment on > > the previous patch) > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > well as DT) as a platform device. I'd prefer it if we could do the > > same for this driver in one way or the other. > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > dependency. BTW, I will switch to platform device as it looks more > appropriate. > The bus driver approach only makes sense if we can enumerate the available TAs, rather than describe them via the DT or ACPI tables. But a child node with its own compatible string is an improvement in any case, and you can let the driver core instantiate the platform device for you. > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > index 0767f1d..fe0fb74 100644 > > > --- a/MAINTAINERS > > > +++ b/MAINTAINERS > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > S: Maintained > > > F: drivers/tee/optee/ > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > +S: Maintained > > > +F: drivers/char/hw_random/optee-rng.c > > > + > > > OPA-VNIC DRIVER > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > index dac895d..25a7d8f 100644 > > > --- a/drivers/char/hw_random/Kconfig > > > +++ b/drivers/char/hw_random/Kconfig > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > will be called exynos-trng. > > > > > > If unsure, say Y. > > > + > > > +config HW_RANDOM_OPTEE > > > + tristate "OP-TEE based Random Number Generator support" > > > + depends on OPTEE > > > + default HW_RANDOM > > > + help > > > + This driver provides support for OP-TEE based Random Number > > > + Generator on ARM SoCs where hardware entropy sources are not > > > + accessible to normal world (Linux). > > > + > > > + To compile this driver as a module, choose M here: the module > > > + will be called optee-rng. > > > + > > > + If unsure, say Y. > > > + > > > endif # HW_RANDOM > > > > > > config UML_RANDOM > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > index e35ec3c..7c9ef4a 100644 > > > --- a/drivers/char/hw_random/Makefile > > > +++ b/drivers/char/hw_random/Makefile > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > new file mode 100644 > > > index 0000000..8c63730 > > > --- /dev/null > > > +++ b/drivers/char/hw_random/optee-rng.c > > > @@ -0,0 +1,273 @@ > > > +// SPDX-License-Identifier: GPL-2.0 > > > +/* > > > + * Copyright (C) 2018 Linaro Ltd. > > > + */ > > > + > > > +#include <linux/delay.h> > > > +#include <linux/of.h> > > > +#include <linux/hw_random.h> > > > +#include <linux/kernel.h> > > > +#include <linux/module.h> > > > +#include <linux/tee_drv.h> > > > +#include <linux/uuid.h> > > > + > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > + > > > +/* > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > + * > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > + * param[1] unused > > > + * param[2] unused > > > + * param[3] unused > > > + * > > > + * Result: > > > + * TEE_SUCCESS - Invoke command success > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > + */ > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > + > > > +/* > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > + * > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > + * value.b: Quality/Entropy per 1024 bit of data > > > + * param[1] unused > > > + * param[2] unused > > > + * param[3] unused > > > + * > > > + * Result: > > > + * TEE_SUCCESS - Invoke command success > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > + */ > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > + > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > + > > > +static struct tee_context *ctx; > > > +static struct tee_shm *entropy_shm_pool; > > > +static u32 ta_rng_data_rate; > > > +static u32 ta_rng_seesion_id; > > > > session not seesion > > > > Will fix. > > > > + > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > +{ > > > + u32 ret = 0; > > > + u8 *rng_data = NULL; > > > + size_t rng_size = 0; > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > + struct tee_param param[4] = {0}; > > > + > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > + inv_arg.session = ta_rng_seesion_id; > > > + inv_arg.num_params = 4; > > > + > > > + /* Fill invoke cmd params */ > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > + param[0].u.memref.shm = entropy_shm_pool; > > > + param[0].u.memref.size = req_size; > > > + param[0].u.memref.shm_offs = 0; > > > + > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > + inv_arg.ret); > > > + return 0; > > > + } > > > + > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > + if (IS_ERR(rng_data)) { > > > + pr_err("tee_shm_get_va failed\n"); > > > + return 0; > > > + } > > > + > > > + rng_size = param[0].u.memref.size; > > > + memcpy(buf, rng_data, rng_size); > > > + > > > + return rng_size; > > > +} > > > + > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > +{ > > > + u8 *data = buf; > > > + size_t read = 0, rng_size = 0; > > > + int timeout = 1; > > > + > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > + max = MAX_ENTROPY_REQ_SZ; > > > + > > > + while (read == 0) { > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > + > > > + data += rng_size; > > > + read += rng_size; > > > + > > > + if (wait) { > > > + if (timeout-- == 0) > > > + return read; > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > + } else { > > > + return read; > > > + } > > > + } > > > + > > > + return read; > > > +} > > > + > > > +static int optee_rng_init(struct hwrng *rng) > > > +{ > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > + if (IS_ERR(entropy_shm_pool)) { > > > + pr_err("tee_shm_alloc failed\n"); > > > + return PTR_ERR(entropy_shm_pool); > > > + } > > > + > > > + return 0; > > > +} > > > + > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > +{ > > > + tee_shm_free(entropy_shm_pool); > > > +} > > > + > > > +static struct hwrng optee_rng = { > > > + .name = "optee-rng", > > > + .init = optee_rng_init, > > > + .cleanup = optee_rng_cleanup, > > > + .read = optee_rng_read, > > > +}; > > > + > > > +static const struct of_device_id optee_match[] = { > > > + { .compatible = "linaro,optee-tz" }, > > > + {}, > > > +}; > > > + > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > +{ > > > + struct device_node *fw_np; > > > + struct device_node *np; > > > + const char *uuid; > > > + > > > + /* Node is supposed to be below /firmware */ > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > + if (!fw_np) > > > + return -ENODEV; > > > + > > > + np = of_find_matching_node(fw_np, optee_match); > > > + if (!np || !of_device_is_available(np)) > > > + return -ENODEV; > > > + > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > + pr_warn("missing \"uuid\" property\n"); > > > + return -ENXIO; > > > + } > > > + > > > > So, duplicating all of this is really not a good idea. > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > + pr_warn("incorrect rng ta uuid\n"); > > > + return -EINVAL; > > > + } > > > + > > > + return 0; > > > +} > > > + > > > +static int get_optee_rng_info(void) > > > +{ > > > + u32 ret = 0; > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > + struct tee_param param[4] = {0}; > > > + > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > + inv_arg.session = ta_rng_seesion_id; > > > + inv_arg.num_params = 4; > > > + > > > + /* Fill invoke cmd params */ > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > + > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > + inv_arg.ret); > > > + return -EINVAL; > > > + } > > > + > > > + ta_rng_data_rate = param[0].u.value.a; > > > + optee_rng.quality = param[0].u.value.b; > > > + > > > + return 0; > > > +} > > > + > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > +{ > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > + return 1; > > > + else > > > + return 0; > > > +} > > > + > > > +static int __init mod_init(void) > > > +{ > > > + int ret = 0, err = -ENODEV; > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > + uuid_t ta_rng_uuid = {0}; > > > + > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > + if (err) > > > + return err; > > > + > > > + /* Open context with TEE driver */ > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > + if (IS_ERR(ctx)) > > > + return -ENODEV; > > > + > > > + /* Open session with hwrng Trusted App */ > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > + sess_arg.num_params = 0; > > > + > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > + sess_arg.ret); > > > + err = -EINVAL; > > > + goto out_ctx; > > > + } > > > + ta_rng_seesion_id = sess_arg.session; > > > + > > > + err = get_optee_rng_info(); > > > + if (err) > > > + goto out_sess; > > > + > > > + err = hwrng_register(&optee_rng); > > > + if (err) { > > > + pr_err("registering failed (%d)\n", err); > > > + goto out_sess; > > > + } > > > + > > > + return 0; > > > + > > > +out_sess: > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > +out_ctx: > > > + tee_client_close_context(ctx); > > > + > > > + return err; > > > +} > > > + > > > +static void __exit mod_exit(void) > > > +{ > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > + tee_client_close_context(ctx); > > > + hwrng_unregister(&optee_rng); > > > +} > > > + > > > +module_init(mod_init); > > > +module_exit(mod_exit); > > > + > > > +MODULE_LICENSE("GPL"); > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > +MODULE_SOFTDEP("pre: optee"); > > > > This is also an indicator that the API design needs some work. If the > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > device (which is what this driver should bind to) will only exist if > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > /firmware/optee node. > > > > Agree. > > > > -- > > > 2.7.4 > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-28 10:38 ` Ard Biesheuvel @ 2018-12-28 13:03 ` Sumit Garg 2018-12-28 14:46 ` Jens Wiklander 0 siblings, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-28 13:03 UTC (permalink / raw) To: Ard Biesheuvel Cc: open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Jens Wiklander, Daniel Thompson, Bhupesh Sharma, tee-dev On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Thanks Ard for your comments. > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > might not be accessible to normal world (linux in this case) and rather > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > aims to provides a generic interface to OP-TEE based random number > > > > generator service. > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > --- > > > > MAINTAINERS | 5 + > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > drivers/char/hw_random/Makefile | 1 + > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > 4 files changed, 294 insertions(+) > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > Hi Sumit, > > > > > > I am having some trouble with this driver. Even though the firmware > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > I have added this to the DT: > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > @@ -583,6 +583,7 @@ > compatible = "linaro,optee-tz"; > method = "smc"; > status = "disabled"; > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > }; > }; > }; > It pretty strange as it could work well at my end. Can you please build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > 1. early/pseudo TAs (resident). > > 2. Dynamic TAs (loaded at runtime). > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > TAs via tee-supplicant. It seems that its probably stuck in > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > for supplicant to fulfil the request. > > > > I think this should be resolved via TEE bus driver approach that I > > have proposed in previous patch. > > > > It would be useful if we could detect the absence of teesupplicant > rather than wait indefinitely. Currenty, we cannot make the RNG driver > a builtin due to this, so please add 'depends on m' as a dependency if > we don't resolve this in the short term. > By default this module is out of tree only (default m). Jens, Is there any particular reason to wait indefinitely in "optee_supp_thrd_req" if there is no supplicant running? I think we should probably return as follows from "optee_supp_thrd_req" API in case no supplicant is available: --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, { struct optee *optee = tee_get_drvdata(ctx->teedev); struct optee_supp *supp = &optee->supp; - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); + struct optee_supp_req *req; bool interruptable; u32 ret; + /* Return in case there is no supplicant available */ + if (!supp->ctx) + return TEEC_ERROR_COMMUNICATION; + + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return TEEC_ERROR_OUT_OF_MEMORY; > > > Also, I have some concerns about the DT dependency (see my comment on > > > the previous patch) > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > well as DT) as a platform device. I'd prefer it if we could do the > > > same for this driver in one way or the other. > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > dependency. BTW, I will switch to platform device as it looks more > > appropriate. > > > > The bus driver approach only makes sense if we can enumerate the > available TAs, rather than describe them via the DT or ACPI tables. > > But a child node with its own compatible string is an improvement in > any case, and you can let the driver core instantiate the platform > device for you. > Ok then I will keep DT or ACPI child node. -Sumit > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > index 0767f1d..fe0fb74 100644 > > > > --- a/MAINTAINERS > > > > +++ b/MAINTAINERS > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > S: Maintained > > > > F: drivers/tee/optee/ > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > +S: Maintained > > > > +F: drivers/char/hw_random/optee-rng.c > > > > + > > > > OPA-VNIC DRIVER > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > index dac895d..25a7d8f 100644 > > > > --- a/drivers/char/hw_random/Kconfig > > > > +++ b/drivers/char/hw_random/Kconfig > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > will be called exynos-trng. > > > > > > > > If unsure, say Y. > > > > + > > > > +config HW_RANDOM_OPTEE > > > > + tristate "OP-TEE based Random Number Generator support" > > > > + depends on OPTEE > > > > + default HW_RANDOM > > > > + help > > > > + This driver provides support for OP-TEE based Random Number > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > + accessible to normal world (Linux). > > > > + > > > > + To compile this driver as a module, choose M here: the module > > > > + will be called optee-rng. > > > > + > > > > + If unsure, say Y. > > > > + > > > > endif # HW_RANDOM > > > > > > > > config UML_RANDOM > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > index e35ec3c..7c9ef4a 100644 > > > > --- a/drivers/char/hw_random/Makefile > > > > +++ b/drivers/char/hw_random/Makefile > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > new file mode 100644 > > > > index 0000000..8c63730 > > > > --- /dev/null > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > @@ -0,0 +1,273 @@ > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > +/* > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > + */ > > > > + > > > > +#include <linux/delay.h> > > > > +#include <linux/of.h> > > > > +#include <linux/hw_random.h> > > > > +#include <linux/kernel.h> > > > > +#include <linux/module.h> > > > > +#include <linux/tee_drv.h> > > > > +#include <linux/uuid.h> > > > > + > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > + > > > > +/* > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > + * > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > + * param[1] unused > > > > + * param[2] unused > > > > + * param[3] unused > > > > + * > > > > + * Result: > > > > + * TEE_SUCCESS - Invoke command success > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > + */ > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > + > > > > +/* > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > + * > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > + * param[1] unused > > > > + * param[2] unused > > > > + * param[3] unused > > > > + * > > > > + * Result: > > > > + * TEE_SUCCESS - Invoke command success > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > + */ > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > + > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > + > > > > +static struct tee_context *ctx; > > > > +static struct tee_shm *entropy_shm_pool; > > > > +static u32 ta_rng_data_rate; > > > > +static u32 ta_rng_seesion_id; > > > > > > session not seesion > > > > > > > Will fix. > > > > > > + > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > +{ > > > > + u32 ret = 0; > > > > + u8 *rng_data = NULL; > > > > + size_t rng_size = 0; > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > + struct tee_param param[4] = {0}; > > > > + > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > + inv_arg.session = ta_rng_seesion_id; > > > > + inv_arg.num_params = 4; > > > > + > > > > + /* Fill invoke cmd params */ > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > + param[0].u.memref.size = req_size; > > > > + param[0].u.memref.shm_offs = 0; > > > > + > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > + inv_arg.ret); > > > > + return 0; > > > > + } > > > > + > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > + if (IS_ERR(rng_data)) { > > > > + pr_err("tee_shm_get_va failed\n"); > > > > + return 0; > > > > + } > > > > + > > > > + rng_size = param[0].u.memref.size; > > > > + memcpy(buf, rng_data, rng_size); > > > > + > > > > + return rng_size; > > > > +} > > > > + > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > +{ > > > > + u8 *data = buf; > > > > + size_t read = 0, rng_size = 0; > > > > + int timeout = 1; > > > > + > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > + > > > > + while (read == 0) { > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > + > > > > + data += rng_size; > > > > + read += rng_size; > > > > + > > > > + if (wait) { > > > > + if (timeout-- == 0) > > > > + return read; > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > + } else { > > > > + return read; > > > > + } > > > > + } > > > > + > > > > + return read; > > > > +} > > > > + > > > > +static int optee_rng_init(struct hwrng *rng) > > > > +{ > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > + pr_err("tee_shm_alloc failed\n"); > > > > + return PTR_ERR(entropy_shm_pool); > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > +{ > > > > + tee_shm_free(entropy_shm_pool); > > > > +} > > > > + > > > > +static struct hwrng optee_rng = { > > > > + .name = "optee-rng", > > > > + .init = optee_rng_init, > > > > + .cleanup = optee_rng_cleanup, > > > > + .read = optee_rng_read, > > > > +}; > > > > + > > > > +static const struct of_device_id optee_match[] = { > > > > + { .compatible = "linaro,optee-tz" }, > > > > + {}, > > > > +}; > > > > + > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > +{ > > > > + struct device_node *fw_np; > > > > + struct device_node *np; > > > > + const char *uuid; > > > > + > > > > + /* Node is supposed to be below /firmware */ > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > + if (!fw_np) > > > > + return -ENODEV; > > > > + > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > + if (!np || !of_device_is_available(np)) > > > > + return -ENODEV; > > > > + > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > + pr_warn("missing \"uuid\" property\n"); > > > > + return -ENXIO; > > > > + } > > > > + > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > + return -EINVAL; > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int get_optee_rng_info(void) > > > > +{ > > > > + u32 ret = 0; > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > + struct tee_param param[4] = {0}; > > > > + > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > + inv_arg.session = ta_rng_seesion_id; > > > > + inv_arg.num_params = 4; > > > > + > > > > + /* Fill invoke cmd params */ > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > + > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > + inv_arg.ret); > > > > + return -EINVAL; > > > > + } > > > > + > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > + optee_rng.quality = param[0].u.value.b; > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > +{ > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > + return 1; > > > > + else > > > > + return 0; > > > > +} > > > > + > > > > +static int __init mod_init(void) > > > > +{ > > > > + int ret = 0, err = -ENODEV; > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > + uuid_t ta_rng_uuid = {0}; > > > > + > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > + if (err) > > > > + return err; > > > > + > > > > + /* Open context with TEE driver */ > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > + if (IS_ERR(ctx)) > > > > + return -ENODEV; > > > > + > > > > + /* Open session with hwrng Trusted App */ > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > + sess_arg.num_params = 0; > > > > + > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > + sess_arg.ret); > > > > + err = -EINVAL; > > > > + goto out_ctx; > > > > + } > > > > + ta_rng_seesion_id = sess_arg.session; > > > > + > > > > + err = get_optee_rng_info(); > > > > + if (err) > > > > + goto out_sess; > > > > + > > > > + err = hwrng_register(&optee_rng); > > > > + if (err) { > > > > + pr_err("registering failed (%d)\n", err); > > > > + goto out_sess; > > > > + } > > > > + > > > > + return 0; > > > > + > > > > +out_sess: > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > +out_ctx: > > > > + tee_client_close_context(ctx); > > > > + > > > > + return err; > > > > +} > > > > + > > > > +static void __exit mod_exit(void) > > > > +{ > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > + tee_client_close_context(ctx); > > > > + hwrng_unregister(&optee_rng); > > > > +} > > > > + > > > > +module_init(mod_init); > > > > +module_exit(mod_exit); > > > > + > > > > +MODULE_LICENSE("GPL"); > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > This is also an indicator that the API design needs some work. If the > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > device (which is what this driver should bind to) will only exist if > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > /firmware/optee node. > > > > > > > Agree. > > > > > > -- > > > > 2.7.4 > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-28 13:03 ` Sumit Garg @ 2018-12-28 14:46 ` Jens Wiklander 2018-12-30 14:59 ` Vesa Jääskeläinen 2018-12-31 10:24 ` Sumit Garg 0 siblings, 2 replies; 25+ messages in thread From: Jens Wiklander @ 2018-12-28 14:46 UTC (permalink / raw) To: Sumit Garg Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev Hi Sumit, On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Thanks Ard for your comments. > > > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > > might not be accessible to normal world (linux in this case) and rather > > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > > aims to provides a generic interface to OP-TEE based random number > > > > > generator service. > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > --- > > > > > MAINTAINERS | 5 + > > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > > drivers/char/hw_random/Makefile | 1 + > > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > > 4 files changed, 294 insertions(+) > > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > > > > Hi Sumit, > > > > > > > > I am having some trouble with this driver. Even though the firmware > > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > > > > I have added this to the DT: > > > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > @@ -583,6 +583,7 @@ > > compatible = "linaro,optee-tz"; > > method = "smc"; > > status = "disabled"; > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > }; > > }; > > }; > > > > It pretty strange as it could work well at my end. Can you please > build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > > > 1. early/pseudo TAs (resident). > > > 2. Dynamic TAs (loaded at runtime). > > > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > > TAs via tee-supplicant. It seems that its probably stuck in > > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > > for supplicant to fulfil the request. > > > > > > I think this should be resolved via TEE bus driver approach that I > > > have proposed in previous patch. > > > > > > > It would be useful if we could detect the absence of teesupplicant > > rather than wait indefinitely. Currenty, we cannot make the RNG driver > > a builtin due to this, so please add 'depends on m' as a dependency if > > we don't resolve this in the short term. > > > > By default this module is out of tree only (default m). > > Jens, > > Is there any particular reason to wait indefinitely in > "optee_supp_thrd_req" if there is no supplicant running? I think we > should probably return as follows from "optee_supp_thrd_req" API in > case no supplicant is available: > > --- a/drivers/tee/optee/supp.c > +++ b/drivers/tee/optee/supp.c > @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > u32 func, size_t num_params, > { > struct optee *optee = tee_get_drvdata(ctx->teedev); > struct optee_supp *supp = &optee->supp; > - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > + struct optee_supp_req *req; > bool interruptable; > u32 ret; > > + /* Return in case there is no supplicant available */ > + if (!supp->ctx) > + return TEEC_ERROR_COMMUNICATION; > + > + req = kzalloc(sizeof(*req), GFP_KERNEL); > if (!req) > return TEEC_ERROR_OUT_OF_MEMORY; >From a user space point of view it has been more useful to just wait until the supplicant starts to serve requests than polling the interface until the call succeeds. For this new use case it makes more sense to be able to return an error instead. The proposed change is a user space API change, so we will need to do a bit more than that. -Jens > > > > > Also, I have some concerns about the DT dependency (see my comment on > > > > the previous patch) > > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > > well as DT) as a platform device. I'd prefer it if we could do the > > > > same for this driver in one way or the other. > > > > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > > dependency. BTW, I will switch to platform device as it looks more > > > appropriate. > > > > > > > The bus driver approach only makes sense if we can enumerate the > > available TAs, rather than describe them via the DT or ACPI tables. > > > > But a child node with its own compatible string is an improvement in > > any case, and you can let the driver core instantiate the platform > > device for you. > > > > Ok then I will keep DT or ACPI child node. > > -Sumit > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > index 0767f1d..fe0fb74 100644 > > > > > --- a/MAINTAINERS > > > > > +++ b/MAINTAINERS > > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > > S: Maintained > > > > > F: drivers/tee/optee/ > > > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > > +S: Maintained > > > > > +F: drivers/char/hw_random/optee-rng.c > > > > > + > > > > > OPA-VNIC DRIVER > > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > > index dac895d..25a7d8f 100644 > > > > > --- a/drivers/char/hw_random/Kconfig > > > > > +++ b/drivers/char/hw_random/Kconfig > > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > > will be called exynos-trng. > > > > > > > > > > If unsure, say Y. > > > > > + > > > > > +config HW_RANDOM_OPTEE > > > > > + tristate "OP-TEE based Random Number Generator support" > > > > > + depends on OPTEE > > > > > + default HW_RANDOM > > > > > + help > > > > > + This driver provides support for OP-TEE based Random Number > > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > > + accessible to normal world (Linux). > > > > > + > > > > > + To compile this driver as a module, choose M here: the module > > > > > + will be called optee-rng. > > > > > + > > > > > + If unsure, say Y. > > > > > + > > > > > endif # HW_RANDOM > > > > > > > > > > config UML_RANDOM > > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > > index e35ec3c..7c9ef4a 100644 > > > > > --- a/drivers/char/hw_random/Makefile > > > > > +++ b/drivers/char/hw_random/Makefile > > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > > new file mode 100644 > > > > > index 0000000..8c63730 > > > > > --- /dev/null > > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > > @@ -0,0 +1,273 @@ > > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > > +/* > > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > > + */ > > > > > + > > > > > +#include <linux/delay.h> > > > > > +#include <linux/of.h> > > > > > +#include <linux/hw_random.h> > > > > > +#include <linux/kernel.h> > > > > > +#include <linux/module.h> > > > > > +#include <linux/tee_drv.h> > > > > > +#include <linux/uuid.h> > > > > > + > > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > > + > > > > > +/* > > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > > + * > > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > > + * param[1] unused > > > > > + * param[2] unused > > > > > + * param[3] unused > > > > > + * > > > > > + * Result: > > > > > + * TEE_SUCCESS - Invoke command success > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > > + */ > > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > > + > > > > > +/* > > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > > + * > > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > > + * param[1] unused > > > > > + * param[2] unused > > > > > + * param[3] unused > > > > > + * > > > > > + * Result: > > > > > + * TEE_SUCCESS - Invoke command success > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > + */ > > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > > + > > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > > + > > > > > +static struct tee_context *ctx; > > > > > +static struct tee_shm *entropy_shm_pool; > > > > > +static u32 ta_rng_data_rate; > > > > > +static u32 ta_rng_seesion_id; > > > > > > > > session not seesion > > > > > > > > > > Will fix. > > > > > > > > + > > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > > +{ > > > > > + u32 ret = 0; > > > > > + u8 *rng_data = NULL; > > > > > + size_t rng_size = 0; > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > + struct tee_param param[4] = {0}; > > > > > + > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > + inv_arg.num_params = 4; > > > > > + > > > > > + /* Fill invoke cmd params */ > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > > + param[0].u.memref.size = req_size; > > > > > + param[0].u.memref.shm_offs = 0; > > > > > + > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > > + inv_arg.ret); > > > > > + return 0; > > > > > + } > > > > > + > > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > > + if (IS_ERR(rng_data)) { > > > > > + pr_err("tee_shm_get_va failed\n"); > > > > > + return 0; > > > > > + } > > > > > + > > > > > + rng_size = param[0].u.memref.size; > > > > > + memcpy(buf, rng_data, rng_size); > > > > > + > > > > > + return rng_size; > > > > > +} > > > > > + > > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > > +{ > > > > > + u8 *data = buf; > > > > > + size_t read = 0, rng_size = 0; > > > > > + int timeout = 1; > > > > > + > > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > > + > > > > > + while (read == 0) { > > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > > + > > > > > + data += rng_size; > > > > > + read += rng_size; > > > > > + > > > > > + if (wait) { > > > > > + if (timeout-- == 0) > > > > > + return read; > > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > > + } else { > > > > > + return read; > > > > > + } > > > > > + } > > > > > + > > > > > + return read; > > > > > +} > > > > > + > > > > > +static int optee_rng_init(struct hwrng *rng) > > > > > +{ > > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > > + pr_err("tee_shm_alloc failed\n"); > > > > > + return PTR_ERR(entropy_shm_pool); > > > > > + } > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > > +{ > > > > > + tee_shm_free(entropy_shm_pool); > > > > > +} > > > > > + > > > > > +static struct hwrng optee_rng = { > > > > > + .name = "optee-rng", > > > > > + .init = optee_rng_init, > > > > > + .cleanup = optee_rng_cleanup, > > > > > + .read = optee_rng_read, > > > > > +}; > > > > > + > > > > > +static const struct of_device_id optee_match[] = { > > > > > + { .compatible = "linaro,optee-tz" }, > > > > > + {}, > > > > > +}; > > > > > + > > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > > +{ > > > > > + struct device_node *fw_np; > > > > > + struct device_node *np; > > > > > + const char *uuid; > > > > > + > > > > > + /* Node is supposed to be below /firmware */ > > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > > + if (!fw_np) > > > > > + return -ENODEV; > > > > > + > > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > > + if (!np || !of_device_is_available(np)) > > > > > + return -ENODEV; > > > > > + > > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > > + pr_warn("missing \"uuid\" property\n"); > > > > > + return -ENXIO; > > > > > + } > > > > > + > > > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > > + return -EINVAL; > > > > > + } > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static int get_optee_rng_info(void) > > > > > +{ > > > > > + u32 ret = 0; > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > + struct tee_param param[4] = {0}; > > > > > + > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > + inv_arg.num_params = 4; > > > > > + > > > > > + /* Fill invoke cmd params */ > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > > + > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > > + inv_arg.ret); > > > > > + return -EINVAL; > > > > > + } > > > > > + > > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > > + optee_rng.quality = param[0].u.value.b; > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > > +{ > > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > > + return 1; > > > > > + else > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static int __init mod_init(void) > > > > > +{ > > > > > + int ret = 0, err = -ENODEV; > > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > > + uuid_t ta_rng_uuid = {0}; > > > > > + > > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > > + if (err) > > > > > + return err; > > > > > + > > > > > + /* Open context with TEE driver */ > > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > > + if (IS_ERR(ctx)) > > > > > + return -ENODEV; > > > > > + > > > > > + /* Open session with hwrng Trusted App */ > > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > > + sess_arg.num_params = 0; > > > > > + > > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > > + sess_arg.ret); > > > > > + err = -EINVAL; > > > > > + goto out_ctx; > > > > > + } > > > > > + ta_rng_seesion_id = sess_arg.session; > > > > > + > > > > > + err = get_optee_rng_info(); > > > > > + if (err) > > > > > + goto out_sess; > > > > > + > > > > > + err = hwrng_register(&optee_rng); > > > > > + if (err) { > > > > > + pr_err("registering failed (%d)\n", err); > > > > > + goto out_sess; > > > > > + } > > > > > + > > > > > + return 0; > > > > > + > > > > > +out_sess: > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > +out_ctx: > > > > > + tee_client_close_context(ctx); > > > > > + > > > > > + return err; > > > > > +} > > > > > + > > > > > +static void __exit mod_exit(void) > > > > > +{ > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > + tee_client_close_context(ctx); > > > > > + hwrng_unregister(&optee_rng); > > > > > +} > > > > > + > > > > > +module_init(mod_init); > > > > > +module_exit(mod_exit); > > > > > + > > > > > +MODULE_LICENSE("GPL"); > > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > > > This is also an indicator that the API design needs some work. If the > > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > > device (which is what this driver should bind to) will only exist if > > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > > /firmware/optee node. > > > > > > > > > > Agree. > > > > > > > > -- > > > > > 2.7.4 > > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-28 14:46 ` Jens Wiklander @ 2018-12-30 14:59 ` Vesa Jääskeläinen 2018-12-31 10:35 ` Sumit Garg 2018-12-31 10:24 ` Sumit Garg 1 sibling, 1 reply; 25+ messages in thread From: Vesa Jääskeläinen @ 2018-12-30 14:59 UTC (permalink / raw) To: Jens Wiklander, Sumit Garg Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev Hi All, On 28/12/2018 16.46, Jens Wiklander wrote: > Hi Sumit, > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: >> On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: >> Jens, >> >> Is there any particular reason to wait indefinitely in >> "optee_supp_thrd_req" if there is no supplicant running? I think we >> should probably return as follows from "optee_supp_thrd_req" API in >> case no supplicant is available: >> >> --- a/drivers/tee/optee/supp.c >> +++ b/drivers/tee/optee/supp.c >> @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, >> u32 func, size_t num_params, >> { >> struct optee *optee = tee_get_drvdata(ctx->teedev); >> struct optee_supp *supp = &optee->supp; >> - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); >> + struct optee_supp_req *req; >> bool interruptable; >> u32 ret; >> >> + /* Return in case there is no supplicant available */ >> + if (!supp->ctx) >> + return TEEC_ERROR_COMMUNICATION; >> + >> + req = kzalloc(sizeof(*req), GFP_KERNEL); >> if (!req) >> return TEEC_ERROR_OUT_OF_MEMORY; > > From a user space point of view it has been more useful to just wait > until the supplicant starts to serve requests than polling the interface > until the call succeeds. For this new use case it makes more sense to be > able to return an error instead. > > The proposed change is a user space API change, so we will need to do a > bit more than that. There are parts of kernel that need randomness before user space is ready. Can't we move necessary logic for this to in kernel now that there is kernel service requiring TEE services? I suppose there are even more services that would be better to be only optee<->kernel interface and not exposed as such to user space. One example of such would be mass storage encryption key or hardware rooted encryption for Linux keyring. Eg. replacement for TPM chip when TEE environment is available. Thanks, Vesa Jääskeläinen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-30 14:59 ` Vesa Jääskeläinen @ 2018-12-31 10:35 ` Sumit Garg 0 siblings, 0 replies; 25+ messages in thread From: Sumit Garg @ 2018-12-31 10:35 UTC (permalink / raw) To: Vesa Jääskeläinen Cc: Jens Wiklander, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev On Sun, 30 Dec 2018 at 20:29, Vesa Jääskeläinen <dachaac@gmail.com> wrote: > > Hi All, > > On 28/12/2018 16.46, Jens Wiklander wrote: > > Hi Sumit, > > > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > >> On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > >> Jens, > >> > >> Is there any particular reason to wait indefinitely in > >> "optee_supp_thrd_req" if there is no supplicant running? I think we > >> should probably return as follows from "optee_supp_thrd_req" API in > >> case no supplicant is available: > >> > >> --- a/drivers/tee/optee/supp.c > >> +++ b/drivers/tee/optee/supp.c > >> @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > >> u32 func, size_t num_params, > >> { > >> struct optee *optee = tee_get_drvdata(ctx->teedev); > >> struct optee_supp *supp = &optee->supp; > >> - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > >> + struct optee_supp_req *req; > >> bool interruptable; > >> u32 ret; > >> > >> + /* Return in case there is no supplicant available */ > >> + if (!supp->ctx) > >> + return TEEC_ERROR_COMMUNICATION; > >> + > >> + req = kzalloc(sizeof(*req), GFP_KERNEL); > >> if (!req) > >> return TEEC_ERROR_OUT_OF_MEMORY; > > > > From a user space point of view it has been more useful to just wait > > until the supplicant starts to serve requests than polling the interface > > until the call succeeds. For this new use case it makes more sense to be > > able to return an error instead. > > > > The proposed change is a user space API change, so we will need to do a > > bit more than that. > > There are parts of kernel that need randomness before user space is ready. > > Can't we move necessary logic for this to in kernel now that there is > kernel service requiring TEE services? > Yes it is exactly what this optee-rng kernel module is trying to achieve. > I suppose there are even more services that would be better to be only > optee<->kernel interface and not exposed as such to user space. One > example of such would be mass storage encryption key or hardware rooted > encryption for Linux keyring. Eg. replacement for TPM chip when TEE > environment is available. > Agree, for such use-cases we are working on adding TEE bus support so that kernel drivers would be able to communicate with TEE based devices. -Sumit > Thanks, > Vesa Jääskeläinen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-28 14:46 ` Jens Wiklander 2018-12-30 14:59 ` Vesa Jääskeläinen @ 2018-12-31 10:24 ` Sumit Garg 2019-01-02 8:04 ` Jens Wiklander 1 sibling, 1 reply; 25+ messages in thread From: Sumit Garg @ 2018-12-31 10:24 UTC (permalink / raw) To: Jens Wiklander Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev On Fri, 28 Dec 2018 at 20:16, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > Hi Sumit, > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > > On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Thanks Ard for your comments. > > > > > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > > > might not be accessible to normal world (linux in this case) and rather > > > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > > > aims to provides a generic interface to OP-TEE based random number > > > > > > generator service. > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > --- > > > > > > MAINTAINERS | 5 + > > > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > > > drivers/char/hw_random/Makefile | 1 + > > > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > > > 4 files changed, 294 insertions(+) > > > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > > > > > > > Hi Sumit, > > > > > > > > > > I am having some trouble with this driver. Even though the firmware > > > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > > > > > > > I have added this to the DT: > > > > > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > @@ -583,6 +583,7 @@ > > > compatible = "linaro,optee-tz"; > > > method = "smc"; > > > status = "disabled"; > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > }; > > > }; > > > }; > > > > > > > It pretty strange as it could work well at my end. Can you please > > build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > > > > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > > > > > 1. early/pseudo TAs (resident). > > > > 2. Dynamic TAs (loaded at runtime). > > > > > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > > > TAs via tee-supplicant. It seems that its probably stuck in > > > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > > > for supplicant to fulfil the request. > > > > > > > > I think this should be resolved via TEE bus driver approach that I > > > > have proposed in previous patch. > > > > > > > > > > It would be useful if we could detect the absence of teesupplicant > > > rather than wait indefinitely. Currenty, we cannot make the RNG driver > > > a builtin due to this, so please add 'depends on m' as a dependency if > > > we don't resolve this in the short term. > > > > > > > By default this module is out of tree only (default m). > > > > Jens, > > > > Is there any particular reason to wait indefinitely in > > "optee_supp_thrd_req" if there is no supplicant running? I think we > > should probably return as follows from "optee_supp_thrd_req" API in > > case no supplicant is available: > > > > --- a/drivers/tee/optee/supp.c > > +++ b/drivers/tee/optee/supp.c > > @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > > u32 func, size_t num_params, > > { > > struct optee *optee = tee_get_drvdata(ctx->teedev); > > struct optee_supp *supp = &optee->supp; > > - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > > + struct optee_supp_req *req; > > bool interruptable; > > u32 ret; > > > > + /* Return in case there is no supplicant available */ > > + if (!supp->ctx) > > + return TEEC_ERROR_COMMUNICATION; > > + > > + req = kzalloc(sizeof(*req), GFP_KERNEL); > > if (!req) > > return TEEC_ERROR_OUT_OF_MEMORY; > > From a user space point of view it has been more useful to just wait > until the supplicant starts to serve requests than polling the interface > until the call succeeds. For this new use case it makes more sense to be > able to return an error instead. I don't see any case in user-space where user would launch client applications before tee-supplicant daemon. If it does so, to me it looks like error scenario only. Like in case of dynamic TA loading, user should be informed that TA is not found indicating that tee-supplicant might not be running. -Sumit > > The proposed change is a user space API change, so we will need to do a > bit more than that. > > -Jens > > > > > > > > Also, I have some concerns about the DT dependency (see my comment on > > > > > the previous patch) > > > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > > > well as DT) as a platform device. I'd prefer it if we could do the > > > > > same for this driver in one way or the other. > > > > > > > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > > > dependency. BTW, I will switch to platform device as it looks more > > > > appropriate. > > > > > > > > > > The bus driver approach only makes sense if we can enumerate the > > > available TAs, rather than describe them via the DT or ACPI tables. > > > > > > But a child node with its own compatible string is an improvement in > > > any case, and you can let the driver core instantiate the platform > > > device for you. > > > > > > > Ok then I will keep DT or ACPI child node. > > > > -Sumit > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > > index 0767f1d..fe0fb74 100644 > > > > > > --- a/MAINTAINERS > > > > > > +++ b/MAINTAINERS > > > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > > > S: Maintained > > > > > > F: drivers/tee/optee/ > > > > > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > > > +S: Maintained > > > > > > +F: drivers/char/hw_random/optee-rng.c > > > > > > + > > > > > > OPA-VNIC DRIVER > > > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > > > index dac895d..25a7d8f 100644 > > > > > > --- a/drivers/char/hw_random/Kconfig > > > > > > +++ b/drivers/char/hw_random/Kconfig > > > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > > > will be called exynos-trng. > > > > > > > > > > > > If unsure, say Y. > > > > > > + > > > > > > +config HW_RANDOM_OPTEE > > > > > > + tristate "OP-TEE based Random Number Generator support" > > > > > > + depends on OPTEE > > > > > > + default HW_RANDOM > > > > > > + help > > > > > > + This driver provides support for OP-TEE based Random Number > > > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > > > + accessible to normal world (Linux). > > > > > > + > > > > > > + To compile this driver as a module, choose M here: the module > > > > > > + will be called optee-rng. > > > > > > + > > > > > > + If unsure, say Y. > > > > > > + > > > > > > endif # HW_RANDOM > > > > > > > > > > > > config UML_RANDOM > > > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > > > index e35ec3c..7c9ef4a 100644 > > > > > > --- a/drivers/char/hw_random/Makefile > > > > > > +++ b/drivers/char/hw_random/Makefile > > > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > > > new file mode 100644 > > > > > > index 0000000..8c63730 > > > > > > --- /dev/null > > > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > > > @@ -0,0 +1,273 @@ > > > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > > > +/* > > > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > > > + */ > > > > > > + > > > > > > +#include <linux/delay.h> > > > > > > +#include <linux/of.h> > > > > > > +#include <linux/hw_random.h> > > > > > > +#include <linux/kernel.h> > > > > > > +#include <linux/module.h> > > > > > > +#include <linux/tee_drv.h> > > > > > > +#include <linux/uuid.h> > > > > > > + > > > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > > > + > > > > > > +/* > > > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > > > + * > > > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > > > + * param[1] unused > > > > > > + * param[2] unused > > > > > > + * param[3] unused > > > > > > + * > > > > > > + * Result: > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > > > + */ > > > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > > > + > > > > > > +/* > > > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > > > + * > > > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > > > + * param[1] unused > > > > > > + * param[2] unused > > > > > > + * param[3] unused > > > > > > + * > > > > > > + * Result: > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > + */ > > > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > > > + > > > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > > > + > > > > > > +static struct tee_context *ctx; > > > > > > +static struct tee_shm *entropy_shm_pool; > > > > > > +static u32 ta_rng_data_rate; > > > > > > +static u32 ta_rng_seesion_id; > > > > > > > > > > session not seesion > > > > > > > > > > > > > Will fix. > > > > > > > > > > + > > > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > > > +{ > > > > > > + u32 ret = 0; > > > > > > + u8 *rng_data = NULL; > > > > > > + size_t rng_size = 0; > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > + struct tee_param param[4] = {0}; > > > > > > + > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > + inv_arg.num_params = 4; > > > > > > + > > > > > > + /* Fill invoke cmd params */ > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > > > + param[0].u.memref.size = req_size; > > > > > > + param[0].u.memref.shm_offs = 0; > > > > > > + > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > > > + inv_arg.ret); > > > > > > + return 0; > > > > > > + } > > > > > > + > > > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > > > + if (IS_ERR(rng_data)) { > > > > > > + pr_err("tee_shm_get_va failed\n"); > > > > > > + return 0; > > > > > > + } > > > > > > + > > > > > > + rng_size = param[0].u.memref.size; > > > > > > + memcpy(buf, rng_data, rng_size); > > > > > > + > > > > > > + return rng_size; > > > > > > +} > > > > > > + > > > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > > > +{ > > > > > > + u8 *data = buf; > > > > > > + size_t read = 0, rng_size = 0; > > > > > > + int timeout = 1; > > > > > > + > > > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > > > + > > > > > > + while (read == 0) { > > > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > > > + > > > > > > + data += rng_size; > > > > > > + read += rng_size; > > > > > > + > > > > > > + if (wait) { > > > > > > + if (timeout-- == 0) > > > > > > + return read; > > > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > > > + } else { > > > > > > + return read; > > > > > > + } > > > > > > + } > > > > > > + > > > > > > + return read; > > > > > > +} > > > > > > + > > > > > > +static int optee_rng_init(struct hwrng *rng) > > > > > > +{ > > > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > > > + pr_err("tee_shm_alloc failed\n"); > > > > > > + return PTR_ERR(entropy_shm_pool); > > > > > > + } > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > > > +{ > > > > > > + tee_shm_free(entropy_shm_pool); > > > > > > +} > > > > > > + > > > > > > +static struct hwrng optee_rng = { > > > > > > + .name = "optee-rng", > > > > > > + .init = optee_rng_init, > > > > > > + .cleanup = optee_rng_cleanup, > > > > > > + .read = optee_rng_read, > > > > > > +}; > > > > > > + > > > > > > +static const struct of_device_id optee_match[] = { > > > > > > + { .compatible = "linaro,optee-tz" }, > > > > > > + {}, > > > > > > +}; > > > > > > + > > > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > > > +{ > > > > > > + struct device_node *fw_np; > > > > > > + struct device_node *np; > > > > > > + const char *uuid; > > > > > > + > > > > > > + /* Node is supposed to be below /firmware */ > > > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > > > + if (!fw_np) > > > > > > + return -ENODEV; > > > > > > + > > > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > > > + if (!np || !of_device_is_available(np)) > > > > > > + return -ENODEV; > > > > > > + > > > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > > > + pr_warn("missing \"uuid\" property\n"); > > > > > > + return -ENXIO; > > > > > > + } > > > > > > + > > > > > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > > > + return -EINVAL; > > > > > > + } > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static int get_optee_rng_info(void) > > > > > > +{ > > > > > > + u32 ret = 0; > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > + struct tee_param param[4] = {0}; > > > > > > + > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > + inv_arg.num_params = 4; > > > > > > + > > > > > > + /* Fill invoke cmd params */ > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > > > + > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > > > + inv_arg.ret); > > > > > > + return -EINVAL; > > > > > > + } > > > > > > + > > > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > > > + optee_rng.quality = param[0].u.value.b; > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > > > +{ > > > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > > > + return 1; > > > > > > + else > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static int __init mod_init(void) > > > > > > +{ > > > > > > + int ret = 0, err = -ENODEV; > > > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > > > + uuid_t ta_rng_uuid = {0}; > > > > > > + > > > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > > > + if (err) > > > > > > + return err; > > > > > > + > > > > > > + /* Open context with TEE driver */ > > > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > > > + if (IS_ERR(ctx)) > > > > > > + return -ENODEV; > > > > > > + > > > > > > + /* Open session with hwrng Trusted App */ > > > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > > > + sess_arg.num_params = 0; > > > > > > + > > > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > > > + sess_arg.ret); > > > > > > + err = -EINVAL; > > > > > > + goto out_ctx; > > > > > > + } > > > > > > + ta_rng_seesion_id = sess_arg.session; > > > > > > + > > > > > > + err = get_optee_rng_info(); > > > > > > + if (err) > > > > > > + goto out_sess; > > > > > > + > > > > > > + err = hwrng_register(&optee_rng); > > > > > > + if (err) { > > > > > > + pr_err("registering failed (%d)\n", err); > > > > > > + goto out_sess; > > > > > > + } > > > > > > + > > > > > > + return 0; > > > > > > + > > > > > > +out_sess: > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > +out_ctx: > > > > > > + tee_client_close_context(ctx); > > > > > > + > > > > > > + return err; > > > > > > +} > > > > > > + > > > > > > +static void __exit mod_exit(void) > > > > > > +{ > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > + tee_client_close_context(ctx); > > > > > > + hwrng_unregister(&optee_rng); > > > > > > +} > > > > > > + > > > > > > +module_init(mod_init); > > > > > > +module_exit(mod_exit); > > > > > > + > > > > > > +MODULE_LICENSE("GPL"); > > > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > > > > > This is also an indicator that the API design needs some work. If the > > > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > > > device (which is what this driver should bind to) will only exist if > > > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > > > /firmware/optee node. > > > > > > > > > > > > > Agree. > > > > > > > > > > -- > > > > > > 2.7.4 > > > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2018-12-31 10:24 ` Sumit Garg @ 2019-01-02 8:04 ` Jens Wiklander 2019-01-02 8:26 ` Bhupesh Sharma 2019-01-02 10:12 ` Sumit Garg 0 siblings, 2 replies; 25+ messages in thread From: Jens Wiklander @ 2019-01-02 8:04 UTC (permalink / raw) To: Sumit Garg Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev On Mon, Dec 31, 2018 at 11:24 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > On Fri, 28 Dec 2018 at 20:16, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > Hi Sumit, > > > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > > > On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Thanks Ard for your comments. > > > > > > > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > > > > might not be accessible to normal world (linux in this case) and rather > > > > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > > > > aims to provides a generic interface to OP-TEE based random number > > > > > > > generator service. > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > --- > > > > > > > MAINTAINERS | 5 + > > > > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > > > > drivers/char/hw_random/Makefile | 1 + > > > > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > > > > 4 files changed, 294 insertions(+) > > > > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > > > > > > > > > > Hi Sumit, > > > > > > > > > > > > I am having some trouble with this driver. Even though the firmware > > > > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > > > > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > > > > > > > > > > I have added this to the DT: > > > > > > > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > @@ -583,6 +583,7 @@ > > > > compatible = "linaro,optee-tz"; > > > > method = "smc"; > > > > status = "disabled"; > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > }; > > > > }; > > > > }; > > > > > > > > > > It pretty strange as it could work well at my end. Can you please > > > build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > > > > > > > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > > > > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > > > > > > > 1. early/pseudo TAs (resident). > > > > > 2. Dynamic TAs (loaded at runtime). > > > > > > > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > > > > TAs via tee-supplicant. It seems that its probably stuck in > > > > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > > > > for supplicant to fulfil the request. > > > > > > > > > > I think this should be resolved via TEE bus driver approach that I > > > > > have proposed in previous patch. > > > > > > > > > > > > > It would be useful if we could detect the absence of teesupplicant > > > > rather than wait indefinitely. Currenty, we cannot make the RNG driver > > > > a builtin due to this, so please add 'depends on m' as a dependency if > > > > we don't resolve this in the short term. > > > > > > > > > > By default this module is out of tree only (default m). > > > > > > Jens, > > > > > > Is there any particular reason to wait indefinitely in > > > "optee_supp_thrd_req" if there is no supplicant running? I think we > > > should probably return as follows from "optee_supp_thrd_req" API in > > > case no supplicant is available: > > > > > > --- a/drivers/tee/optee/supp.c > > > +++ b/drivers/tee/optee/supp.c > > > @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > > > u32 func, size_t num_params, > > > { > > > struct optee *optee = tee_get_drvdata(ctx->teedev); > > > struct optee_supp *supp = &optee->supp; > > > - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > > > + struct optee_supp_req *req; > > > bool interruptable; > > > u32 ret; > > > > > > + /* Return in case there is no supplicant available */ > > > + if (!supp->ctx) > > > + return TEEC_ERROR_COMMUNICATION; > > > + > > > + req = kzalloc(sizeof(*req), GFP_KERNEL); > > > if (!req) > > > return TEEC_ERROR_OUT_OF_MEMORY; > > > > From a user space point of view it has been more useful to just wait > > until the supplicant starts to serve requests than polling the interface > > until the call succeeds. For this new use case it makes more sense to be > > able to return an error instead. > > I don't see any case in user-space where user would launch client > applications before tee-supplicant daemon. If it does so, to me it > looks like error scenario only. Like in case of dynamic TA loading, > user should be informed that TA is not found indicating that > tee-supplicant might not be running. It takes a little while after the tee-supplicant daemon has been started until it has registered itself as a tee-supplicant. That window has to be closed in some way and that's what we've done with the current design. As I said in my previous mail, we need a way for the caller to tell if it should be blocked or get an error if tee-supplicant isn't available. This has to be done by extending the API instead of making incompatible changes of it. It is tempting to add a flag to struct tee_context (caller specific struct) which would indicate if tee-supplicant communication is allowed or not. However, it's a bit ugly and also I'm not sure it will cover all cases we'll need. -Jens > > -Sumit > > > > > The proposed change is a user space API change, so we will need to do a > > bit more than that. > > > > -Jens > > > > > > > > > > > Also, I have some concerns about the DT dependency (see my comment on > > > > > > the previous patch) > > > > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > > > > well as DT) as a platform device. I'd prefer it if we could do the > > > > > > same for this driver in one way or the other. > > > > > > > > > > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > > > > dependency. BTW, I will switch to platform device as it looks more > > > > > appropriate. > > > > > > > > > > > > > The bus driver approach only makes sense if we can enumerate the > > > > available TAs, rather than describe them via the DT or ACPI tables. > > > > > > > > But a child node with its own compatible string is an improvement in > > > > any case, and you can let the driver core instantiate the platform > > > > device for you. > > > > > > > > > > Ok then I will keep DT or ACPI child node. > > > > > > -Sumit > > > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > > > index 0767f1d..fe0fb74 100644 > > > > > > > --- a/MAINTAINERS > > > > > > > +++ b/MAINTAINERS > > > > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > > > > S: Maintained > > > > > > > F: drivers/tee/optee/ > > > > > > > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > > > > +S: Maintained > > > > > > > +F: drivers/char/hw_random/optee-rng.c > > > > > > > + > > > > > > > OPA-VNIC DRIVER > > > > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > > > > index dac895d..25a7d8f 100644 > > > > > > > --- a/drivers/char/hw_random/Kconfig > > > > > > > +++ b/drivers/char/hw_random/Kconfig > > > > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > > > > will be called exynos-trng. > > > > > > > > > > > > > > If unsure, say Y. > > > > > > > + > > > > > > > +config HW_RANDOM_OPTEE > > > > > > > + tristate "OP-TEE based Random Number Generator support" > > > > > > > + depends on OPTEE > > > > > > > + default HW_RANDOM > > > > > > > + help > > > > > > > + This driver provides support for OP-TEE based Random Number > > > > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > > > > + accessible to normal world (Linux). > > > > > > > + > > > > > > > + To compile this driver as a module, choose M here: the module > > > > > > > + will be called optee-rng. > > > > > > > + > > > > > > > + If unsure, say Y. > > > > > > > + > > > > > > > endif # HW_RANDOM > > > > > > > > > > > > > > config UML_RANDOM > > > > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > > > > index e35ec3c..7c9ef4a 100644 > > > > > > > --- a/drivers/char/hw_random/Makefile > > > > > > > +++ b/drivers/char/hw_random/Makefile > > > > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > > > > new file mode 100644 > > > > > > > index 0000000..8c63730 > > > > > > > --- /dev/null > > > > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > > > > @@ -0,0 +1,273 @@ > > > > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > > > > +/* > > > > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > > > > + */ > > > > > > > + > > > > > > > +#include <linux/delay.h> > > > > > > > +#include <linux/of.h> > > > > > > > +#include <linux/hw_random.h> > > > > > > > +#include <linux/kernel.h> > > > > > > > +#include <linux/module.h> > > > > > > > +#include <linux/tee_drv.h> > > > > > > > +#include <linux/uuid.h> > > > > > > > + > > > > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > > > > + > > > > > > > +/* > > > > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > > > > + * > > > > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > > > > + * param[1] unused > > > > > > > + * param[2] unused > > > > > > > + * param[3] unused > > > > > > > + * > > > > > > > + * Result: > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > > > > + */ > > > > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > > > > + > > > > > > > +/* > > > > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > > > > + * > > > > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > > > > + * param[1] unused > > > > > > > + * param[2] unused > > > > > > > + * param[3] unused > > > > > > > + * > > > > > > > + * Result: > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > + */ > > > > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > > > > + > > > > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > > > > + > > > > > > > +static struct tee_context *ctx; > > > > > > > +static struct tee_shm *entropy_shm_pool; > > > > > > > +static u32 ta_rng_data_rate; > > > > > > > +static u32 ta_rng_seesion_id; > > > > > > > > > > > > session not seesion > > > > > > > > > > > > > > > > Will fix. > > > > > > > > > > > > + > > > > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > > > > +{ > > > > > > > + u32 ret = 0; > > > > > > > + u8 *rng_data = NULL; > > > > > > > + size_t rng_size = 0; > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > + > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > + inv_arg.num_params = 4; > > > > > > > + > > > > > > > + /* Fill invoke cmd params */ > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > > > > + param[0].u.memref.size = req_size; > > > > > > > + param[0].u.memref.shm_offs = 0; > > > > > > > + > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > > > > + inv_arg.ret); > > > > > > > + return 0; > > > > > > > + } > > > > > > > + > > > > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > > > > + if (IS_ERR(rng_data)) { > > > > > > > + pr_err("tee_shm_get_va failed\n"); > > > > > > > + return 0; > > > > > > > + } > > > > > > > + > > > > > > > + rng_size = param[0].u.memref.size; > > > > > > > + memcpy(buf, rng_data, rng_size); > > > > > > > + > > > > > > > + return rng_size; > > > > > > > +} > > > > > > > + > > > > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > > > > +{ > > > > > > > + u8 *data = buf; > > > > > > > + size_t read = 0, rng_size = 0; > > > > > > > + int timeout = 1; > > > > > > > + > > > > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > > > > + > > > > > > > + while (read == 0) { > > > > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > > > > + > > > > > > > + data += rng_size; > > > > > > > + read += rng_size; > > > > > > > + > > > > > > > + if (wait) { > > > > > > > + if (timeout-- == 0) > > > > > > > + return read; > > > > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > > > > + } else { > > > > > > > + return read; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + return read; > > > > > > > +} > > > > > > > + > > > > > > > +static int optee_rng_init(struct hwrng *rng) > > > > > > > +{ > > > > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > > > > + pr_err("tee_shm_alloc failed\n"); > > > > > > > + return PTR_ERR(entropy_shm_pool); > > > > > > > + } > > > > > > > + > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > > > > +{ > > > > > > > + tee_shm_free(entropy_shm_pool); > > > > > > > +} > > > > > > > + > > > > > > > +static struct hwrng optee_rng = { > > > > > > > + .name = "optee-rng", > > > > > > > + .init = optee_rng_init, > > > > > > > + .cleanup = optee_rng_cleanup, > > > > > > > + .read = optee_rng_read, > > > > > > > +}; > > > > > > > + > > > > > > > +static const struct of_device_id optee_match[] = { > > > > > > > + { .compatible = "linaro,optee-tz" }, > > > > > > > + {}, > > > > > > > +}; > > > > > > > + > > > > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > > > > +{ > > > > > > > + struct device_node *fw_np; > > > > > > > + struct device_node *np; > > > > > > > + const char *uuid; > > > > > > > + > > > > > > > + /* Node is supposed to be below /firmware */ > > > > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > > > > + if (!fw_np) > > > > > > > + return -ENODEV; > > > > > > > + > > > > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > > > > + if (!np || !of_device_is_available(np)) > > > > > > > + return -ENODEV; > > > > > > > + > > > > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > > > > + pr_warn("missing \"uuid\" property\n"); > > > > > > > + return -ENXIO; > > > > > > > + } > > > > > > > + > > > > > > > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > > > > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > > > > + return -EINVAL; > > > > > > > + } > > > > > > > + > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +static int get_optee_rng_info(void) > > > > > > > +{ > > > > > > > + u32 ret = 0; > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > + > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > + inv_arg.num_params = 4; > > > > > > > + > > > > > > > + /* Fill invoke cmd params */ > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > > > > + > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > > > > + inv_arg.ret); > > > > > > > + return -EINVAL; > > > > > > > + } > > > > > > > + > > > > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > > > > + optee_rng.quality = param[0].u.value.b; > > > > > > > + > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > > > > +{ > > > > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > > > > + return 1; > > > > > > > + else > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +static int __init mod_init(void) > > > > > > > +{ > > > > > > > + int ret = 0, err = -ENODEV; > > > > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > > > > + uuid_t ta_rng_uuid = {0}; > > > > > > > + > > > > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > > > > + if (err) > > > > > > > + return err; > > > > > > > + > > > > > > > + /* Open context with TEE driver */ > > > > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > > > > + if (IS_ERR(ctx)) > > > > > > > + return -ENODEV; > > > > > > > + > > > > > > > + /* Open session with hwrng Trusted App */ > > > > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > > > > + sess_arg.num_params = 0; > > > > > > > + > > > > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > > > > + sess_arg.ret); > > > > > > > + err = -EINVAL; > > > > > > > + goto out_ctx; > > > > > > > + } > > > > > > > + ta_rng_seesion_id = sess_arg.session; > > > > > > > + > > > > > > > + err = get_optee_rng_info(); > > > > > > > + if (err) > > > > > > > + goto out_sess; > > > > > > > + > > > > > > > + err = hwrng_register(&optee_rng); > > > > > > > + if (err) { > > > > > > > + pr_err("registering failed (%d)\n", err); > > > > > > > + goto out_sess; > > > > > > > + } > > > > > > > + > > > > > > > + return 0; > > > > > > > + > > > > > > > +out_sess: > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > +out_ctx: > > > > > > > + tee_client_close_context(ctx); > > > > > > > + > > > > > > > + return err; > > > > > > > +} > > > > > > > + > > > > > > > +static void __exit mod_exit(void) > > > > > > > +{ > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > + tee_client_close_context(ctx); > > > > > > > + hwrng_unregister(&optee_rng); > > > > > > > +} > > > > > > > + > > > > > > > +module_init(mod_init); > > > > > > > +module_exit(mod_exit); > > > > > > > + > > > > > > > +MODULE_LICENSE("GPL"); > > > > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > > > > > > > This is also an indicator that the API design needs some work. If the > > > > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > > > > device (which is what this driver should bind to) will only exist if > > > > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > > > > /firmware/optee node. > > > > > > > > > > > > > > > > Agree. > > > > > > > > > > > > -- > > > > > > > 2.7.4 > > > > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2019-01-02 8:04 ` Jens Wiklander @ 2019-01-02 8:26 ` Bhupesh Sharma 2019-01-02 10:12 ` Sumit Garg 1 sibling, 0 replies; 25+ messages in thread From: Bhupesh Sharma @ 2019-01-02 8:26 UTC (permalink / raw) To: Jens Wiklander Cc: Sumit Garg, Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, tee-dev Hi Sumit, Jens, On Wed, Jan 2, 2019 at 1:34 PM Jens Wiklander <jens.wiklander@linaro.org> wrote: > > On Mon, Dec 31, 2018 at 11:24 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Fri, 28 Dec 2018 at 20:16, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > Hi Sumit, > > > > > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > > > > On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Thanks Ard for your comments. > > > > > > > > > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > > > > > might not be accessible to normal world (linux in this case) and rather > > > > > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > > > > > aims to provides a generic interface to OP-TEE based random number > > > > > > > > generator service. > > > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > --- > > > > > > > > MAINTAINERS | 5 + > > > > > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > > > > > drivers/char/hw_random/Makefile | 1 + > > > > > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > > > > > 4 files changed, 294 insertions(+) > > > > > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > > > > > > > > > > > > > Hi Sumit, > > > > > > > > > > > > > > I am having some trouble with this driver. Even though the firmware > > > > > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > > > > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > > > > > > > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > > > > > > > > > > > > > I have added this to the DT: > > > > > > > > > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > > @@ -583,6 +583,7 @@ > > > > > compatible = "linaro,optee-tz"; > > > > > method = "smc"; > > > > > status = "disabled"; > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > }; > > > > > }; > > > > > }; > > > > > > > > > > > > > It pretty strange as it could work well at my end. Can you please > > > > build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > > > > > > > > > > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > > > > > > > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > > > > > > > > > 1. early/pseudo TAs (resident). > > > > > > 2. Dynamic TAs (loaded at runtime). > > > > > > > > > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > > > > > TAs via tee-supplicant. It seems that its probably stuck in > > > > > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > > > > > for supplicant to fulfil the request. > > > > > > > > > > > > I think this should be resolved via TEE bus driver approach that I > > > > > > have proposed in previous patch. > > > > > > > > > > > > > > > > It would be useful if we could detect the absence of teesupplicant > > > > > rather than wait indefinitely. Currenty, we cannot make the RNG driver > > > > > a builtin due to this, so please add 'depends on m' as a dependency if > > > > > we don't resolve this in the short term. > > > > > > > > > > > > > By default this module is out of tree only (default m). > > > > > > > > Jens, > > > > > > > > Is there any particular reason to wait indefinitely in > > > > "optee_supp_thrd_req" if there is no supplicant running? I think we > > > > should probably return as follows from "optee_supp_thrd_req" API in > > > > case no supplicant is available: > > > > > > > > --- a/drivers/tee/optee/supp.c > > > > +++ b/drivers/tee/optee/supp.c > > > > @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > > > > u32 func, size_t num_params, > > > > { > > > > struct optee *optee = tee_get_drvdata(ctx->teedev); > > > > struct optee_supp *supp = &optee->supp; > > > > - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > > > > + struct optee_supp_req *req; > > > > bool interruptable; > > > > u32 ret; > > > > > > > > + /* Return in case there is no supplicant available */ > > > > + if (!supp->ctx) > > > > + return TEEC_ERROR_COMMUNICATION; > > > > + > > > > + req = kzalloc(sizeof(*req), GFP_KERNEL); > > > > if (!req) > > > > return TEEC_ERROR_OUT_OF_MEMORY; > > > > > > From a user space point of view it has been more useful to just wait > > > until the supplicant starts to serve requests than polling the interface > > > until the call succeeds. For this new use case it makes more sense to be > > > able to return an error instead. > > > > I don't see any case in user-space where user would launch client > > applications before tee-supplicant daemon. If it does so, to me it > > looks like error scenario only. Like in case of dynamic TA loading, > > user should be informed that TA is not found indicating that > > tee-supplicant might not be running. > > It takes a little while after the tee-supplicant daemon has been > started until it has registered itself as a tee-supplicant. That > window has to be closed in some way and that's what we've done with > the current design. > > As I said in my previous mail, we need a way for the caller to tell if > it should be blocked or get an error if tee-supplicant isn't > available. This has to be done by extending the API instead of making > incompatible changes of it. > > It is tempting to add a flag to struct tee_context (caller specific > struct) which would indicate if tee-supplicant communication is > allowed or not. +1 . Adding a flag to specify a NONBLOCK'ing (call from the caller) [similar to the getrandom() user space call - see <http://man7.org/linux/man-pages/man2/getrandom.2.html> for details), would be helpful - specially when we look to integrate these user-space TEE applications with a 'systemd' like framework so that they can be launched appropriately (in the right order) while loading the initramfs. Regards, Bhupesh > However, it's a bit ugly and also I'm not sure it will > cover all cases we'll need. > > -Jens > > > > > -Sumit > > > > > > > > The proposed change is a user space API change, so we will need to do a > > > bit more than that. > > > > > > -Jens > > > > > > > > > > > > > > Also, I have some concerns about the DT dependency (see my comment on > > > > > > > the previous patch) > > > > > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > > > > > well as DT) as a platform device. I'd prefer it if we could do the > > > > > > > same for this driver in one way or the other. > > > > > > > > > > > > > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > > > > > dependency. BTW, I will switch to platform device as it looks more > > > > > > appropriate. > > > > > > > > > > > > > > > > The bus driver approach only makes sense if we can enumerate the > > > > > available TAs, rather than describe them via the DT or ACPI tables. > > > > > > > > > > But a child node with its own compatible string is an improvement in > > > > > any case, and you can let the driver core instantiate the platform > > > > > device for you. > > > > > > > > > > > > > Ok then I will keep DT or ACPI child node. > > > > > > > > -Sumit > > > > > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > > > > index 0767f1d..fe0fb74 100644 > > > > > > > > --- a/MAINTAINERS > > > > > > > > +++ b/MAINTAINERS > > > > > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > > > > > S: Maintained > > > > > > > > F: drivers/tee/optee/ > > > > > > > > > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > +S: Maintained > > > > > > > > +F: drivers/char/hw_random/optee-rng.c > > > > > > > > + > > > > > > > > OPA-VNIC DRIVER > > > > > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > > > > > index dac895d..25a7d8f 100644 > > > > > > > > --- a/drivers/char/hw_random/Kconfig > > > > > > > > +++ b/drivers/char/hw_random/Kconfig > > > > > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > > > > > will be called exynos-trng. > > > > > > > > > > > > > > > > If unsure, say Y. > > > > > > > > + > > > > > > > > +config HW_RANDOM_OPTEE > > > > > > > > + tristate "OP-TEE based Random Number Generator support" > > > > > > > > + depends on OPTEE > > > > > > > > + default HW_RANDOM > > > > > > > > + help > > > > > > > > + This driver provides support for OP-TEE based Random Number > > > > > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > > > > > + accessible to normal world (Linux). > > > > > > > > + > > > > > > > > + To compile this driver as a module, choose M here: the module > > > > > > > > + will be called optee-rng. > > > > > > > > + > > > > > > > > + If unsure, say Y. > > > > > > > > + > > > > > > > > endif # HW_RANDOM > > > > > > > > > > > > > > > > config UML_RANDOM > > > > > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > > > > > index e35ec3c..7c9ef4a 100644 > > > > > > > > --- a/drivers/char/hw_random/Makefile > > > > > > > > +++ b/drivers/char/hw_random/Makefile > > > > > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > > > > > new file mode 100644 > > > > > > > > index 0000000..8c63730 > > > > > > > > --- /dev/null > > > > > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > > > > > @@ -0,0 +1,273 @@ > > > > > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > > > > > +/* > > > > > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > > > > > + */ > > > > > > > > + > > > > > > > > +#include <linux/delay.h> > > > > > > > > +#include <linux/of.h> > > > > > > > > +#include <linux/hw_random.h> > > > > > > > > +#include <linux/kernel.h> > > > > > > > > +#include <linux/module.h> > > > > > > > > +#include <linux/tee_drv.h> > > > > > > > > +#include <linux/uuid.h> > > > > > > > > + > > > > > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > > > > > + > > > > > > > > +/* > > > > > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > > > > > + * > > > > > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > > > > > + * param[1] unused > > > > > > > > + * param[2] unused > > > > > > > > + * param[3] unused > > > > > > > > + * > > > > > > > > + * Result: > > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > > > > > + */ > > > > > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > > > > > + > > > > > > > > +/* > > > > > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > > > > > + * > > > > > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > > > > > + * param[1] unused > > > > > > > > + * param[2] unused > > > > > > > > + * param[3] unused > > > > > > > > + * > > > > > > > > + * Result: > > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > > + */ > > > > > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > > > > > + > > > > > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > > > > > + > > > > > > > > +static struct tee_context *ctx; > > > > > > > > +static struct tee_shm *entropy_shm_pool; > > > > > > > > +static u32 ta_rng_data_rate; > > > > > > > > +static u32 ta_rng_seesion_id; > > > > > > > > > > > > > > session not seesion > > > > > > > > > > > > > > > > > > > Will fix. > > > > > > > > > > > > > > + > > > > > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > > > > > +{ > > > > > > > > + u32 ret = 0; > > > > > > > > + u8 *rng_data = NULL; > > > > > > > > + size_t rng_size = 0; > > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > > + > > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > > + inv_arg.num_params = 4; > > > > > > > > + > > > > > > > > + /* Fill invoke cmd params */ > > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > > > > > + param[0].u.memref.size = req_size; > > > > > > > > + param[0].u.memref.shm_offs = 0; > > > > > > > > + > > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > > > > > + inv_arg.ret); > > > > > > > > + return 0; > > > > > > > > + } > > > > > > > > + > > > > > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > > > > > + if (IS_ERR(rng_data)) { > > > > > > > > + pr_err("tee_shm_get_va failed\n"); > > > > > > > > + return 0; > > > > > > > > + } > > > > > > > > + > > > > > > > > + rng_size = param[0].u.memref.size; > > > > > > > > + memcpy(buf, rng_data, rng_size); > > > > > > > > + > > > > > > > > + return rng_size; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > > > > > +{ > > > > > > > > + u8 *data = buf; > > > > > > > > + size_t read = 0, rng_size = 0; > > > > > > > > + int timeout = 1; > > > > > > > > + > > > > > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > > > > > + > > > > > > > > + while (read == 0) { > > > > > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > > > > > + > > > > > > > > + data += rng_size; > > > > > > > > + read += rng_size; > > > > > > > > + > > > > > > > > + if (wait) { > > > > > > > > + if (timeout-- == 0) > > > > > > > > + return read; > > > > > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > > > > > + } else { > > > > > > > > + return read; > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > + return read; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_rng_init(struct hwrng *rng) > > > > > > > > +{ > > > > > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > > > > > + pr_err("tee_shm_alloc failed\n"); > > > > > > > > + return PTR_ERR(entropy_shm_pool); > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > > > > > +{ > > > > > > > > + tee_shm_free(entropy_shm_pool); > > > > > > > > +} > > > > > > > > + > > > > > > > > +static struct hwrng optee_rng = { > > > > > > > > + .name = "optee-rng", > > > > > > > > + .init = optee_rng_init, > > > > > > > > + .cleanup = optee_rng_cleanup, > > > > > > > > + .read = optee_rng_read, > > > > > > > > +}; > > > > > > > > + > > > > > > > > +static const struct of_device_id optee_match[] = { > > > > > > > > + { .compatible = "linaro,optee-tz" }, > > > > > > > > + {}, > > > > > > > > +}; > > > > > > > > + > > > > > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > > > > > +{ > > > > > > > > + struct device_node *fw_np; > > > > > > > > + struct device_node *np; > > > > > > > > + const char *uuid; > > > > > > > > + > > > > > > > > + /* Node is supposed to be below /firmware */ > > > > > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > > > > > + if (!fw_np) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > > > > > + if (!np || !of_device_is_available(np)) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > > > > > + pr_warn("missing \"uuid\" property\n"); > > > > > > > > + return -ENXIO; > > > > > > > > + } > > > > > > > > + > > > > > > > > > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > > > > > > > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > > > > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > > > > > + return -EINVAL; > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int get_optee_rng_info(void) > > > > > > > > +{ > > > > > > > > + u32 ret = 0; > > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > > + > > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > > + inv_arg.num_params = 4; > > > > > > > > + > > > > > > > > + /* Fill invoke cmd params */ > > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > > > > > + > > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > > > > > + inv_arg.ret); > > > > > > > > + return -EINVAL; > > > > > > > > + } > > > > > > > > + > > > > > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > > > > > + optee_rng.quality = param[0].u.value.b; > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > > > > > +{ > > > > > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > > > > > + return 1; > > > > > > > > + else > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int __init mod_init(void) > > > > > > > > +{ > > > > > > > > + int ret = 0, err = -ENODEV; > > > > > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > > > > > + uuid_t ta_rng_uuid = {0}; > > > > > > > > + > > > > > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > > > > > + if (err) > > > > > > > > + return err; > > > > > > > > + > > > > > > > > + /* Open context with TEE driver */ > > > > > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > > > > > + if (IS_ERR(ctx)) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + /* Open session with hwrng Trusted App */ > > > > > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > > > > > + sess_arg.num_params = 0; > > > > > > > > + > > > > > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > > > > > + sess_arg.ret); > > > > > > > > + err = -EINVAL; > > > > > > > > + goto out_ctx; > > > > > > > > + } > > > > > > > > + ta_rng_seesion_id = sess_arg.session; > > > > > > > > + > > > > > > > > + err = get_optee_rng_info(); > > > > > > > > + if (err) > > > > > > > > + goto out_sess; > > > > > > > > + > > > > > > > > + err = hwrng_register(&optee_rng); > > > > > > > > + if (err) { > > > > > > > > + pr_err("registering failed (%d)\n", err); > > > > > > > > + goto out_sess; > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > + > > > > > > > > +out_sess: > > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > > +out_ctx: > > > > > > > > + tee_client_close_context(ctx); > > > > > > > > + > > > > > > > > + return err; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static void __exit mod_exit(void) > > > > > > > > +{ > > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > > + tee_client_close_context(ctx); > > > > > > > > + hwrng_unregister(&optee_rng); > > > > > > > > +} > > > > > > > > + > > > > > > > > +module_init(mod_init); > > > > > > > > +module_exit(mod_exit); > > > > > > > > + > > > > > > > > +MODULE_LICENSE("GPL"); > > > > > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > > > > > > > > > This is also an indicator that the API design needs some work. If the > > > > > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > > > > > device (which is what this driver should bind to) will only exist if > > > > > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > > > > > /firmware/optee node. > > > > > > > > > > > > > > > > > > > Agree. > > > > > > > > > > > > > > -- > > > > > > > > 2.7.4 > > > > > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/2] hwrng: add OP-TEE based rng driver 2019-01-02 8:04 ` Jens Wiklander 2019-01-02 8:26 ` Bhupesh Sharma @ 2019-01-02 10:12 ` Sumit Garg 1 sibling, 0 replies; 25+ messages in thread From: Sumit Garg @ 2019-01-02 10:12 UTC (permalink / raw) To: Jens Wiklander Cc: Ard Biesheuvel, open list:HARDWARE RANDOM NUMBER GENERATOR CORE, Devicetree List, mpm, Herbert Xu, Rob Herring, Mark Rutland, Arnd Bergmann, Greg Kroah-Hartman, Daniel Thompson, Bhupesh Sharma, tee-dev On Wed, 2 Jan 2019 at 13:34, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > On Mon, Dec 31, 2018 at 11:24 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Fri, 28 Dec 2018 at 20:16, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > > > Hi Sumit, > > > > > > On Fri, Dec 28, 2018 at 06:33:22PM +0530, Sumit Garg wrote: > > > > On Fri, 28 Dec 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > On Fri, 28 Dec 2018 at 10:58, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Thanks Ard for your comments. > > > > > > > > > > > > On Thu, 27 Dec 2018 at 23:58, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > > > > > > > > > > > > > > On Thu, 27 Dec 2018 at 12:08, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > On ARM SoC's with TrustZone enabled, peripherals like entropy sources > > > > > > > > might not be accessible to normal world (linux in this case) and rather > > > > > > > > accessible to secure world (OP-TEE in this case) only. So this driver > > > > > > > > aims to provides a generic interface to OP-TEE based random number > > > > > > > > generator service. > > > > > > > > > > > > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > --- > > > > > > > > MAINTAINERS | 5 + > > > > > > > > drivers/char/hw_random/Kconfig | 15 ++ > > > > > > > > drivers/char/hw_random/Makefile | 1 + > > > > > > > > drivers/char/hw_random/optee-rng.c | 273 +++++++++++++++++++++++++++++++++++++ > > > > > > > > 4 files changed, 294 insertions(+) > > > > > > > > create mode 100644 drivers/char/hw_random/optee-rng.c > > > > > > > > > > > > > > > > > > > > > > Hi Sumit, > > > > > > > > > > > > > > I am having some trouble with this driver. Even though the firmware > > > > > > > manages to invoke the pseudo-TA, the kernel driver responds with > > > > > > > > > > > > > > [ 73.915971] tee_client_open_session failed, error: ffff0008 > > > > > > > > > > > > > > > > > > > Please double check UUID in device tree (probably via dtc dump). > > > > > > > > > > > > > > > > I have added this to the DT: > > > > > > > > > > --- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > > +++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi > > > > > @@ -583,6 +583,7 @@ > > > > > compatible = "linaro,optee-tz"; > > > > > method = "smc"; > > > > > status = "disabled"; > > > > > + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; > > > > > }; > > > > > }; > > > > > }; > > > > > > > > > > > > > It pretty strange as it could work well at my end. Can you please > > > > build optee_os with CFG_TEE_CORE_LOG_LEVEL=4 and share logs? > > > > > > > > > > > > > > > > (note that I need to run teesupplicant or the insmod just hangs) > > > > > > > > > > > > > > > > > > > Actually OP-TEE tries to find TA in following order: > > > > > > > > > > > > 1. early/pseudo TAs (resident). > > > > > > 2. Dynamic TAs (loaded at runtime). > > > > > > > > > > > > So if it doesn't find early/pseudo TAs then it tries to load dynamic > > > > > > TAs via tee-supplicant. It seems that its probably stuck in > > > > > > "optee_supp_thrd_req" (drivers/tee/optee/supp.c +85) where it waits > > > > > > for supplicant to fulfil the request. > > > > > > > > > > > > I think this should be resolved via TEE bus driver approach that I > > > > > > have proposed in previous patch. > > > > > > > > > > > > > > > > It would be useful if we could detect the absence of teesupplicant > > > > > rather than wait indefinitely. Currenty, we cannot make the RNG driver > > > > > a builtin due to this, so please add 'depends on m' as a dependency if > > > > > we don't resolve this in the short term. > > > > > > > > > > > > > By default this module is out of tree only (default m). > > > > > > > > Jens, > > > > > > > > Is there any particular reason to wait indefinitely in > > > > "optee_supp_thrd_req" if there is no supplicant running? I think we > > > > should probably return as follows from "optee_supp_thrd_req" API in > > > > case no supplicant is available: > > > > > > > > --- a/drivers/tee/optee/supp.c > > > > +++ b/drivers/tee/optee/supp.c > > > > @@ -88,10 +88,15 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, > > > > u32 func, size_t num_params, > > > > { > > > > struct optee *optee = tee_get_drvdata(ctx->teedev); > > > > struct optee_supp *supp = &optee->supp; > > > > - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); > > > > + struct optee_supp_req *req; > > > > bool interruptable; > > > > u32 ret; > > > > > > > > + /* Return in case there is no supplicant available */ > > > > + if (!supp->ctx) > > > > + return TEEC_ERROR_COMMUNICATION; > > > > + > > > > + req = kzalloc(sizeof(*req), GFP_KERNEL); > > > > if (!req) > > > > return TEEC_ERROR_OUT_OF_MEMORY; > > > > > > From a user space point of view it has been more useful to just wait > > > until the supplicant starts to serve requests than polling the interface > > > until the call succeeds. For this new use case it makes more sense to be > > > able to return an error instead. > > > > I don't see any case in user-space where user would launch client > > applications before tee-supplicant daemon. If it does so, to me it > > looks like error scenario only. Like in case of dynamic TA loading, > > user should be informed that TA is not found indicating that > > tee-supplicant might not be running. > > It takes a little while after the tee-supplicant daemon has been > started until it has registered itself as a tee-supplicant. That > window has to be closed in some way and that's what we've done with > the current design. > Thanks Jens for further clarification on this over chat. It seems that current tee-supplicant when run with "-d" option (daemon mode added recently) shouldn't be an issue for this API change (non-blocking with return error code). But to be backwards compatible where tee-supplicant is usually started as background process (using "&"), we need blocking mode as well. > As I said in my previous mail, we need a way for the caller to tell if > it should be blocked or get an error if tee-supplicant isn't > available. This has to be done by extending the API instead of making > incompatible changes of it. > > It is tempting to add a flag to struct tee_context (caller specific > struct) which would indicate if tee-supplicant communication is > allowed or not. However, it's a bit ugly and also I'm not sure it will > cover all cases we'll need. > So will add a flag to "struct tee_context" which is default set to blocking mode for tee-supplicant. -Sumit > -Jens > > > > > -Sumit > > > > > > > > The proposed change is a user space API change, so we will need to do a > > > bit more than that. > > > > > > -Jens > > > > > > > > > > > > > > Also, I have some concerns about the DT dependency (see my comment on > > > > > > > the previous patch) > > > > > > > I will cc you on some patches I have to expose OP-TEE via ACPI (as > > > > > > > well as DT) as a platform device. I'd prefer it if we could do the > > > > > > > same for this driver in one way or the other. > > > > > > > > > > > > > > > > > > > Probably via TEE bus driver approach we may get rid of DT or ACPI > > > > > > dependency. BTW, I will switch to platform device as it looks more > > > > > > appropriate. > > > > > > > > > > > > > > > > The bus driver approach only makes sense if we can enumerate the > > > > > available TAs, rather than describe them via the DT or ACPI tables. > > > > > > > > > > But a child node with its own compatible string is an improvement in > > > > > any case, and you can let the driver core instantiate the platform > > > > > device for you. > > > > > > > > > > > > > Ok then I will keep DT or ACPI child node. > > > > > > > > -Sumit > > > > > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > > > > index 0767f1d..fe0fb74 100644 > > > > > > > > --- a/MAINTAINERS > > > > > > > > +++ b/MAINTAINERS > > > > > > > > @@ -11100,6 +11100,11 @@ M: Jens Wiklander <jens.wiklander@linaro.org> > > > > > > > > S: Maintained > > > > > > > > F: drivers/tee/optee/ > > > > > > > > > > > > > > > > +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER > > > > > > > > +M: Sumit Garg <sumit.garg@linaro.org> > > > > > > > > +S: Maintained > > > > > > > > +F: drivers/char/hw_random/optee-rng.c > > > > > > > > + > > > > > > > > OPA-VNIC DRIVER > > > > > > > > M: Dennis Dalessandro <dennis.dalessandro@intel.com> > > > > > > > > M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > > > > > > > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > > > > > > > > index dac895d..25a7d8f 100644 > > > > > > > > --- a/drivers/char/hw_random/Kconfig > > > > > > > > +++ b/drivers/char/hw_random/Kconfig > > > > > > > > @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS > > > > > > > > will be called exynos-trng. > > > > > > > > > > > > > > > > If unsure, say Y. > > > > > > > > + > > > > > > > > +config HW_RANDOM_OPTEE > > > > > > > > + tristate "OP-TEE based Random Number Generator support" > > > > > > > > + depends on OPTEE > > > > > > > > + default HW_RANDOM > > > > > > > > + help > > > > > > > > + This driver provides support for OP-TEE based Random Number > > > > > > > > + Generator on ARM SoCs where hardware entropy sources are not > > > > > > > > + accessible to normal world (Linux). > > > > > > > > + > > > > > > > > + To compile this driver as a module, choose M here: the module > > > > > > > > + will be called optee-rng. > > > > > > > > + > > > > > > > > + If unsure, say Y. > > > > > > > > + > > > > > > > > endif # HW_RANDOM > > > > > > > > > > > > > > > > config UML_RANDOM > > > > > > > > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > > > > > > > > index e35ec3c..7c9ef4a 100644 > > > > > > > > --- a/drivers/char/hw_random/Makefile > > > > > > > > +++ b/drivers/char/hw_random/Makefile > > > > > > > > @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o > > > > > > > > obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o > > > > > > > > +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o > > > > > > > > diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c > > > > > > > > new file mode 100644 > > > > > > > > index 0000000..8c63730 > > > > > > > > --- /dev/null > > > > > > > > +++ b/drivers/char/hw_random/optee-rng.c > > > > > > > > @@ -0,0 +1,273 @@ > > > > > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > > > > > +/* > > > > > > > > + * Copyright (C) 2018 Linaro Ltd. > > > > > > > > + */ > > > > > > > > + > > > > > > > > +#include <linux/delay.h> > > > > > > > > +#include <linux/of.h> > > > > > > > > +#include <linux/hw_random.h> > > > > > > > > +#include <linux/kernel.h> > > > > > > > > +#include <linux/module.h> > > > > > > > > +#include <linux/tee_drv.h> > > > > > > > > +#include <linux/uuid.h> > > > > > > > > + > > > > > > > > +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 > > > > > > > > + > > > > > > > > +/* > > > > > > > > + * TA_CMD_GET_ENTROPY - Get Entropy from RNG > > > > > > > > + * > > > > > > > > + * param[0] (inout memref) - Entropy buffer memory reference > > > > > > > > + * param[1] unused > > > > > > > > + * param[2] unused > > > > > > > > + * param[3] unused > > > > > > > > + * > > > > > > > > + * Result: > > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > > + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool > > > > > > > > + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed > > > > > > > > + */ > > > > > > > > +#define TA_CMD_GET_ENTROPY 0x0 > > > > > > > > + > > > > > > > > +/* > > > > > > > > + * TA_CMD_GET_RNG_INFO - Get RNG information > > > > > > > > + * > > > > > > > > + * param[0] (out value) - value.a: RNG data-rate in bytes per second > > > > > > > > + * value.b: Quality/Entropy per 1024 bit of data > > > > > > > > + * param[1] unused > > > > > > > > + * param[2] unused > > > > > > > > + * param[3] unused > > > > > > > > + * > > > > > > > > + * Result: > > > > > > > > + * TEE_SUCCESS - Invoke command success > > > > > > > > + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param > > > > > > > > + */ > > > > > > > > +#define TA_CMD_GET_RNG_INFO 0x1 > > > > > > > > + > > > > > > > > +#define MAX_ENTROPY_REQ_SZ (4 * 1024) > > > > > > > > + > > > > > > > > +static struct tee_context *ctx; > > > > > > > > +static struct tee_shm *entropy_shm_pool; > > > > > > > > +static u32 ta_rng_data_rate; > > > > > > > > +static u32 ta_rng_seesion_id; > > > > > > > > > > > > > > session not seesion > > > > > > > > > > > > > > > > > > > Will fix. > > > > > > > > > > > > > > + > > > > > > > > +static size_t get_optee_rng_data(void *buf, size_t req_size) > > > > > > > > +{ > > > > > > > > + u32 ret = 0; > > > > > > > > + u8 *rng_data = NULL; > > > > > > > > + size_t rng_size = 0; > > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > > + > > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > > + inv_arg.func = TA_CMD_GET_ENTROPY; > > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > > + inv_arg.num_params = 4; > > > > > > > > + > > > > > > > > + /* Fill invoke cmd params */ > > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > > > > > + param[0].u.memref.shm = entropy_shm_pool; > > > > > > > > + param[0].u.memref.size = req_size; > > > > > > > > + param[0].u.memref.shm_offs = 0; > > > > > > > > + > > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > > + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", > > > > > > > > + inv_arg.ret); > > > > > > > > + return 0; > > > > > > > > + } > > > > > > > > + > > > > > > > > + rng_data = tee_shm_get_va(entropy_shm_pool, 0); > > > > > > > > + if (IS_ERR(rng_data)) { > > > > > > > > + pr_err("tee_shm_get_va failed\n"); > > > > > > > > + return 0; > > > > > > > > + } > > > > > > > > + > > > > > > > > + rng_size = param[0].u.memref.size; > > > > > > > > + memcpy(buf, rng_data, rng_size); > > > > > > > > + > > > > > > > > + return rng_size; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) > > > > > > > > +{ > > > > > > > > + u8 *data = buf; > > > > > > > > + size_t read = 0, rng_size = 0; > > > > > > > > + int timeout = 1; > > > > > > > > + > > > > > > > > + if (max > MAX_ENTROPY_REQ_SZ) > > > > > > > > + max = MAX_ENTROPY_REQ_SZ; > > > > > > > > + > > > > > > > > + while (read == 0) { > > > > > > > > + rng_size = get_optee_rng_data(data, (max - read)); > > > > > > > > + > > > > > > > > + data += rng_size; > > > > > > > > + read += rng_size; > > > > > > > > + > > > > > > > > + if (wait) { > > > > > > > > + if (timeout-- == 0) > > > > > > > > + return read; > > > > > > > > + msleep((1000 * (max - read)) / ta_rng_data_rate); > > > > > > > > + } else { > > > > > > > > + return read; > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > + return read; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_rng_init(struct hwrng *rng) > > > > > > > > +{ > > > > > > > > + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, > > > > > > > > + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); > > > > > > > > + if (IS_ERR(entropy_shm_pool)) { > > > > > > > > + pr_err("tee_shm_alloc failed\n"); > > > > > > > > + return PTR_ERR(entropy_shm_pool); > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static void optee_rng_cleanup(struct hwrng *rng) > > > > > > > > +{ > > > > > > > > + tee_shm_free(entropy_shm_pool); > > > > > > > > +} > > > > > > > > + > > > > > > > > +static struct hwrng optee_rng = { > > > > > > > > + .name = "optee-rng", > > > > > > > > + .init = optee_rng_init, > > > > > > > > + .cleanup = optee_rng_cleanup, > > > > > > > > + .read = optee_rng_read, > > > > > > > > +}; > > > > > > > > + > > > > > > > > +static const struct of_device_id optee_match[] = { > > > > > > > > + { .compatible = "linaro,optee-tz" }, > > > > > > > > + {}, > > > > > > > > +}; > > > > > > > > + > > > > > > > > +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) > > > > > > > > +{ > > > > > > > > + struct device_node *fw_np; > > > > > > > > + struct device_node *np; > > > > > > > > + const char *uuid; > > > > > > > > + > > > > > > > > + /* Node is supposed to be below /firmware */ > > > > > > > > + fw_np = of_find_node_by_name(NULL, "firmware"); > > > > > > > > + if (!fw_np) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + np = of_find_matching_node(fw_np, optee_match); > > > > > > > > + if (!np || !of_device_is_available(np)) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + if (of_property_read_string(np, "rng-uuid", &uuid)) { > > > > > > > > + pr_warn("missing \"uuid\" property\n"); > > > > > > > > + return -ENXIO; > > > > > > > > + } > > > > > > > > + > > > > > > > > > > > > > > So, duplicating all of this is really not a good idea. > > > > > > > > > > > > > > > > > > > Yeah, we may not need this in case we go via TEE bus driver approach. > > > > > > > > > > > > > > + if (uuid_parse(uuid, ta_rng_uuid)) { > > > > > > > > + pr_warn("incorrect rng ta uuid\n"); > > > > > > > > + return -EINVAL; > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int get_optee_rng_info(void) > > > > > > > > +{ > > > > > > > > + u32 ret = 0; > > > > > > > > + struct tee_ioctl_invoke_arg inv_arg = {0}; > > > > > > > > + struct tee_param param[4] = {0}; > > > > > > > > + > > > > > > > > + /* Invoke TA_CMD_GET_RNG function of Trusted App */ > > > > > > > > + inv_arg.func = TA_CMD_GET_RNG_INFO; > > > > > > > > + inv_arg.session = ta_rng_seesion_id; > > > > > > > > + inv_arg.num_params = 4; > > > > > > > > + > > > > > > > > + /* Fill invoke cmd params */ > > > > > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > > > > > + > > > > > > > > + ret = tee_client_invoke_func(ctx, &inv_arg, param); > > > > > > > > + if ((ret < 0) || (inv_arg.ret != 0)) { > > > > > > > > + pr_err("TA_CMD_GET_RNG_INFO invoke function error: %x\n", > > > > > > > > + inv_arg.ret); > > > > > > > > + return -EINVAL; > > > > > > > > + } > > > > > > > > + > > > > > > > > + ta_rng_data_rate = param[0].u.value.a; > > > > > > > > + optee_rng.quality = param[0].u.value.b; > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > > > > > +{ > > > > > > > > + if (ver->impl_id == TEE_IMPL_ID_OPTEE) > > > > > > > > + return 1; > > > > > > > > + else > > > > > > > > + return 0; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static int __init mod_init(void) > > > > > > > > +{ > > > > > > > > + int ret = 0, err = -ENODEV; > > > > > > > > + struct tee_ioctl_open_session_arg sess_arg = {0}; > > > > > > > > + uuid_t ta_rng_uuid = {0}; > > > > > > > > + > > > > > > > > + err = get_optee_rng_uuid(&ta_rng_uuid); > > > > > > > > + if (err) > > > > > > > > + return err; > > > > > > > > + > > > > > > > > + /* Open context with TEE driver */ > > > > > > > > + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > > > > > + if (IS_ERR(ctx)) > > > > > > > > + return -ENODEV; > > > > > > > > + > > > > > > > > + /* Open session with hwrng Trusted App */ > > > > > > > > + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); > > > > > > > > + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; > > > > > > > > + sess_arg.num_params = 0; > > > > > > > > + > > > > > > > > + ret = tee_client_open_session(ctx, &sess_arg, NULL); > > > > > > > > + if ((ret < 0) || (sess_arg.ret != 0)) { > > > > > > > > + pr_err("tee_client_open_session failed, error: %x\n", > > > > > > > > + sess_arg.ret); > > > > > > > > + err = -EINVAL; > > > > > > > > + goto out_ctx; > > > > > > > > + } > > > > > > > > + ta_rng_seesion_id = sess_arg.session; > > > > > > > > + > > > > > > > > + err = get_optee_rng_info(); > > > > > > > > + if (err) > > > > > > > > + goto out_sess; > > > > > > > > + > > > > > > > > + err = hwrng_register(&optee_rng); > > > > > > > > + if (err) { > > > > > > > > + pr_err("registering failed (%d)\n", err); > > > > > > > > + goto out_sess; > > > > > > > > + } > > > > > > > > + > > > > > > > > + return 0; > > > > > > > > + > > > > > > > > +out_sess: > > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > > +out_ctx: > > > > > > > > + tee_client_close_context(ctx); > > > > > > > > + > > > > > > > > + return err; > > > > > > > > +} > > > > > > > > + > > > > > > > > +static void __exit mod_exit(void) > > > > > > > > +{ > > > > > > > > + tee_client_close_session(ctx, ta_rng_seesion_id); > > > > > > > > + tee_client_close_context(ctx); > > > > > > > > + hwrng_unregister(&optee_rng); > > > > > > > > +} > > > > > > > > + > > > > > > > > +module_init(mod_init); > > > > > > > > +module_exit(mod_exit); > > > > > > > > + > > > > > > > > +MODULE_LICENSE("GPL"); > > > > > > > > +MODULE_AUTHOR("Sumit Garg <sumit.garg@linaro.org>"); > > > > > > > > +MODULE_DESCRIPTION("OP-TEE based random number generator driver"); > > > > > > > > +MODULE_SOFTDEP("pre: optee"); > > > > > > > > > > > > > > This is also an indicator that the API design needs some work. If the > > > > > > > OP-TEE driver becomes a 'bus' driver of some sort, the child RNG > > > > > > > device (which is what this driver should bind to) will only exist if > > > > > > > a) the OP-TEE driver is loaded, and b) it has actually bound to the > > > > > > > /firmware/optee node. > > > > > > > > > > > > > > > > > > > Agree. > > > > > > > > > > > > > > -- > > > > > > > > 2.7.4 > > > > > > > > ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2019-01-07 6:46 UTC | newest] Thread overview: 25+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-12-27 11:07 [PATCH v1 0/2] Add OP-TEE based hwrng driver Sumit Garg 2018-12-27 11:07 ` [PATCH v1 1/2] dt/bindings: add bindings for optional optee rng-uuid property Sumit Garg 2018-12-27 13:39 ` Ard Biesheuvel 2018-12-28 9:11 ` Sumit Garg 2019-01-03 17:14 ` Daniel Thompson 2019-01-04 6:39 ` Sumit Garg 2019-01-04 11:01 ` Jens Wiklander 2019-01-04 12:01 ` Sumit Garg 2019-01-04 13:03 ` Jens Wiklander 2019-01-07 5:32 ` Sumit Garg 2019-01-07 5:59 ` Ard Biesheuvel 2019-01-07 6:46 ` Sumit Garg 2019-01-03 16:20 ` Rob Herring 2018-12-27 11:07 ` [PATCH v1 2/2] hwrng: add OP-TEE based rng driver Sumit Garg 2018-12-27 18:28 ` Ard Biesheuvel 2018-12-28 9:58 ` Sumit Garg 2018-12-28 10:38 ` Ard Biesheuvel 2018-12-28 13:03 ` Sumit Garg 2018-12-28 14:46 ` Jens Wiklander 2018-12-30 14:59 ` Vesa Jääskeläinen 2018-12-31 10:35 ` Sumit Garg 2018-12-31 10:24 ` Sumit Garg 2019-01-02 8:04 ` Jens Wiklander 2019-01-02 8:26 ` Bhupesh Sharma 2019-01-02 10:12 ` Sumit Garg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).