Skip to content

Commit 358ba76

Browse files
ndreysherbertx
authored andcommitted
crypto: caam - enable prediction resistance in HRWNG
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). 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: Andrey Smirnov <[email protected]> Signed-off-by: Andrei Botila <[email protected]> Cc: Chris Healy <[email protected]> Cc: Lucas Stach <[email protected]> Cc: Horia Geantă <[email protected]> Cc: Herbert Xu <[email protected]> Cc: Iuliana Prodan <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Reviewed-by: Horia Geantă <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 0544cb7 commit 358ba76

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

drivers/crypto/caam/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ config CRYPTO_DEV_FSL_CAAM
1313
depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE
1414
select SOC_BUS
1515
select CRYPTO_DEV_FSL_CAAM_COMMON
16+
imply FSL_MC_BUS
1617
help
1718
Enables the driver module for Freescale's Cryptographic Accelerator
1819
and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).

drivers/crypto/caam/caamrng.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ static u32 *caam_init_desc(u32 *desc, dma_addr_t dst_dma, int len)
6969
{
7070
init_job_desc(desc, 0); /* + 1 cmd_sz */
7171
/* Generate random bytes: + 1 cmd_sz */
72-
append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
72+
append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG |
73+
OP_ALG_PR_ON);
7374
/* Store bytes: + 1 cmd_sz + caam_ptr_sz */
7475
append_fifo_store(desc, dst_dma, len, FIFOST_TYPE_RNGSTORE);
7576

drivers/crypto/caam/ctrl.c

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/of_address.h>
1111
#include <linux/of_irq.h>
1212
#include <linux/sys_soc.h>
13+
#include <linux/fsl/mc.h>
1314

1415
#include "compat.h"
1516
#include "regs.h"
@@ -36,7 +37,8 @@ static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
3637
init_job_desc(desc, 0);
3738

3839
op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
39-
(handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
40+
(handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT |
41+
OP_ALG_PR_ON;
4042

4143
/* INIT RNG in non-test mode */
4244
append_operation(desc, op_flags);
@@ -278,12 +280,25 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
278280
return -ENOMEM;
279281

280282
for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
283+
const u32 rdsta_if = RDSTA_IF0 << sh_idx;
284+
const u32 rdsta_pr = RDSTA_PR0 << sh_idx;
285+
const u32 rdsta_mask = rdsta_if | rdsta_pr;
281286
/*
282287
* If the corresponding bit is set, this state handle
283288
* was initialized by somebody else, so it's left alone.
284289
*/
285-
if ((1 << sh_idx) & state_handle_mask)
286-
continue;
290+
if (rdsta_if & state_handle_mask) {
291+
if (rdsta_pr & state_handle_mask)
292+
continue;
293+
294+
dev_info(ctrldev,
295+
"RNG4 SH%d was previously instantiated without prediction resistance. Tearing it down\n",
296+
sh_idx);
297+
298+
ret = deinstantiate_rng(ctrldev, rdsta_if);
299+
if (ret)
300+
break;
301+
}
287302

288303
/* Create the descriptor for instantiating RNG State Handle */
289304
build_instantiation_desc(desc, sh_idx, gen_sk);
@@ -303,9 +318,9 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
303318
if (ret)
304319
break;
305320

306-
rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK;
321+
rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_MASK;
307322
if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) ||
308-
!(rdsta_val & (1 << sh_idx))) {
323+
(rdsta_val & rdsta_mask) != rdsta_mask) {
309324
ret = -EAGAIN;
310325
break;
311326
}
@@ -564,6 +579,26 @@ static void caam_remove_debugfs(void *root)
564579
}
565580
#endif
566581

