diff mbox series

[08/10] tpm: Add the RNG child device

Message ID 20220224180552.26901-9-sughosh.ganu@linaro.org
State Superseded
Headers show
Series tpm: rng: Move TPM RNG functionality to driver model | expand

Commit Message

Sughosh Ganu Feb. 24, 2022, 6:05 p.m. UTC
The TPM device comes with the random number generator(RNG)
functionality which is built into the TPM device. Add logic to add the
RNG child device in the TPM uclass post probe callback.

The RNG device can then be used to pass a set of random bytes to the
linux kernel, need for address space randomisation through the
EFI_RNG_PROTOCOL interface.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 drivers/tpm/tpm-uclass.c | 58 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

Comments

Heinrich Schuchardt Feb. 24, 2022, 6:51 p.m. UTC | #1
On 2/24/22 19:05, Sughosh Ganu wrote:
> The TPM device comes with the random number generator(RNG)
> functionality which is built into the TPM device. Add logic to add the
> RNG child device in the TPM uclass post probe callback.
>
> The RNG device can then be used to pass a set of random bytes to the
> linux kernel, need for address space randomisation through the
> EFI_RNG_PROTOCOL interface.
>
> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> ---
>   drivers/tpm/tpm-uclass.c | 58 +++++++++++++++++++++++++++++++++++++---
>   1 file changed, 54 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
> index 8619da89d8..383cc7bc48 100644
> --- a/drivers/tpm/tpm-uclass.c
> +++ b/drivers/tpm/tpm-uclass.c
> @@ -16,6 +16,11 @@
>   #include <tpm-v2.h>
>   #include "tpm_internal.h"
>
> +#include <dm/lists.h>
> +
> +#define TPM_RNG1_DRV_NAME	"tpm1-rng"
> +#define TPM_RNG2_DRV_NAME	"tpm2-rng"
> +
>   bool is_tpm1(struct udevice *dev)
>   {
>   	return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
> @@ -147,12 +152,57 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
>   	return 0;
>   }
>
> +#if IS_ENABLED(CONFIG_TPM)

This is is superfluous.
This file is only compiled if CONFIG_$(SPL_TPL_)TPM = y.

Best regards

Heinrich

