Re: CAAM RNG trouble

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/14/2020 9:00 PM, Lucas Stach wrote:
> Hi all,
> 
> I've been looking into a CAAM RNG issue for a while, where I could need
> some input from people knowing the CAAM hardware better than I do.
> Basically the issue is that on some i.MX6 units the RNG functionality
> sometimes fails with this error:
> caam_jr 2101000.jr0: 20003c5b: CCB: desc idx 60: RNG: Hardware error.
> 
> I can tell that it is related to the entropy delay. On all failing
> units the RNG4 gets instantiated with the default entropy delay of
> 3200. If I dial up the delay to 3600 or 4000 the RNG works reliably. As
> a negative test I changed the initial delay to 400. With this change
> all units are able to successfully instantiate the RNG handles at an
> entropy delay of 2000 or 2400, but then reliably fail at getting random
> data with the error shown above. I guess the issue is related to
> prediction resistance on the handles, which causes the PRNG to be re-
> seeded from the TRNG fairly often.
> 
> Now I don't have a good idea on how to arrive at a reliably working
> entropy delay setting, as apparently the simple "are we able to
> instantiate the handle" check is not enough to actually guarantee a
> working RNG setup. Any suggestions?
> 
The successful instantiation of the RNG state handle(s) means that
the HW self-tests passed, but this doesn't mean RNG will work flawlessly.

A properly configured RNG should have a certain (very low) failure rate.
The logic in the caam rng driver is not checking this rate, since it's running
only once with a given configuration.
OTOH properly checking the RNG configuration would take some time, so it would
be better to run it offline. The "characterization" should also account for
temperature, voltage and process (fixed for a given SoC).

>From this perspective, the caam rng driver should be updated to statically
configure the RNG with these offline-determined parameters.
Ideally we'd be able to use a single set of parameters to cover all SoCs
that have the same IP (RNG4 TRNG).
Unfortunately we're not there yet.

The situation became more visible after changing the caam rng driver to reseed
the PRNG before every request (practically making the PRNG function like a TRNG,
a hwrng framework requirement), since the HW self-tests are now running more
often then before.

Some questions that would give me more details about the exact issue you
and Robert are facing:

1. What SoC exactly are you running on?

2. How fast and how often is the RNG hardware error occurring?
Does this happen at boot time, only when stressing /dev/hwrng etc.?

3. Try dumping some of the RNG registers using below patch:

-- >8 --

Subject: [PATCH] crypto: caam - rng debugging

Dump RNG registers at hwrng.init time and in case descriptor returns
RNG HW error.

Signed-off-by: Horia Geantă <horia.geanta@xxxxxxx>
---
 drivers/crypto/caam/caamrng.c |  9 ++++++++-
 drivers/crypto/caam/ctrl.c    | 29 +++++++++++++++++++++++++++++
 drivers/crypto/caam/ctrl.h    |  2 ++
 drivers/crypto/caam/regs.h    |  5 ++++-
 4 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index 77d048dfe5d0..fc2192183696 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -16,6 +16,7 @@
 
 #include "compat.h"
 
+#include "ctrl.h"
 #include "regs.h"
 #include "intern.h"
 #include "desc_constr.h"
@@ -57,9 +58,12 @@ static void caam_rng_done(struct device *jrdev, u32 *desc, u32 err,
 {
 	struct caam_rng_job_ctx *jctx = context;
 
-	if (err)
+	if (err) {
 		*jctx->err = caam_jr_strstatus(jrdev, err);
 
+		caam_dump_rng_regs(jrdev);
+	}
+
 	complete(jctx->done);
 }
 
@@ -199,6 +203,9 @@ static int caam_init(struct hwrng *rng)
 		return err;
 	}
 
+	dev_dbg(ctx->jrdev, "CAAM RNG - register status at hwrng.init time\n");
+	caam_dump_rng_regs(ctx->jrdev);
+
 	/*
 	 * Fill async buffer to have early randomness data for
 	 * hw_random
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index ca0361b2dbb0..52db32b599aa 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -27,6 +27,35 @@ EXPORT_SYMBOL(caam_dpaa2);
 #include "qi.h"
 #endif
 
+void caam_dump_rng_regs(struct device *jrdev)
+{
+	struct device *ctrldev = jrdev->parent;
+	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+	struct caam_ctrl __iomem *ctrl;
+	struct rng4tst __iomem *r4tst;
+	u32 rtmctl;
+
+	dev_dbg(jrdev, "RNG register dump:\n");
+
+	ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
+	r4tst = &ctrl->r4tst[0];
+
+	dev_dbg(jrdev, "\trdsta = 0x%08x\n", rd_reg32(&r4tst->rdsta));
+
+	rtmctl = rd_reg32(&r4tst->rtmctl);
+	dev_dbg(jrdev, "\trtmctl = 0x%08x\n", rtmctl);
+	dev_dbg(jrdev, "\trtstatus = 0x%08x\n", rd_reg32(&r4tst->rtstatus));
+
+	/* Group of registers that can be read only when RTMCTL[PRGM]=1 */
+	clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM | RTMCTL_ACC);
+	dev_dbg(jrdev, "\trtscmisc = 0x%08x\n", rd_reg32(&r4tst->rtscmisc));
+	dev_dbg(jrdev, "\trtfrqmin = 0x%08x\n", rd_reg32(&r4tst->rtfrqmin));
+	dev_dbg(jrdev, "\trtfrqmax = 0x%08x\n", rd_reg32(&r4tst->rtfrqmax));
+	clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM | RTMCTL_ACC, RTMCTL_ERR);
+
+}
+EXPORT_SYMBOL(caam_dump_rng_regs);
+
 /*
  * Descriptor to instantiate RNG State Handle 0 in normal mode and
  * load the JDKEK, TDKEK and TDSK registers
diff --git a/drivers/crypto/caam/ctrl.h b/drivers/crypto/caam/ctrl.h
index f3ecd67922a7..806f4563990c 100644
--- a/drivers/crypto/caam/ctrl.h
+++ b/drivers/crypto/caam/ctrl.h
@@ -11,4 +11,6 @@
 /* Prototypes for backend-level services exposed to APIs */
 extern bool caam_dpaa2;
 
+void caam_dump_rng_regs(struct device *ctrldev);
+
 #endif /* CTRL_H */
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index af61f3a2c0d4..dfc25a458a55 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -493,6 +493,7 @@ struct rngtst {
 /* RNG4 TRNG test registers */
 struct rng4tst {
 #define RTMCTL_ACC  BIT(5)  /* TRNG access mode */
+#define RTMCTL_ERR  BIT(12) /* TRNG error */
 #define RTMCTL_PRGM BIT(16) /* 1 -> program mode, 0 -> run mode */
 #define RTMCTL_SAMP_MODE_VON_NEUMANN_ES_SC	0 /* use von Neumann data in
 						     both entropy shifter and
@@ -526,7 +527,9 @@ struct rng4tst {
 		u32 rtfrqmax;	/* PRGM=1: freq. count max. limit register */
 		u32 rtfrqcnt;	/* PRGM=0: freq. count register */
 	};
-	u32 rsvd1[40];
+	u32 rsvd[7];
+	u32 rtstatus;		/* TRNG status register */
+	u32 rsvd1[32];
 #define RDSTA_SKVT 0x80000000
 #define RDSTA_SKVN 0x40000000
 #define RDSTA_PR0 BIT(4)
-- 
2.17.1



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux