|
@@ -7,6 +7,7 @@
|
|
|
|
|
|
#include <common.h>
|
|
|
#include <cpu_func.h>
|
|
|
+#include <linux/kernel.h>
|
|
|
#include <log.h>
|
|
|
#include <malloc.h>
|
|
|
#include "fsl_sec.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 = ALIGN(sizeof(u32) * 2, ARCH_DMA_MINALIGN);
|
|
|
+
|
|
|
+ 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 +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
|