> +static int tpm_uclass_post_probe(struct udevice *dev)
> +{
> +	int ret;
> +	const char *drv = is_tpm1(dev) ? TPM_RNG1_DRV_NAME : TPM_RNG2_DRV_NAME;
> +	struct udevice *child;
> +
> +	ret = device_bind_driver(dev, drv, "tpm-rng0", &child);
> +	if (ret == -ENOENT) {
> +		log_err("No driver configured for tpm-rng device\n");
> +		return 0;
> +	}
> +
> +	if (ret) {
> +		log_err("Unable to bind rng driver with the tpm-rng device\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int tpm_uclass_child_pre_probe(struct udevice *dev)
> +{
> +	int ret;
> +
> +	ret = tpm_open(dev->parent);
> +	if (ret == -EBUSY) {
> +		log_info("TPM device already opened\n");
> +	} else if (ret) {
> +		log_err("Unable to open TPM device\n");
> +		return ret;
> +	}
> +
> +	ret = tpm_startup(dev->parent, TPM_ST_CLEAR);
> +	if (ret)
> +		log_err("Unable to start TPM device\n");
> +
> +	return ret;
> +}
> +#endif /* CONFIG_TPM */
> +
>   UCLASS_DRIVER(tpm) = {
> -	.id		= UCLASS_TPM,
> -	.name		= "tpm",
> -	.flags		= DM_UC_FLAG_SEQ_ALIAS,
> +	.id			= UCLASS_TPM,
> +	.name			= "tpm",
> +	.flags			= DM_UC_FLAG_SEQ_ALIAS,
>   #if CONFIG_IS_ENABLED(OF_REAL)
> -	.post_bind	= dm_scan_fdt_dev,
> +	.post_bind		= dm_scan_fdt_dev,
> +#endif
> +#if IS_ENABLED(CONFIG_TPM)
> +	.post_probe		= tpm_uclass_post_probe,
> +	.child_pre_probe	= tpm_uclass_child_pre_probe,
>   #endif
>   	.per_device_auto	= sizeof(struct tpm_chip_priv),
>   };
Sughosh Ganu Feb. 25, 2022, 5:45 a.m. UTC | #2
On Fri, 25 Feb 2022 at 00:21, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 2/24/22 19:05, Sughosh Ganu wrote:
> > The TPM device comes with the random number generator(RNG)
> > functionality which is built into the TPM device. Add logic to add the
> > RNG child device in the TPM uclass post probe callback.
> >
> > The RNG device can then be used to pass a set of random bytes to the
> > linux kernel, need for address space randomisation through the
> > EFI_RNG_PROTOCOL interface.
> >
> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > ---
> >   drivers/tpm/tpm-uclass.c | 58 +++++++++++++++++++++++++++++++++++++---
> >   1 file changed, 54 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
> > index 8619da89d8..383cc7bc48 100644
> > --- a/drivers/tpm/tpm-uclass.c
> > +++ b/drivers/tpm/tpm-uclass.c
> > @@ -16,6 +16,11 @@
> >   #include <tpm-v2.h>
> >   #include "tpm_internal.h"
> >
> > +#include <dm/lists.h>
> > +
> > +#define TPM_RNG1_DRV_NAME    "tpm1-rng"
> > +#define TPM_RNG2_DRV_NAME    "tpm2-rng"
> > +
> >   bool is_tpm1(struct udevice *dev)
> >   {
> >       return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
> > @@ -147,12 +152,57 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
> >       return 0;
> >   }
> >
> > +#if IS_ENABLED(CONFIG_TPM)
>
> This is is superfluous.
> This file is only compiled if CONFIG_$(SPL_TPL_)TPM = y.

Yes, but I want the RNG child device addition to be done only in case
of u-boot proper, not for SPL and TPM. We do not have RNG support for
the SPL/TPM boot stages. So unless someone needs to enable RNG support
for SPL/TPL stages, which I doubt, this code should run only in u-boot
proper. Thanks.

-sughosh

>
> Best regards
>
> Heinrich
>
> > +static int tpm_uclass_post_probe(struct udevice *dev)
> > +{
> > +     int ret;
> > +     const char *drv = is_tpm1(dev) ? TPM_RNG1_DRV_NAME : TPM_RNG2_DRV_NAME;
> > +     struct udevice *child;
> > +
> > +     ret = device_bind_driver(dev, drv, "tpm-rng0", &child);
> > +     if (ret == -ENOENT) {
> > +             log_err("No driver configured for tpm-rng device\n");
> > +             return 0;
> > +     }
> > +
> > +     if (ret) {
> > +             log_err("Unable to bind rng driver with the tpm-rng device\n");
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int tpm_uclass_child_pre_probe(struct udevice *dev)
> > +{
> > +     int ret;
> > +
> > +     ret = tpm_open(dev->parent);
> > +     if (ret == -EBUSY) {
> > +             log_info("TPM device already opened\n");
> > +     } else if (ret) {
> > +             log_err("Unable to open TPM device\n");
> > +             return ret;
> > +     }
> > +
> > +     ret = tpm_startup(dev->parent, TPM_ST_CLEAR);
> > +     if (ret)
> > +             log_err("Unable to start TPM device\n");
> > +
> > +     return ret;
> > +}
> > +#endif /* CONFIG_TPM */
> > +
> >   UCLASS_DRIVER(tpm) = {
> > -     .id             = UCLASS_TPM,
> > -     .name           = "tpm",
> > -     .flags          = DM_UC_FLAG_SEQ_ALIAS,
> > +     .id                     = UCLASS_TPM,
> > +     .name                   = "tpm",
> > +     .flags                  = DM_UC_FLAG_SEQ_ALIAS,
> >   #if CONFIG_IS_ENABLED(OF_REAL)
> > -     .post_bind      = dm_scan_fdt_dev,
> > +     .post_bind              = dm_scan_fdt_dev,
> > +#endif
> > +#if IS_ENABLED(CONFIG_TPM)
> > +     .post_probe             = tpm_uclass_post_probe,
> > +     .child_pre_probe        = tpm_uclass_child_pre_probe,
> >   #endif
> >       .per_device_auto        = sizeof(struct tpm_chip_priv),
> >   };
>
Heinrich Schuchardt Feb. 25, 2022, 6:30 a.m. UTC | #3
On 2/25/22 06:45, Sughosh Ganu wrote:
> On Fri, 25 Feb 2022 at 00:21, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>>
>> On 2/24/22 19:05, Sughosh Ganu wrote:
>>> The TPM device comes with the random number generator(RNG)
>>> functionality which is built into the TPM device. Add logic to add the
>>> RNG child device in the TPM uclass post probe callback.
>>>
>>> The RNG device can then be used to pass a set of random bytes to the
>>> linux kernel, need for address space randomisation through the
>>> EFI_RNG_PROTOCOL interface.
>>>
>>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
>>> ---
>>>    drivers/tpm/tpm-uclass.c | 58 +++++++++++++++++++++++++++++++++++++---
>>>    1 file changed, 54 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
>>> index 8619da89d8..383cc7bc48 100644
>>> --- a/drivers/tpm/tpm-uclass.c
>>> +++ b/drivers/tpm/tpm-uclass.c
>>> @@ -16,6 +16,11 @@
>>>    #include <tpm-v2.h>
>>>    #include "tpm_internal.h"
>>>
>>> +#include <dm/lists.h>
>>> +
>>> +#define TPM_RNG1_DRV_NAME    "tpm1-rng"
>>> +#define TPM_RNG2_DRV_NAME    "tpm2-rng"
>>> +
>>>    bool is_tpm1(struct udevice *dev)
>>>    {
>>>        return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
>>> @@ -147,12 +152,57 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
>>>        return 0;
>>>    }
>>>
>>> +#if IS_ENABLED(CONFIG_TPM)
>>
>> This is is superfluous.
>> This file is only compiled if CONFIG_$(SPL_TPL_)TPM = y.
>
> Yes, but I want the RNG child device addition to be done only in case
> of u-boot proper, not for SPL and TPM. We do not have RNG support for
> the SPL/TPM boot stages. So unless someone needs to enable RNG support
> for SPL/TPL stages, which I doubt, this code should run only in u-boot
> proper. Thanks.

The tpm-uclass.c is never compiled in SPL or TPL. Have a look at
drivers/tpm/Kconfig. There is no CONFIG_SPL_TPM or CONFIG_TPL_TPM symbol.

Best regards

Heinrich

>
> -sughosh
>
>>
>> Best regards
>>
>> Heinrich
>>
>>> +static int tpm_uclass_post_probe(struct udevice *dev)
>>> +{
>>> +     int ret;
>>> +     const char *drv = is_tpm1(dev) ? TPM_RNG1_DRV_NAME : TPM_RNG2_DRV_NAME;
>>> +     struct udevice *child;
>>> +
>>> +     ret = device_bind_driver(dev, drv, "tpm-rng0", &child);
>>> +     if (ret == -ENOENT) {
>>> +             log_err("No driver configured for tpm-rng device\n");
>>> +             return 0;
>>> +     }
>>> +
>>> +     if (ret) {
>>> +             log_err("Unable to bind rng driver with the tpm-rng device\n");
>>> +             return ret;
>>> +     }
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int tpm_uclass_child_pre_probe(struct udevice *dev)
>>> +{
>>> +     int ret;
>>> +
>>> +     ret = tpm_open(dev->parent);
>>> +     if (ret == -EBUSY) {
>>> +             log_info("TPM device already opened\n");
>>> +     } else if (ret) {
>>> +             log_err("Unable to open TPM device\n");
>>> +             return ret;
>>> +     }
>>> +
>>> +     ret = tpm_startup(dev->parent, TPM_ST_CLEAR);
>>> +     if (ret)
>>> +             log_err("Unable to start TPM device\n");
>>> +
>>> +     return ret;
>>> +}
>>> +#endif /* CONFIG_TPM */
>>> +
>>>    UCLASS_DRIVER(tpm) = {
>>> -     .id             = UCLASS_TPM,
>>> -     .name           = "tpm",
>>> -     .flags          = DM_UC_FLAG_SEQ_ALIAS,
>>> +     .id                     = UCLASS_TPM,
>>> +     .name                   = "tpm",
>>> +     .flags                  = DM_UC_FLAG_SEQ_ALIAS,
>>>    #if CONFIG_IS_ENABLED(OF_REAL)
>>> -     .post_bind      = dm_scan_fdt_dev,
>>> +     .post_bind              = dm_scan_fdt_dev,
>>> +#endif
>>> +#if IS_ENABLED(CONFIG_TPM)
>>> +     .post_probe             = tpm_uclass_post_probe,
>>> +     .child_pre_probe        = tpm_uclass_child_pre_probe,
>>>    #endif
>>>        .per_device_auto        = sizeof(struct tpm_chip_priv),
>>>    };
>>
Sughosh Ganu Feb. 25, 2022, 6:41 a.m. UTC | #4
hello Heinrich,

On Fri, 25 Feb 2022 at 12:00, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 2/25/22 06:45, Sughosh Ganu wrote:
> > On Fri, 25 Feb 2022 at 00:21, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> >>
> >> On 2/24/22 19:05, Sughosh Ganu wrote:
> >>> The TPM device comes with the random number generator(RNG)
> >>> functionality which is built into the TPM device. Add logic to add the
> >>> RNG child device in the TPM uclass post probe callback.
> >>>
> >>> The RNG device can then be used to pass a set of random bytes to the
> >>> linux kernel, need for address space randomisation through the
> >>> EFI_RNG_PROTOCOL interface.
> >>>
> >>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> >>> ---
> >>>    drivers/tpm/tpm-uclass.c | 58 +++++++++++++++++++++++++++++++++++++---
> >>>    1 file changed, 54 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
> >>> index 8619da89d8..383cc7bc48 100644
> >>> --- a/drivers/tpm/tpm-uclass.c
> >>> +++ b/drivers/tpm/tpm-uclass.c
> >>> @@ -16,6 +16,11 @@
> >>>    #include <tpm-v2.h>
> >>>    #include "tpm_internal.h"
> >>>
> >>> +#include <dm/lists.h>
> >>> +
> >>> +#define TPM_RNG1_DRV_NAME    "tpm1-rng"
> >>> +#define TPM_RNG2_DRV_NAME    "tpm2-rng"
> >>> +
> >>>    bool is_tpm1(struct udevice *dev)
> >>>    {
> >>>        return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
> >>> @@ -147,12 +152,57 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
> >>>        return 0;
> >>>    }
> >>>
> >>> +#if IS_ENABLED(CONFIG_TPM)
> >>
> >> This is is superfluous.
> >> This file is only compiled if CONFIG_$(SPL_TPL_)TPM = y.
> >
> > Yes, but I want the RNG child device addition to be done only in case
> > of u-boot proper, not for SPL and TPM. We do not have RNG support for
> > the SPL/TPM boot stages. So unless someone needs to enable RNG support
> > for SPL/TPL stages, which I doubt, this code should run only in u-boot
> > proper. Thanks.
>
> The tpm-uclass.c is never compiled in SPL or TPL. Have a look at
> drivers/tpm/Kconfig. There is no CONFIG_SPL_TPM or CONFIG_TPL_TPM symbol.

The {S,T}PL_TPM symbol is actually defined under lib/Kconfig.
Currently it is not getting defined in any platform's defconfig, but
one can add it and build the tpm-uclass driver for the SPL/TPL stage
as well. I added the SPL_TPM config to the chromebook_coral and it
indeed builds the tpm-uclass driver. Thanks.

-sughosh

>
> Best regards
>
> Heinrich
>
> >
> > -sughosh
> >
> >>
> >> Best regards
> >>
> >> Heinrich
> >>
> >>> +static int tpm_uclass_post_probe(struct udevice *dev)
> >>> +{
> >>> +     int ret;
> >>> +     const char *drv = is_tpm1(dev) ? TPM_RNG1_DRV_NAME : TPM_RNG2_DRV_NAME;
> >>> +     struct udevice *child;
> >>> +
> >>> +     ret = device_bind_driver(dev, drv, "tpm-rng0", &child);
> >>> +     if (ret == -ENOENT) {
> >>> +             log_err("No driver configured for tpm-rng device\n");
> >>> +             return 0;
> >>> +     }
> >>> +
> >>> +     if (ret) {
> >>> +             log_err("Unable to bind rng driver with the tpm-rng device\n");
> >>> +             return ret;
> >>> +     }
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static int tpm_uclass_child_pre_probe(struct udevice *dev)
> >>> +{
> >>> +     int ret;
> >>> +
> >>> +     ret = tpm_open(dev->parent);
> >>> +     if (ret == -EBUSY) {
> >>> +             log_info("TPM device already opened\n");
> >>> +     } else if (ret) {
> >>> +             log_err("Unable to open TPM device\n");
> >>> +             return ret;
> >>> +     }
> >>> +
> >>> +     ret = tpm_startup(dev->parent, TPM_ST_CLEAR);
> >>> +     if (ret)
> >>> +             log_err("Unable to start TPM device\n");
> >>> +
> >>> +     return ret;
> >>> +}
> >>> +#endif /* CONFIG_TPM */
> >>> +
> >>>    UCLASS_DRIVER(tpm) = {
> >>> -     .id             = UCLASS_TPM,
> >>> -     .name           = "tpm",
> >>> -     .flags          = DM_UC_FLAG_SEQ_ALIAS,
> >>> +     .id                     = UCLASS_TPM,
> >>> +     .name                   = "tpm",
> >>> +     .flags                  = DM_UC_FLAG_SEQ_ALIAS,
> >>>    #if CONFIG_IS_ENABLED(OF_REAL)
> >>> -     .post_bind      = dm_scan_fdt_dev,
> >>> +     .post_bind              = dm_scan_fdt_dev,
> >>> +#endif
> >>> +#if IS_ENABLED(CONFIG_TPM)
> >>> +     .post_probe             = tpm_uclass_post_probe,
> >>> +     .child_pre_probe        = tpm_uclass_child_pre_probe,
> >>>    #endif
> >>>        .per_device_auto        = sizeof(struct tpm_chip_priv),
> >>>    };
> >>
>
diff mbox series

Patch

diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index 8619da89d8..383cc7bc48 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -16,6 +16,11 @@ 
 #include <tpm-v2.h>
 #include "tpm_internal.h"
 
+#include <dm/lists.h>
+
+#define TPM_RNG1_DRV_NAME	"tpm1-rng"
+#define TPM_RNG2_DRV_NAME	"tpm2-rng"
+
 bool is_tpm1(struct udevice *dev)
 {
 	return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
@@ -147,12 +152,57 @@  int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_TPM)
+static int tpm_uclass_post_probe(struct udevice *dev)
+{
+	int ret;
+	const char *drv = is_tpm1(dev) ? TPM_RNG1_DRV_NAME : TPM_RNG2_DRV_NAME;
+	struct udevice *child;
+
+	ret = device_bind_driver(dev, drv, "tpm-rng0", &child);
+	if (ret == -ENOENT) {
+		log_err("No driver configured for tpm-rng device\n");
+		return 0;
+	}
+
+	if (ret) {
+		log_err("Unable to bind rng driver with the tpm-rng device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int tpm_uclass_child_pre_probe(struct udevice *dev)
+{
+	int ret;
+
+	ret = tpm_open(dev->parent);
+	if (ret == -EBUSY) {
+		log_info("TPM device already opened\n");
+	} else if (ret) {
+		log_err("Unable to open TPM device\n");
+		return ret;
+	}
+
+	ret = tpm_startup(dev->parent, TPM_ST_CLEAR);
+	if (ret)
+		log_err("Unable to start TPM device\n");
+
+	return ret;
+}
+#endif /* CONFIG_TPM */
+
 UCLASS_DRIVER(tpm) = {
-	.id		= UCLASS_TPM,
-	.name		= "tpm",
-	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+	.id			= UCLASS_TPM,
+	.name			= "tpm",
+	.flags			= DM_UC_FLAG_SEQ_ALIAS,
 #if CONFIG_IS_ENABLED(OF_REAL)
-	.post_bind	= dm_scan_fdt_dev,
+	.post_bind		= dm_scan_fdt_dev,
+#endif
+#if IS_ENABLED(CONFIG_TPM)
+	.post_probe		= tpm_uclass_post_probe,
+	.child_pre_probe	= tpm_uclass_child_pre_probe,
 #endif
 	.per_device_auto	= sizeof(struct tpm_chip_priv),
 };