[PATCH v2 5/6] crypto/fsl: instantiate the RNG with prediciton resistance
Michael Walle
michael at walle.cc
Thu Jun 4 18:16:26 CEST 2020
Am 2020-06-04 17:46, schrieb Michael Walle:
> If it is already instantiated tear it down first and then reinstanciate
> it again with prediction resistance.
>
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
> drivers/crypto/fsl/desc.h | 2 ++
> drivers/crypto/fsl/jobdesc.c | 12 ++++++-
> drivers/crypto/fsl/jobdesc.h | 2 ++
> drivers/crypto/fsl/jr.c | 66 ++++++++++++++++++++++++++++++++----
> include/fsl_sec.h | 7 ++--
> 5 files changed, 78 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..14f9227b37 100644
> --- a/drivers/crypto/fsl/jr.c
> +++ b/drivers/crypto/fsl/jr.c
> @@ -446,6 +446,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) * 3;
This should be 2.
> +
> + desc = memalign(ARCH_DMA_MINALIGN, 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);
> +
> + 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 +511,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) | RDSTA_PR(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 +535,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 +608,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];
--
-michael
More information about the U-Boot
mailing list