582+
#ifdef CONFIG_FSL_MC_BUS
583+
static bool check_version(struct fsl_mc_version *mc_version, u32 major,
584+
u32 minor, u32 revision)
585+
{
586+
if (mc_version->major > major)
587+
return true;
588+
589+
if (mc_version->major == major) {
590+
if (mc_version->minor > minor)
591+
return true;
592+
593+
if (mc_version->minor == minor &&
594+
mc_version->revision > revision)
595+
return true;
596+
}
597+
598+
return false;
599+
}
600+
#endif
601+
567602
/* Probe routine for CAAM top (controller) level */
568603
static int caam_probe(struct platform_device *pdev)
569604
{
@@ -582,6 +617,7 @@ static int caam_probe(struct platform_device *pdev)
582617
u8 rng_vid;
583618
int pg_size;
584619
int BLOCK_OFFSET = 0;
620+
bool pr_support = false;
585621

586622
ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);
587623
if (!ctrlpriv)
@@ -667,17 +703,28 @@ static int caam_probe(struct platform_device *pdev)
667703

668704
/* Get the IRQ of the controller (for security violations only) */
669705
ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
706+
np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc");
707+
ctrlpriv->mc_en = !!np;
708+
of_node_put(np);
709+
710+
#ifdef CONFIG_FSL_MC_BUS
711+
if (ctrlpriv->mc_en) {
712+
struct fsl_mc_version *mc_version;
713+
714+
mc_version = fsl_mc_get_version();
715+
if (mc_version)
716+
pr_support = check_version(mc_version, 10, 20, 0);
717+
else
718+
return -EPROBE_DEFER;
719+
}
720+
#endif
670721

671722
/*
672723
* Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
673724
* long pointers in master configuration register.
674725
* In case of SoCs with Management Complex, MC f/w performs
675726
* the configuration.
676727
*/
677-
np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc");
678-
ctrlpriv->mc_en = !!np;
679-
of_node_put(np);
680-
681728
if (!ctrlpriv->mc_en)
682729
clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK,
683730
MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
@@ -784,7 +831,7 @@ static int caam_probe(struct platform_device *pdev)
784831
* already instantiated, do RNG instantiation
785832
* In case of SoCs with Management Complex, RNG is managed by MC f/w.
786833
*/
787-
if (!ctrlpriv->mc_en && rng_vid >= 4) {
834+
if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) {
788835
ctrlpriv->rng4_sh_init =
789836
rd_reg32(&ctrl->r4tst[0].rdsta);
790837
/*
@@ -794,11 +841,11 @@ static int caam_probe(struct platform_device *pdev)
794841
* to regenerate these keys before the next POR.
795842
*/
796843
gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
797-
ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
844+
ctrlpriv->rng4_sh_init &= RDSTA_MASK;
798845
do {
799846
int inst_handles =
800847
rd_reg32(&ctrl->r4tst[0].rdsta) &
801-
RDSTA_IFMASK;
848+
RDSTA_MASK;
802849
/*
803850
* If either SH were instantiated by somebody else
804851
* (e.g. u-boot) then it is assumed that the entropy
@@ -838,7 +885,7 @@ static int caam_probe(struct platform_device *pdev)
838885
* Set handles init'ed by this module as the complement of the
839886
* already initialized ones
840887
*/
841-
ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
888+
ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
842889

843890
/* Enable RDB bit so that RNG works faster */
844891
clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);

drivers/crypto/caam/desc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,8 @@
12541254
#define OP_ALG_ICV_OFF (0 << OP_ALG_ICV_SHIFT)
12551255
#define OP_ALG_ICV_ON (1 << OP_ALG_ICV_SHIFT)
12561256

1257+
#define OP_ALG_PR_ON BIT(1)
1258+
12571259
#define OP_ALG_DIR_SHIFT 0
12581260
#define OP_ALG_DIR_MASK 1
12591261
#define OP_ALG_DECRYPT 0

drivers/crypto/caam/regs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,11 @@ struct rng4tst {
524524
u32 rsvd1[40];
525525
#define RDSTA_SKVT 0x80000000
526526
#define RDSTA_SKVN 0x40000000
527+
#define RDSTA_PR0 BIT(4)
528+
#define RDSTA_PR1 BIT(5)
527529
#define RDSTA_IF0 0x00000001
528530
#define RDSTA_IF1 0x00000002
529-
#define RDSTA_IFMASK (RDSTA_IF1 | RDSTA_IF0)
531+
#define RDSTA_MASK (RDSTA_PR1 | RDSTA_PR0 | RDSTA_IF1 | RDSTA_IF0)
530532
u32 rdsta;
531533
u32 rsvd2[15];
532534
};

0 commit comments

Comments
 (0)