From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heinrich Schuchardt Date: Sat, 27 Jun 2020 19:32:41 +0200 Subject: [PATCH v3 5/6] crypto/fsl: instantiate the RNG with prediciton resistance In-Reply-To: <20200625121905.4475-6-michael@walle.cc> References: <20200625121905.4475-1-michael@walle.cc> <20200625121905.4475-6-michael@walle.cc> Message-ID: <6781a942-3387-736e-d6ae-62f8b1317df5@gmx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 6/25/20 2:19 PM, Michael Walle wrote: > If it is already instantiated tear it down first and then reinstanciate > it again with prediction resistance. > > Signed-off-by: Michael Walle > --- > drivers/crypto/fsl/desc.h | 2 ++ > drivers/crypto/fsl/jobdesc.c | 12 ++++++- > drivers/crypto/fsl/jobdesc.h | 2 ++ > drivers/crypto/fsl/jr.c | 67 ++++++++++++++++++++++++++++++++---- > include/fsl_sec.h | 7 ++-- > 5 files changed, 79 insertions(+), 11 deletions(-) > > diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h > index 11ad506829..3589e6ea02 100644 > --- a/drivers/crypto/fsl/desc.h > +++ b/drivers/crypto/fsl/desc.h > @@ -520,6 +520,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 0x02 > + > #define OP_ALG_DIR_SHIFT 0 > #define OP_ALG_DIR_MASK 1 > #define OP_ALG_DECRYPT 0 > diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c > index 6102e9c06b..d9554c550b 100644 > --- a/drivers/crypto/fsl/jobdesc.c > +++ b/drivers/crypto/fsl/jobdesc.c > @@ -266,7 +266,8 @@ void inline_cnstr_jobdesc_rng_instantiation(u32 *desc, int handle, int do_sk) > > /* INIT RNG in non-test mode */ > append_operation(desc, 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); > > /* For SH0, Secure Keys must be generated as well */ > if (!handle && do_sk) { > @@ -286,6 +287,15 @@ void inline_cnstr_jobdesc_rng_instantiation(u32 *desc, int handle, int do_sk) > } > } > > +/* Descriptor for deinstantiation of the RNG block. */ > +void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle) > +{ > + init_job_desc(desc, 0); > + > + append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | > + (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL); > +} > + > /* Change key size to bytes form bits in calling function*/ > void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc, > struct pk_in_params *pkin, uint8_t *out, > diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h > index 14b2a119d7..5185ddd535 100644 > --- a/drivers/crypto/fsl/jobdesc.h > +++ b/drivers/crypto/fsl/jobdesc.h > @@ -41,6 +41,8 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr, > > void inline_cnstr_jobdesc_rng_instantiation(u32 *desc, int handle, int do_sk); > > +void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle); > + > void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc, > struct pk_in_params *pkin, uint8_t *out, > uint32_t out_siz); > diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c > index 42865a6cd7..00a3244b18 100644 > --- a/drivers/crypto/fsl/jr.c > +++ b/drivers/crypto/fsl/jr.c > @@ -9,6 +9,7 @@ > #include > #include > #include > +#include > #include "fsl_sec.h" > #include "jr.h" > #include "jobdesc.h" > @@ -446,6 +447,51 @@ int sec_reset(void) > return sec_reset_idx(0); > } > #ifndef CONFIG_SPL_BUILD > +static int deinstantiate_rng(u8 sec_idx, int state_handle_mask) > +{ > + u32 *desc; > + int sh_idx, ret = 0; > + int desc_size = sizeof(u32) * 2; > + > + desc = malloc_cache_aligned(desc_size); > + if (!desc) { > + debug("cannot allocate RNG init descriptor memory\n"); > + return -ENOMEM; > + } > + > + for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { > + /* > + * If the corresponding bit is set, then it means the state > + * handle was initialized by us, and thus it needs to be > + * deinitialized as well > + */ > + > + if (state_handle_mask & RDSTA_IF(sh_idx)) { > + /* > + * Create the descriptor for deinstantating this state > + * handle. > + */ > + inline_cnstr_jobdesc_rng_deinstantiation(desc, sh_idx); > + flush_dcache_range((unsigned long)desc, > + (unsigned long)desc + desc_size); flush_dcache_range() tests that start and stop address are multiples of CONFIG_SYS_CACHELINE_SIZE (= ARCH_DMA_MINALIGN on ARM). See check_cache_range(start, stop). So you should use ALIGN(desc_size, ARCH_DMA_MINALIGN) instead of desc_size. Best regards Heinrich > + > + ret = run_descriptor_jr_idx(desc, sec_idx); > + if (ret) { > + printf("SEC%u: RNG4 SH%d deinstantiation failed with error 0x%x\n", > + sec_idx, sh_idx, ret); > + ret = -EIO; > + break; > + } > + > + printf("SEC%u: Deinstantiated RNG4 SH%d\n", > + sec_idx, sh_idx); > + } > + } > + > + free(desc); > + return ret; > +} > + > static int instantiate_rng(u8 sec_idx, int gen_sk) > { > u32 *desc; > @@ -466,9 +512,18 @@ static int instantiate_rng(u8 sec_idx, int gen_sk) > * If the corresponding bit is set, this state handle > * was initialized by somebody else, so it's left alone. > */ > - rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; > - if (rdsta_val & (1 << sh_idx)) > - continue; > + rdsta_val = sec_in32(&rng->rdsta); > + if (rdsta_val & (RDSTA_IF(sh_idx))) { > + if (rdsta_val & RDSTA_PR(sh_idx)) > + continue; > + > + printf("SEC%u: RNG4 SH%d was instantiated w/o prediction resistance. Tearing it down\n", > + sec_idx, sh_idx); > + > + ret = deinstantiate_rng(sec_idx, RDSTA_IF(sh_idx)); > + if (ret) > + break; > + } > > inline_cnstr_jobdesc_rng_instantiation(desc, sh_idx, gen_sk); > size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN); > @@ -481,8 +536,8 @@ static int instantiate_rng(u8 sec_idx, int gen_sk) > printf("SEC%u: RNG4 SH%d instantiation failed with error 0x%x\n", > sec_idx, sh_idx, ret); > > - rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; > - if (!(rdsta_val & (1 << sh_idx))) { > + rdsta_val = sec_in32(&rng->rdsta); > + if (!(rdsta_val & RDSTA_IF(sh_idx))) { > free(desc); > return -1; > } > @@ -554,7 +609,7 @@ static int rng_init(uint8_t sec_idx) > > gen_sk = !(sec_in32(&rng->rdsta) & RDSTA_SKVN); > do { > - inst_handles = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; > + inst_handles = sec_in32(&rng->rdsta) & RDSTA_MASK; > > /* > * If either of the SH's were instantiated by somebody else > diff --git a/include/fsl_sec.h b/include/fsl_sec.h > index 64b8751f2d..1c6f1eb23e 100644 > --- a/include/fsl_sec.h > +++ b/include/fsl_sec.h > @@ -65,10 +65,9 @@ struct rng4tst { > u32 rtfreqcnt; /* PRGM=0: freq. count register */ > }; > u32 rsvd1[40]; > -#define RNG_STATE0_HANDLE_INSTANTIATED 0x00000001 > -#define RNG_STATE1_HANDLE_INSTANTIATED 0x00000002 > -#define RNG_STATE_HANDLE_MASK \ > - (RNG_STATE0_HANDLE_INSTANTIATED | RNG_STATE1_HANDLE_INSTANTIATED) > +#define RDSTA_IF(idx) (0x00000001 << (idx)) > +#define RDSTA_PR(idx) (0x00000010 << (idx)) > +#define RDSTA_MASK (RDSTA_PR(1) | RDSTA_PR(0) | RDSTA_IF(1) | RDSTA_IF(0)) > #define RDSTA_SKVN 0x40000000 > u32 rdsta; /*RNG DRNG Status Register*/ > u32 rsvd2[15]; >