aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam/ctrl.c
diff options
context:
space:
mode:
authorAlex Porosanu <alexandru.porosanu@freescale.com>2013-09-09 11:56:34 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-09-13 07:43:56 -0400
commit1005bccd7a4a6345d995449b77cb1ba748ff9a28 (patch)
tree7b3dd00c93771213cf002e19280e2f422c6eee4f /drivers/crypto/caam/ctrl.c
parentf1157a5bf383bd811d27e8924543dd629a2e34c0 (diff)
crypto: caam - enable instantiation of all RNG4 state handles
RNG4 block contains multiple (i.e. 2) state handles that can be initialized. This patch adds the necessary code for detecting which of the two state handles has been instantiated by another piece of software e.g. u-boot and instantiate the other one (or both if none was instantiated). Only the state handle(s) instantiated by this driver will be deinstantiated when removing the module. Signed-off-by: Alex Porosanu <alexandru.porosanu@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/caam/ctrl.c')
-rw-r--r--drivers/crypto/caam/ctrl.c206
1 files changed, 159 insertions, 47 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 29cbec18a3a8..26438cd12685 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -17,41 +17,49 @@
17 * Descriptor to instantiate RNG State Handle 0 in normal mode and 17 * Descriptor to instantiate RNG State Handle 0 in normal mode and
18 * load the JDKEK, TDKEK and TDSK registers 18 * load the JDKEK, TDKEK and TDSK registers
19 */ 19 */
20static void build_instantiation_desc(u32 *desc) 20static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
21{ 21{
22 u32 *jump_cmd; 22 u32 *jump_cmd, op_flags;
23 23
24 init_job_desc(desc, 0); 24 init_job_desc(desc, 0);
25 25
26 op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
27 (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
28
26 /* INIT RNG in non-test mode */ 29 /* INIT RNG in non-test mode */
27 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | 30 append_operation(desc, op_flags);
28 OP_ALG_AS_INIT);
29 31
30 /* wait for done */ 32 if (!handle && do_sk) {
31 jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1); 33 /*
32 set_jump_tgt_here(desc, jump_cmd); 34 * For SH0, Secure Keys must be generated as well
35 */
33 36
34 /* 37 /* wait for done */
35 * load 1 to clear written reg: 38 jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
36 * resets the done interrupt and returns the RNG to idle. 39 set_jump_tgt_here(desc, jump_cmd);
37 */
38 append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
39 40
40 /* generate secure keys (non-test) */ 41 /*
41 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | 42 * load 1 to clear written reg:
42 OP_ALG_AAI_RNG4_SK); 43 * resets the done interrrupt and returns the RNG to idle.
44 */
45 append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
46
47 /* Initialize State Handle */
48 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
49 OP_ALG_AAI_RNG4_SK);
50 }
43 51
44 append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); 52 append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
45} 53}
46 54
47/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */ 55/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
48static void build_deinstantiation_desc(u32 *desc) 56static void build_deinstantiation_desc(u32 *desc, int handle)
49{ 57{
50 init_job_desc(desc, 0); 58 init_job_desc(desc, 0);
51 59
52 /* Uninstantiate State Handle 0 */ 60 /* Uninstantiate State Handle 0 */
53 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | 61 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
54 OP_ALG_AS_INITFINAL); 62 (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
55 63
56 append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); 64 append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
57} 65}
@@ -60,11 +68,14 @@ static void build_deinstantiation_desc(u32 *desc)
60 * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of 68 * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
61 * the software (no JR/QI used). 69 * the software (no JR/QI used).
62 * @ctrldev - pointer to device 70 * @ctrldev - pointer to device
71 * @status - descriptor status, after being run
72 *
63 * Return: - 0 if no error occurred 73 * Return: - 0 if no error occurred
64 * - -ENODEV if the DECO couldn't be acquired 74 * - -ENODEV if the DECO couldn't be acquired
65 * - -EAGAIN if an error occurred while executing the descriptor 75 * - -EAGAIN if an error occurred while executing the descriptor
66 */ 76 */
67static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc) 77static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
78 u32 *status)
68{ 79{
69 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); 80 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
70 struct caam_full __iomem *topregs; 81 struct caam_full __iomem *topregs;
@@ -113,6 +124,9 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
113 cpu_relax(); 124 cpu_relax();
114 } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); 125 } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
115 126
127 *status = rd_reg32(&topregs->deco.op_status_hi) &
128 DECO_OP_STATUS_HI_ERR_MASK;
129
116 /* Mark the DECO as free */ 130 /* Mark the DECO as free */
117 clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); 131 clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
118 132
@@ -126,6 +140,14 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
126 * instantiate_rng - builds and executes a descriptor on DECO0, 140 * instantiate_rng - builds and executes a descriptor on DECO0,
127 * which initializes the RNG block. 141 * which initializes the RNG block.
128 * @ctrldev - pointer to device 142 * @ctrldev - pointer to device
143 * @state_handle_mask - bitmask containing the instantiation status
144 * for the RNG4 state handles which exist in
145 * the RNG4 block: 1 if it's been instantiated
146 * by an external entry, 0 otherwise.
147 * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK;
148 * Caution: this can be done only once; if the keys need to be
149 * regenerated, a POR is required
150 *
129 * Return: - 0 if no error occurred 151 * Return: - 0 if no error occurred
130 * - -ENOMEM if there isn't enough memory to allocate the descriptor 152 * - -ENOMEM if there isn't enough memory to allocate the descriptor
131 * - -ENODEV if DECO0 couldn't be acquired 153 * - -ENODEV if DECO0 couldn't be acquired
@@ -133,19 +155,56 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
133 * f.i. there was a RNG hardware error due to not "good enough" 155 * f.i. there was a RNG hardware error due to not "good enough"
134 * entropy being aquired. 156 * entropy being aquired.
135 */ 157 */
136static int instantiate_rng(struct device *ctrldev) 158static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
159 int gen_sk)
137{ 160{
138 u32 *desc; 161 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
139 int ret = 0; 162 struct caam_full __iomem *topregs;
163 struct rng4tst __iomem *r4tst;
164 u32 *desc, status, rdsta_val;
165 int ret = 0, sh_idx;
166
167 topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
168 r4tst = &topregs->ctrl.r4tst[0];
140 169
141 desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL); 170 desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
142 if (!desc) 171 if (!desc)
143 return -ENOMEM; 172 return -ENOMEM;
144 /* Create the descriptor for instantiating RNG State Handle 0 */
145 build_instantiation_desc(desc);
146 173
147 /* Try to run it through DECO0 */ 174 for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
148 ret = run_descriptor_deco0(ctrldev, desc); 175 /*
176 * If the corresponding bit is set, this state handle
177 * was initialized by somebody else, so it's left alone.
178 */
179 if ((1 << sh_idx) & state_handle_mask)
180 continue;
181
182 /* Create the descriptor for instantiating RNG State Handle */
183 build_instantiation_desc(desc, sh_idx, gen_sk);
184
185 /* Try to run it through DECO0 */
186 ret = run_descriptor_deco0(ctrldev, desc, &status);
187
188 /*
189 * If ret is not 0, or descriptor status is not 0, then
190 * something went wrong. No need to try the next state
191 * handle (if available), bail out here.
192 * Also, if for some reason, the State Handle didn't get
193 * instantiated although the descriptor has finished
194 * without any error (HW optimizations for later
195 * CAAM eras), then try again.
196 */
197 rdsta_val =
198 rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK;
199 if (status || !(rdsta_val & (1 << sh_idx)))
200 ret = -EAGAIN;
201 if (ret)
202 break;
203
204 dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
205 /* Clear the contents before recreating the descriptor */
206 memset(desc, 0x00, CAAM_CMD_SZ * 7);
207 }
149 208
150 kfree(desc); 209 kfree(desc);
151 210
@@ -156,29 +215,49 @@ static int instantiate_rng(struct device *ctrldev)
156 * deinstantiate_rng - builds and executes a descriptor on DECO0, 215 * deinstantiate_rng - builds and executes a descriptor on DECO0,
157 * which deinitializes the RNG block. 216 * which deinitializes the RNG block.
158 * @ctrldev - pointer to device 217 * @ctrldev - pointer to device
218 * @state_handle_mask - bitmask containing the instantiation status
219 * for the RNG4 state handles which exist in
220 * the RNG4 block: 1 if it's been instantiated
159 * 221 *
160 * Return: - 0 if no error occurred 222 * Return: - 0 if no error occurred
161 * - -ENOMEM if there isn't enough memory to allocate the descriptor 223 * - -ENOMEM if there isn't enough memory to allocate the descriptor
162 * - -ENODEV if DECO0 couldn't be acquired 224 * - -ENODEV if DECO0 couldn't be acquired
163 * - -EAGAIN if an error occurred when executing the descriptor 225 * - -EAGAIN if an error occurred when executing the descriptor
164 */ 226 */
165static int deinstantiate_rng(struct device *ctrldev) 227static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
166{ 228{
167 u32 *desc; 229 u32 *desc, status;
168 int i, ret = 0; 230 int sh_idx, ret = 0;
169 231
170 desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL); 232 desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
171 if (!desc) 233 if (!desc)
172 return -ENOMEM; 234 return -ENOMEM;
173 235
174 /* Create the descriptor for deinstantating RNG State Handle 0 */ 236 for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
175 build_deinstantiation_desc(desc); 237 /*
176 238 * If the corresponding bit is set, then it means the state
177 /* Try to run it through DECO0 */ 239 * handle was initialized by us, and thus it needs to be
178 ret = run_descriptor_deco0(ctrldev, desc); 240 * deintialized as well
179 241 */
180 if (ret) 242 if ((1 << sh_idx) & state_handle_mask) {
181 dev_err(ctrldev, "failed to deinstantiate RNG\n"); 243 /*
244 * Create the descriptor for deinstantating this state
245 * handle
246 */
247 build_deinstantiation_desc(desc, sh_idx);
248
249 /* Try to run it through DECO0 */
250 ret = run_descriptor_deco0(ctrldev, desc, &status);
251
252 if (ret || status) {
253 dev_err(ctrldev,
254 "Failed to deinstantiate RNG4 SH%d\n",
255 sh_idx);
256 break;
257 }
258 dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
259 }
260 }
182 261
183 kfree(desc); 262 kfree(desc);
184 263
@@ -204,9 +283,9 @@ static int caam_remove(struct platform_device *pdev)
204 irq_dispose_mapping(jrpriv->irq); 283 irq_dispose_mapping(jrpriv->irq);
205 } 284 }
206 285
207 /* De-initialize RNG if it was initialized by this driver. */ 286 /* De-initialize RNG state handles initialized by this driver. */
208 if (ctrlpriv->rng4_init) 287 if (ctrlpriv->rng4_sh_init)
209 deinstantiate_rng(ctrldev); 288 deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
210 289
211 /* Shut down debug views */ 290 /* Shut down debug views */
212#ifdef CONFIG_DEBUG_FS 291#ifdef CONFIG_DEBUG_FS
@@ -306,7 +385,7 @@ EXPORT_SYMBOL(caam_get_era);
306/* Probe routine for CAAM top (controller) level */ 385/* Probe routine for CAAM top (controller) level */
307static int caam_probe(struct platform_device *pdev) 386static int caam_probe(struct platform_device *pdev)
308{ 387{
309 int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN; 388 int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
310 u64 caam_id; 389 u64 caam_id;
311 struct device *dev; 390 struct device *dev;
312 struct device_node *nprop, *np; 391 struct device_node *nprop, *np;
@@ -414,20 +493,53 @@ static int caam_probe(struct platform_device *pdev)
414 * If SEC has RNG version >= 4 and RNG state handle has not been 493 * If SEC has RNG version >= 4 and RNG state handle has not been
415 * already instantiated, do RNG instantiation 494 * already instantiated, do RNG instantiation
416 */ 495 */
417 if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 && 496 if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
418 !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) { 497 ctrlpriv->rng4_sh_init =
498 rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
499 /*
500 * If the secure keys (TDKEK, JDKEK, TDSK), were already
501 * generated, signal this to the function that is instantiating
502 * the state handles. An error would occur if RNG4 attempts
503 * to regenerate these keys before the next POR.
504 */
505 gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
506 ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
419 do { 507 do {
420 kick_trng(pdev, ent_delay); 508 int inst_handles =
421 ret = instantiate_rng(dev); 509 rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
422 ent_delay += 400; 510 RDSTA_IFMASK;
511 /*
512 * If either SH were instantiated by somebody else
513 * (e.g. u-boot) then it is assumed that the entropy
514 * parameters are properly set and thus the function
515 * setting these (kick_trng(...)) is skipped.
516 * Also, if a handle was instantiated, do not change
517 * the TRNG parameters.
518 */
519 if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
520 kick_trng(pdev, ent_delay);
521 ent_delay += 400;
522 }
523 /*
524 * if instantiate_rng(...) fails, the loop will rerun
525 * and the kick_trng(...) function will modfiy the
526 * upper and lower limits of the entropy sampling
527 * interval, leading to a sucessful initialization of
528 * the RNG.
529 */
530 ret = instantiate_rng(dev, inst_handles,
531 gen_sk);
423 } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); 532 } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
424 if (ret) { 533 if (ret) {
425 dev_err(dev, "failed to instantiate RNG"); 534 dev_err(dev, "failed to instantiate RNG");
426 caam_remove(pdev); 535 caam_remove(pdev);
427 return ret; 536 return ret;
428 } 537 }
429 538 /*
430 ctrlpriv->rng4_init = 1; 539 * Set handles init'ed by this module as the complement of the
540 * already initialized ones
541 */
542 ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
431 543
432 /* Enable RDB bit so that RNG works faster */ 544 /* Enable RDB bit so that RNG works faster */
433 setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE); 545 setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);