Message ID | 20200127165646.19806-9-andrew.smirnov@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Herbert Xu |
Headers | show |
Series | enable CAAM's HWRNG as default | expand |
On 1/27/2020 6:56 PM, Andrey Smirnov wrote: > +static bool caam_mc_skip_hwrng_init(struct caam_drv_private *ctrlpriv) > +{ > + return ctrlpriv->mc_en; > + /* > + * FIXME: Add check for MC firmware version that need > + * reinitialization due to PR bit > + */ > +} > + Hi Andrey, Please use the following patch as a way to check for MC firmware version. This should be squashed into current PATCH v7 8/9. -- >8 -- From: Andrei Botila <andrei.botila@nxp.com> Subject: [PATCH] crypto: caam - check mc firmware version before instantiating rng Management Complex firmware with version lower than 10.20.0 doesn't provide prediction resistance support. Consider this and only instantiate rng when mc f/w version is lower. Signed-off-by: Andrei Botila <andrei.botila@nxp.com> --- drivers/crypto/caam/Kconfig | 1 + drivers/crypto/caam/ctrl.c | 46 ++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index fac5b2e26610..d0e833121d8c 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -13,6 +13,7 @@ config CRYPTO_DEV_FSL_CAAM depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE select SOC_BUS select CRYPTO_DEV_FSL_CAAM_COMMON + imply FSL_MC_BUS help Enables the driver module for Freescale's Cryptographic Accelerator and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 167a79fa3b8a..52b98e8d5175 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -10,6 +10,7 @@ #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/sys_soc.h> +#include <linux/fsl/mc.h> #include "compat.h" #include "regs.h" @@ -578,14 +579,24 @@ static void caam_remove_debugfs(void *root) } #endif -static bool caam_mc_skip_hwrng_init(struct caam_drv_private *ctrlpriv) +#ifdef CONFIG_FSL_MC_BUS +static bool check_version(struct fsl_mc_version *mc_version, u32 major, + u32 minor, u32 revision) { - return ctrlpriv->mc_en; - /* - * FIXME: Add check for MC firmware version that need - * reinitialization due to PR bit - */ + if (mc_version->major > major) + return true; + + if (mc_version->major == major) { + if (mc_version->minor > minor) + return true; + + if (mc_version->minor == minor && mc_version->revision > 0) + return true; + } + + return false; } +#endif /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct platform_device *pdev) @@ -605,6 +616,7 @@ static int caam_probe(struct platform_device *pdev) u8 rng_vid; int pg_size; int BLOCK_OFFSET = 0; + bool pr_support = false; ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL); if (!ctrlpriv) @@ -691,16 +703,28 @@ static int caam_probe(struct platform_device *pdev) /* Get the IRQ of the controller (for security violations only) */ ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); + np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc"); + ctrlpriv->mc_en = !!np; + of_node_put(np); + +#ifdef CONFIG_FSL_MC_BUS + if (ctrlpriv->mc_en) { + struct fsl_mc_version *mc_version; + + mc_version = fsl_mc_get_version(); + if (mc_version) + pr_support = check_version(mc_version, 10, 20, 0); + else + return -EPROBE_DEFER; + } +#endif + /* * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, * long pointers in master configuration register. * In case of SoCs with Management Complex, MC f/w performs * the configuration. */ - np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc"); - ctrlpriv->mc_en = !!np; - of_node_put(np); - if (!ctrlpriv->mc_en) clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | @@ -807,7 +831,7 @@ static int caam_probe(struct platform_device *pdev) * already instantiated, do RNG instantiation * In case of SoCs with Management Complex, RNG is managed by MC f/w. */ - if (!caam_mc_skip_hwrng_init(ctrlpriv) && rng_vid >= 4) { + if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) { ctrlpriv->rng4_sh_init = rd_reg32(&ctrl->r4tst[0].rdsta); /*
On 2/4/2020 3:09 PM, Andrei Botila (OSS) wrote: > On 1/27/2020 6:56 PM, Andrey Smirnov wrote: >> +static bool caam_mc_skip_hwrng_init(struct caam_drv_private *ctrlpriv) >> +{ >> + return ctrlpriv->mc_en; >> + /* >> + * FIXME: Add check for MC firmware version that need >> + * reinitialization due to PR bit >> + */ >> +} >> + > > Hi Andrey, > > Please use the following patch as a way to check for MC firmware version. > This should be squashed into current PATCH v7 8/9. > Btw, this depends on the fsl-mc bus patch that adds fsl_mc_get_version() bus: fsl-mc: add api to retrieve mc version https://patchwork.kernel.org/patch/11352493/ As already stated, I would like to take the fsl-mc bus dependency through the crypto tree. Greg, Herbert - are you ok with this? Thanks, Horia > -- >8 -- > > From: Andrei Botila <andrei.botila@nxp.com> > Subject: [PATCH] crypto: caam - check mc firmware version before instantiating > rng > > Management Complex firmware with version lower than 10.20.0 > doesn't provide prediction resistance support. Consider this > and only instantiate rng when mc f/w version is lower. > > Signed-off-by: Andrei Botila <andrei.botila@nxp.com> > --- > drivers/crypto/caam/Kconfig | 1 + > drivers/crypto/caam/ctrl.c | 46 ++++++++++++++++++++++++++++--------- > 2 files changed, 36 insertions(+), 11 deletions(-) > > diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig > index fac5b2e26610..d0e833121d8c 100644 > --- a/drivers/crypto/caam/Kconfig > +++ b/drivers/crypto/caam/Kconfig > @@ -13,6 +13,7 @@ config CRYPTO_DEV_FSL_CAAM > depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE > select SOC_BUS > select CRYPTO_DEV_FSL_CAAM_COMMON > + imply FSL_MC_BUS > help > Enables the driver module for Freescale's Cryptographic Accelerator > and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). > diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c > index 167a79fa3b8a..52b98e8d5175 100644 > --- a/drivers/crypto/caam/ctrl.c > +++ b/drivers/crypto/caam/ctrl.c > @@ -10,6 +10,7 @@ > #include <linux/of_address.h> > #include <linux/of_irq.h> > #include <linux/sys_soc.h> > +#include <linux/fsl/mc.h> > > #include "compat.h" > #include "regs.h" > @@ -578,14 +579,24 @@ static void caam_remove_debugfs(void *root) > } > #endif > > -static bool caam_mc_skip_hwrng_init(struct caam_drv_private *ctrlpriv) > +#ifdef CONFIG_FSL_MC_BUS > +static bool check_version(struct fsl_mc_version *mc_version, u32 major, > + u32 minor, u32 revision) > { > - return ctrlpriv->mc_en; > - /* > - * FIXME: Add check for MC firmware version that need > - * reinitialization due to PR bit > - */ > + if (mc_version->major > major) > + return true; > + > + if (mc_version->major == major) { > + if (mc_version->minor > minor) > + return true; > + > + if (mc_version->minor == minor && mc_version->revision > 0) > + return true; > + } > + > + return false; > } > +#endif > > /* Probe routine for CAAM top (controller) level */ > static int caam_probe(struct platform_device *pdev) > @@ -605,6 +616,7 @@ static int caam_probe(struct platform_device *pdev) > u8 rng_vid; > int pg_size; > int BLOCK_OFFSET = 0; > + bool pr_support = false; > > ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL); > if (!ctrlpriv) > @@ -691,16 +703,28 @@ static int caam_probe(struct platform_device *pdev) > /* Get the IRQ of the controller (for security violations only) */ > ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); > > + np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc"); > + ctrlpriv->mc_en = !!np; > + of_node_put(np); > + > +#ifdef CONFIG_FSL_MC_BUS > + if (ctrlpriv->mc_en) { > + struct fsl_mc_version *mc_version; > + > + mc_version = fsl_mc_get_version(); > + if (mc_version) > + pr_support = check_version(mc_version, 10, 20, 0); > + else > + return -EPROBE_DEFER; > + } > +#endif > + > /* > * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, > * long pointers in master configuration register. > * In case of SoCs with Management Complex, MC f/w performs > * the configuration. > */ > - np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc"); > - ctrlpriv->mc_en = !!np; > - of_node_put(np); > - > if (!ctrlpriv->mc_en) > clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, > MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | > @@ -807,7 +831,7 @@ static int caam_probe(struct platform_device *pdev) > * already instantiated, do RNG instantiation > * In case of SoCs with Management Complex, RNG is managed by MC f/w. > */ > - if (!caam_mc_skip_hwrng_init(ctrlpriv) && rng_vid >= 4) { > + if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) { > ctrlpriv->rng4_sh_init = > rd_reg32(&ctrl->r4tst[0].rdsta); > /* >
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c index 790624ae83c6..62f3a69ae837 100644 --- a/drivers/crypto/caam/caamrng.c +++ b/drivers/crypto/caam/caamrng.c @@ -77,7 +77,8 @@ static u32 *caam_init_desc(u32 *desc, dma_addr_t dst_dma, int len) { init_job_desc(desc, 0); /* + 1 cmd_sz */ /* Generate random bytes: + 1 cmd_sz */ - append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG); + append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG | + OP_ALG_PR_ON); /* Store bytes */ append_fifo_store(desc, dst_dma, len, FIFOST_TYPE_RNGSTORE); diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index bcbc832b208e..ad3f6aa921d3 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -36,7 +36,8 @@ static void build_instantiation_desc(u32 *desc, int handle, int do_sk) init_job_desc(desc, 0); op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | - (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT; + (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT | + OP_ALG_PR_ON; /* INIT RNG in non-test mode */ append_operation(desc, op_flags); @@ -276,12 +277,25 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, return -ENOMEM; for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { + const u32 rdsta_if = RDSTA_IF0 << sh_idx; + const u32 rdsta_pr = RDSTA_PR0 << sh_idx; + const u32 rdsta_mask = rdsta_if | rdsta_pr; /* * If the corresponding bit is set, this state handle * was initialized by somebody else, so it's left alone. */ - if ((1 << sh_idx) & state_handle_mask) - continue; + if (rdsta_if & state_handle_mask) { + if (rdsta_pr & state_handle_mask) + continue; + + dev_info(ctrldev, + "RNG4 SH%d was previously instantiated without prediction resistance. Tearing it down\n", + sh_idx); + + ret = deinstantiate_rng(ctrldev, rdsta_if); + if (ret) + break; + } /* Create the descriptor for instantiating RNG State Handle */ build_instantiation_desc(desc, sh_idx, gen_sk); @@ -301,9 +315,9 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, if (ret) break; - rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK; + rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_MASK; if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) || - !(rdsta_val & (1 << sh_idx))) { + (rdsta_val & rdsta_mask) != rdsta_mask) { ret = -EAGAIN; break; } @@ -563,6 +577,15 @@ static void caam_remove_debugfs(void *root) } #endif +static bool caam_mc_skip_hwrng_init(struct caam_drv_private *ctrlpriv) +{ + return ctrlpriv->mc_en; + /* + * FIXME: Add check for MC firmware version that need + * reinitialization due to PR bit + */ +} + /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct platform_device *pdev) { @@ -783,7 +806,7 @@ static int caam_probe(struct platform_device *pdev) * already instantiated, do RNG instantiation * In case of SoCs with Management Complex, RNG is managed by MC f/w. */ - if (!ctrlpriv->mc_en && rng_vid >= 4) { + if (!caam_mc_skip_hwrng_init(ctrlpriv) && rng_vid >= 4) { ctrlpriv->rng4_sh_init = rd_reg32(&ctrl->r4tst[0].rdsta); /* @@ -793,11 +816,11 @@ static int caam_probe(struct platform_device *pdev) * to regenerate these keys before the next POR. */ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1; - ctrlpriv->rng4_sh_init &= RDSTA_IFMASK; + ctrlpriv->rng4_sh_init &= RDSTA_MASK; do { int inst_handles = rd_reg32(&ctrl->r4tst[0].rdsta) & - RDSTA_IFMASK; + RDSTA_MASK; /* * If either SH were instantiated by somebody else * (e.g. u-boot) then it is assumed that the entropy @@ -837,7 +860,7 @@ static int caam_probe(struct platform_device *pdev) * Set handles init'ed by this module as the complement of the * already initialized ones */ - ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK; + ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK; /* Enable RDB bit so that RNG works faster */ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE); diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index 4b6854bf896a..e796d3cb9be8 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -1254,6 +1254,8 @@ #define OP_ALG_ICV_OFF (0 << OP_ALG_ICV_SHIFT) #define OP_ALG_ICV_ON (1 << OP_ALG_ICV_SHIFT) +#define OP_ALG_PR_ON BIT(1) + #define OP_ALG_DIR_SHIFT 0 #define OP_ALG_DIR_MASK 1 #define OP_ALG_DECRYPT 0 diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index c191e8fd0fa7..0f810bc13b2b 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -524,9 +524,11 @@ struct rng4tst { u32 rsvd1[40]; #define RDSTA_SKVT 0x80000000 #define RDSTA_SKVN 0x40000000 +#define RDSTA_PR0 BIT(4) +#define RDSTA_PR1 BIT(5) #define RDSTA_IF0 0x00000001 #define RDSTA_IF1 0x00000002 -#define RDSTA_IFMASK (RDSTA_IF1 | RDSTA_IF0) +#define RDSTA_MASK (RDSTA_PR1 | RDSTA_PR0 | RDSTA_IF1 | RDSTA_IF0) u32 rdsta; u32 rsvd2[15]; };
Instantiate CAAM RNG with prediction resistance enabled to improve its quality (with PR on DRNG is forced to reseed from TRNG every time random data is generated). Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Cc: Chris Healy <cphealy@gmail.com> Cc: Lucas Stach <l.stach@pengutronix.de> Cc: Horia Geantă <horia.geanta@nxp.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Iuliana Prodan <iuliana.prodan@nxp.com> Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-imx@nxp.com --- drivers/crypto/caam/caamrng.c | 3 ++- drivers/crypto/caam/ctrl.c | 41 +++++++++++++++++++++++++++-------- drivers/crypto/caam/desc.h | 2 ++ drivers/crypto/caam/regs.h | 4 +++- 4 files changed, 39 insertions(+), 11 deletions(-)