aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi16
-rw-r--r--drivers/crypto/caam/Kconfig6
-rw-r--r--drivers/crypto/caam/Makefile6
-rw-r--r--drivers/crypto/caam/ctrl.c19
-rw-r--r--drivers/crypto/caam/intern.h5
-rw-r--r--drivers/crypto/caam/secvio.c335
-rw-r--r--drivers/crypto/caam/secvio.h64
-rw-r--r--drivers/crypto/caam/sm.h88
-rw-r--r--drivers/crypto/caam/sm_store.c896
-rw-r--r--drivers/crypto/caam/sm_test.c844
-rw-r--r--drivers/crypto/caam/snvsregs.h237
11 files changed, 2510 insertions, 6 deletions
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index bd6c7a0c266b..6de80a23995f 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -75,6 +75,11 @@
75 interrupt-parent = <&intc>; 75 interrupt-parent = <&intc>;
76 ranges; 76 ranges;
77 77
78 caam_sm: caam-sm@00100000 {
79 compatible = "fsl,imx6q-caam-sm";
80 reg = <0x00100000 0x3fff>;
81 };
82
78 dma_apbh: dma-apbh@00110000 { 83 dma_apbh: dma-apbh@00110000 {
79 compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; 84 compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
80 reg = <0x00110000 0x2000>; 85 reg = <0x00110000 0x2000>;
@@ -85,6 +90,12 @@
85 clocks = <&clks 106>; 90 clocks = <&clks 106>;
86 }; 91 };
87 92
93 irq_sec_vio: caam_secvio {
94 compatible = "fsl,imx6q-caam-secvio";
95 interrupts = <0 20 0x04>;
96 secvio_src = <0x8000001d>;
97 };
98
88 gpmi: gpmi-nand@00112000 { 99 gpmi: gpmi-nand@00112000 {
89 compatible = "fsl,imx6q-gpmi-nand"; 100 compatible = "fsl,imx6q-gpmi-nand";
90 #address-cells = <1>; 101 #address-cells = <1>;
@@ -606,6 +617,11 @@
606 fsl,anatop = <&anatop>; 617 fsl,anatop = <&anatop>;
607 }; 618 };
608 619
620 caam_snvs: caam-snvs@020cc000 {
621 compatible = "fsl,imx6q-caam-snvs";
622 reg = <0x020cc000 0x4000>;
623 };
624
609 snvs@020cc000 { 625 snvs@020cc000 {
610 compatible = "fsl,sec-v4.0-mon", "simple-bus"; 626 compatible = "fsl,sec-v4.0-mon", "simple-bus";
611 #address-cells = <1>; 627 #address-cells = <1>;
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig
index 493fe4073597..0df6f8c3aabe 100644
--- a/drivers/crypto/caam/Kconfig
+++ b/drivers/crypto/caam/Kconfig
@@ -107,7 +107,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST
107 Selecting this will enable self-test for caam rng. 107 Selecting this will enable self-test for caam rng.
108 108
109config CRYPTO_DEV_FSL_CAAM_SM 109config CRYPTO_DEV_FSL_CAAM_SM
110 boolean "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" 110 tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)"
111 default n 111 default n
112 help 112 help
113 Enables use of a prototype kernel-level Keystore API with CAAM 113 Enables use of a prototype kernel-level Keystore API with CAAM
@@ -130,7 +130,7 @@ config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE
130 9 => 512 bytes 130 9 => 512 bytes
131 131
132config CRYPTO_DEV_FSL_CAAM_SM_TEST 132config CRYPTO_DEV_FSL_CAAM_SM_TEST
133 boolean "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)" 133 tristate "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)"
134 depends on CRYPTO_DEV_FSL_CAAM_SM 134 depends on CRYPTO_DEV_FSL_CAAM_SM
135 default n 135 default n
136 help 136 help
@@ -139,7 +139,7 @@ config CRYPTO_DEV_FSL_CAAM_SM_TEST
139 encryption/decryption. 139 encryption/decryption.
140 140
141config CRYPTO_DEV_FSL_CAAM_SECVIO 141config CRYPTO_DEV_FSL_CAAM_SECVIO
142 boolean "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)" 142 tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)"
143 depends on CRYPTO_DEV_FSL_CAAM 143 depends on CRYPTO_DEV_FSL_CAAM
144 default n 144 default n
145 help 145 help
diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile
index b7db9e9efea5..2141ac48b163 100644
--- a/drivers/crypto/caam/Makefile
+++ b/drivers/crypto/caam/Makefile
@@ -6,8 +6,8 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
6obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o 6obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
7obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o 7obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
8obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o 8obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
9#obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o 9obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o
10#obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o 10obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o
11#obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o 11obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
12 12
13caam-objs := ctrl.o jr.o error.o key_gen.o 13caam-objs := ctrl.o jr.o error.o key_gen.o
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 5bc978e8c719..04df1863128b 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -12,6 +12,7 @@
12#include "desc_constr.h" 12#include "desc_constr.h"
13#include "error.h" 13#include "error.h"
14#include "ctrl.h" 14#include "ctrl.h"
15#include "sm.h"
15 16
16/* Used to capture the array of job rings */ 17/* Used to capture the array of job rings */
17struct device **caam_jr_dev; 18struct device **caam_jr_dev;
@@ -236,6 +237,7 @@ static int caam_probe(struct platform_device *pdev)
236 struct device_node *nprop, *np; 237 struct device_node *nprop, *np;
237 struct caam_ctrl __iomem *ctrl; 238 struct caam_ctrl __iomem *ctrl;
238 struct caam_full __iomem *topregs; 239 struct caam_full __iomem *topregs;
240 struct snvs_full __iomem *snvsregs;
239 struct caam_drv_private *ctrlpriv; 241 struct caam_drv_private *ctrlpriv;
240#ifdef CONFIG_DEBUG_FS 242#ifdef CONFIG_DEBUG_FS
241 struct caam_perfmon *perfmon; 243 struct caam_perfmon *perfmon;
@@ -265,6 +267,23 @@ static int caam_probe(struct platform_device *pdev)
265 /* Get the IRQ of the controller (for security violations only) */ 267 /* Get the IRQ of the controller (for security violations only) */
266 ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL); 268 ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
267 269
270 /* Get SNVS register Page */
271 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-snvs");
272
273 if (!np)
274 return -ENODEV;
275
276 snvsregs = of_iomap(np, 0);
277 ctrlpriv->snvs = snvsregs;
278 /* Get CAAM-SM node and of_iomap() and save */
279 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
280
281 if (!np)
282 return -ENODEV;
283
284 ctrlpriv->sm_base = of_iomap(np, 0);
285 ctrlpriv->sm_size = 0x3fff;
286
268/* 287/*
269 * ARM targets tend to have clock control subsystems that can 288 * ARM targets tend to have clock control subsystems that can
270 * enable/disable clocking to our device. Turn clocking on to proceed 289 * enable/disable clocking to our device. Turn clocking on to proceed
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 0311f8572822..6bb12f3098fe 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -70,6 +70,8 @@ struct caam_drv_private_jr {
70struct caam_drv_private { 70struct caam_drv_private {
71 71
72 struct device *dev; 72 struct device *dev;
73 struct device *smdev;
74 struct device *secviodev;
73 struct device **jrdev; /* Alloc'ed array per sub-device */ 75 struct device **jrdev; /* Alloc'ed array per sub-device */
74 spinlock_t jr_alloc_lock; 76 spinlock_t jr_alloc_lock;
75 struct platform_device *pdev; 77 struct platform_device *pdev;
@@ -79,6 +81,9 @@ struct caam_drv_private {
79 struct caam_deco **deco; /* DECO/CCB views */ 81 struct caam_deco **deco; /* DECO/CCB views */
80 struct caam_assurance *ac; 82 struct caam_assurance *ac;
81 struct caam_queue_if *qi; /* QI control region */ 83 struct caam_queue_if *qi; /* QI control region */
84 struct snvs_full __iomem *snvs; /* SNVS HP+LP register space */
85 dma_addr_t __iomem *sm_base; /* Secure memory storage base */
86 u32 sm_size;
82 87
83 /* 88 /*
84 * Detected geometry block. Filled in from device tree if powerpc, 89 * Detected geometry block. Filled in from device tree if powerpc,
diff --git a/drivers/crypto/caam/secvio.c b/drivers/crypto/caam/secvio.c
new file mode 100644
index 000000000000..defd93cb8887
--- /dev/null
+++ b/drivers/crypto/caam/secvio.c
@@ -0,0 +1,335 @@
1
2/*
3 * CAAM/SEC 4.x Security Violation Handler
4 * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
5 */
6
7#include "compat.h"
8#include "intern.h"
9#include "secvio.h"
10#include "regs.h"
11
12/*
13 * These names are associated with each violation handler.
14 * The source names were taken from MX6, and are based on recommendations
15 * for most common SoCs.
16 */
17static const u8 *violation_src_name[] = {
18 "CAAM Security Violation",
19 "JTAG Alarm",
20 "Watchdog",
21 "(reserved)",
22 "External Boot",
23 "Tamper Detect",
24};
25
26/* Top-level security violation interrupt */
27static irqreturn_t caam_secvio_interrupt(int irq, void *snvsdev)
28{
29 struct device *dev = snvsdev;
30 struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
31 u32 irqstate;
32
33 /* Check the HP secvio status register */
34 irqstate = rd_reg32(&svpriv->svregs->hp.secvio_status) |
35 HP_SECVIOST_SECVIOMASK;
36
37 if (!irqstate)
38 return IRQ_NONE;
39
40 /* Mask out one or more causes for deferred service */
41 clrbits32(&svpriv->svregs->hp.secvio_int_ctl, irqstate);
42
43 /* Now ACK causes */
44 setbits32(&svpriv->svregs->hp.secvio_status, irqstate);
45
46 /* And run deferred service */
47 preempt_disable();
48 tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
49 preempt_enable();
50
51 return IRQ_HANDLED;
52}
53
54/* Deferred service handler. Tasklet arg is simply the SNVS dev */
55static void caam_secvio_dispatch(unsigned long indev)
56{
57 struct device *dev = (struct device *)indev;
58 struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
59 unsigned long flags, cause;
60 int i;
61
62
63 /*
64 * Capture the interrupt cause, using masked interrupts as
65 * identification. This only works if all are enabled; if
66 * this changes in the future, a "cause queue" will have to
67 * be built
68 */
69 cause = rd_reg32(&svpriv->svregs->hp.secvio_int_ctl) &
70 (HP_SECVIO_INTEN_SRC5 | HP_SECVIO_INTEN_SRC4 |
71 HP_SECVIO_INTEN_SRC3 | HP_SECVIO_INTEN_SRC2 |
72 HP_SECVIO_INTEN_SRC1 | HP_SECVIO_INTEN_SRC0);
73
74 /* Look through causes, call each handler if exists */
75 for (i = 0; i < MAX_SECVIO_SOURCES; i++)
76 if (cause & (1 << i)) {
77 spin_lock_irqsave(&svpriv->svlock, flags);
78 svpriv->intsrc[i].handler(dev, i,
79 svpriv->intsrc[i].ext);
80 spin_unlock_irqrestore(&svpriv->svlock, flags);
81 };
82
83 /* Re-enable now-serviced interrupts */
84 setbits32(&svpriv->svregs->hp.secvio_int_ctl, cause);
85}
86
87/*
88 * Default cause handler, used in lieu of an application-defined handler.
89 * All it does at this time is print a console message. It could force a halt.
90 */
91static void caam_secvio_default(struct device *dev, u32 cause, void *ext)
92{
93 struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
94
95 dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
96 cause, svpriv->intsrc[cause].intname);
97}
98
99/*
100 * Install an application-defined handler for a specified cause
101 * Arguments:
102 * - dev points to SNVS-owning device
103 * - cause interrupt source cause
104 * - handler application-defined handler, gets called with dev
105 * source cause, and locally-defined handler argument
106 * - cause_description points to a string to override the default cause
107 * name, this can be used as an alternate for error
108 * messages and such. If left NULL, the default
109 * description string is used.
110 * - ext pointer to any extra data needed by the handler.
111 */
112int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
113 void (*handler)(struct device *dev, u32 cause,
114 void *ext),
115 u8 *cause_description, void *ext)
116{
117 unsigned long flags;
118 struct caam_drv_private_secvio *svpriv;
119
120 svpriv = dev_get_drvdata(dev);
121
122 if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
123 return -EINVAL;
124
125 spin_lock_irqsave(&svpriv->svlock, flags);
126 svpriv->intsrc[cause].handler = handler;
127 if (cause_description != NULL)
128 svpriv->intsrc[cause].intname = cause_description;
129 if (ext != NULL)
130 svpriv->intsrc[cause].ext = ext;
131 spin_unlock_irqrestore(&svpriv->svlock, flags);
132
133 return 0;
134}
135EXPORT_SYMBOL(caam_secvio_install_handler);
136
137/*
138 * Remove an application-defined handler for a specified cause (and, by
139 * implication, restore the "default".
140 * Arguments:
141 * - dev points to SNVS-owning device
142 * - cause interrupt source cause
143 */
144int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
145{
146 unsigned long flags;
147 struct caam_drv_private_secvio *svpriv;
148
149 svpriv = dev_get_drvdata(dev);
150
151 if (cause > SECVIO_CAUSE_SOURCE_5)
152 return -EINVAL;
153
154 spin_lock_irqsave(&svpriv->svlock, flags);
155 svpriv->intsrc[cause].intname = violation_src_name[cause];
156 svpriv->intsrc[cause].handler = caam_secvio_default;
157 svpriv->intsrc[cause].ext = NULL;
158 spin_unlock_irqrestore(&svpriv->svlock, flags);
159 return 0;
160}
161EXPORT_SYMBOL(caam_secvio_remove_handler);
162
163int caam_secvio_startup(struct platform_device *pdev)
164{
165 struct device *ctrldev, *svdev;
166 struct caam_drv_private *ctrlpriv;
167 struct caam_drv_private_secvio *svpriv;
168 struct platform_device *svpdev;
169 struct device_node *np;
170 const void *prop;
171 int i, error, secvio_inten_src;
172
173 ctrldev = &pdev->dev;
174 ctrlpriv = dev_get_drvdata(ctrldev);
175 /*
176 * Set up the private block for secure memory
177 * Only one instance is possible
178 */
179 svpriv = kzalloc(sizeof(struct caam_drv_private_secvio), GFP_KERNEL);
180 if (svpriv == NULL) {
181 dev_err(ctrldev, "can't alloc private mem for secvio\n");
182 return -ENOMEM;
183 }
184 svpriv->parentdev = ctrldev;
185
186 /* Create the security violation dev */
187#ifdef CONFIG_OF
188
189 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
190 if (!np)
191 return -ENODEV;
192
193 ctrlpriv->secvio_irq = of_irq_to_resource(np, 0, NULL);
194
195 prop = of_get_property(np, "secvio_src", NULL);
196 if (prop)
197 secvio_inten_src = of_read_ulong(prop, 1);
198 else
199 secvio_inten_src = HP_SECVIO_INTEN_ALL;
200
201 printk(KERN_ERR "secvio_inten_src = %x\n", secvio_inten_src);
202
203 svpdev = of_platform_device_create(np, NULL, ctrldev);
204 if (!svpdev)
205 return -ENODEV;
206
207#else
208 svpdev = platform_device_register_data(ctrldev, "caam_secvio", 0,
209 svpriv,
210 sizeof(struct caam_drv_private_secvio));
211
212 secvio_inten_src = HP_SECVIO_INTEN_ALL;
213#endif
214 if (svpdev == NULL) {
215 kfree(svpriv);
216 return -EINVAL;
217 }
218 svdev = &svpdev->dev;
219 dev_set_drvdata(svdev, svpriv);
220 ctrlpriv->secviodev = svdev;
221 svpriv->svregs = ctrlpriv->snvs;
222
223 /*
224 * Now we have all the dev data set up. Init interrupt
225 * source descriptions
226 */
227 for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
228 svpriv->intsrc[i].intname = violation_src_name[i];
229 svpriv->intsrc[i].handler = caam_secvio_default;
230 }
231
232 /* Connect main handler */
233 for_each_possible_cpu(i)
234 tasklet_init(&svpriv->irqtask[i], caam_secvio_dispatch,
235 (unsigned long)svdev);
236
237 error = request_irq(ctrlpriv->secvio_irq, caam_secvio_interrupt,
238 IRQF_SHARED, "caam_secvio", svdev);
239 if (error) {
240 dev_err(svdev, "can't connect secvio interrupt\n");
241 irq_dispose_mapping(ctrlpriv->secvio_irq);
242 ctrlpriv->secvio_irq = 0;
243 return -EINVAL;
244 }
245
246 /* Enable all sources */
247 wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, secvio_inten_src);
248
249 dev_info(svdev, "security violation service handlers armed\n");
250
251 return 0;
252}
253
254void caam_secvio_shutdown(struct platform_device *pdev)
255{
256 struct device *ctrldev, *svdev;
257 struct caam_drv_private *priv;
258 struct caam_drv_private_secvio *svpriv;
259 int i;
260
261 ctrldev = &pdev->dev;
262 priv = dev_get_drvdata(ctrldev);
263 svdev = priv->secviodev;
264 svpriv = dev_get_drvdata(svdev);
265
266 /* Shut off all sources */
267
268 wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, 0);
269
270 /* Remove tasklets and release interrupt */
271 for_each_possible_cpu(i)
272 tasklet_kill(&svpriv->irqtask[i]);
273
274 free_irq(priv->secvio_irq, svdev);
275
276 kfree(svpriv);
277}
278
279
280#ifdef CONFIG_OF
281static void __exit caam_secvio_exit(void)
282{
283 struct device_node *dev_node;
284 struct platform_device *pdev;
285
286 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
287 if (!dev_node) {
288 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
289 if (!dev_node)
290 return;
291 }
292
293 pdev = of_find_device_by_node(dev_node);
294 if (!pdev)
295 return;
296
297 of_node_get(dev_node);
298
299 caam_secvio_shutdown(pdev);
300
301}
302
303static int __init caam_secvio_init(void)
304{
305 struct device_node *dev_node;
306 struct platform_device *pdev;
307
308 /*
309 * Do of_find_compatible_node() then of_find_device_by_node()
310 * once a functional device tree is available
311 */
312 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
313 if (!dev_node) {
314 dev_node = of_find_compatible_node(NULL, NULL,
315 "arm,imx6-caam-secvio");
316 if (!dev_node)
317 return -ENODEV;
318 }
319
320 pdev = of_find_device_by_node(dev_node);
321 if (!pdev)
322 return -ENODEV;
323
324 of_node_put(dev_node);
325
326 return caam_secvio_startup(pdev);
327}
328
329module_init(caam_secvio_init);
330module_exit(caam_secvio_exit);
331
332MODULE_LICENSE("Dual BSD/GPL");
333MODULE_DESCRIPTION("FSL CAAM/SNVS Security Violation Handler");
334MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
335#endif
diff --git a/drivers/crypto/caam/secvio.h b/drivers/crypto/caam/secvio.h
new file mode 100644
index 000000000000..b0efe20bdc5d
--- /dev/null
+++ b/drivers/crypto/caam/secvio.h
@@ -0,0 +1,64 @@
1
2/*
3 * CAAM Security Violation Handler
4 * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
5 */
6
7#ifndef SECVIO_H
8#define SECVIO_H
9
10#include "snvsregs.h"
11
12
13/*
14 * Defines the published interfaces to install/remove application-specified
15 * handlers for catching violations
16 */
17
18#define MAX_SECVIO_SOURCES 6
19
20/* these are the untranslated causes */
21enum secvio_cause {
22 SECVIO_CAUSE_SOURCE_0,
23 SECVIO_CAUSE_SOURCE_1,
24 SECVIO_CAUSE_SOURCE_2,
25 SECVIO_CAUSE_SOURCE_3,
26 SECVIO_CAUSE_SOURCE_4,
27 SECVIO_CAUSE_SOURCE_5
28};
29
30/* These are common "recommended" cause definitions for most devices */
31#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
32#define SECVIO_CAUSE JTAG_ALARM SECVIO_CAUSE_SOURCE_1
33#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
34#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
35#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
36
37int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
38 void (*handler)(struct device *dev, u32 cause,
39 void *ext),
40 u8 *cause_description, void *ext);
41int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
42
43/*
44 * Private data definitions for the secvio "driver"
45 */
46
47struct secvio_int_src {
48 const u8 *intname; /* Points to a descriptive name for source */
49 void *ext; /* Extended data to pass to the handler */
50 void (*handler)(struct device *dev, u32 cause, void *ext);
51};
52
53struct caam_drv_private_secvio {
54 struct device *parentdev; /* points back to the controller */
55 spinlock_t svlock ____cacheline_aligned;
56 struct tasklet_struct irqtask[NR_CPUS];
57 struct snvs_full __iomem *svregs; /* both HP and LP domains */
58
59 /* Registered handlers for each violation */
60 struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
61
62};
63
64#endif /* SECVIO_H */
diff --git a/drivers/crypto/caam/sm.h b/drivers/crypto/caam/sm.h
new file mode 100644
index 000000000000..88dc0cd93d79
--- /dev/null
+++ b/drivers/crypto/caam/sm.h
@@ -0,0 +1,88 @@
1
2/*
3 * CAAM Secure Memory/Keywrap API Definitions
4 * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
5 */
6
7#ifndef SM_H
8#define SM_H
9
10
11/* Storage access permissions */
12#define SM_PERM_READ 0x01
13#define SM_PERM_WRITE 0x02
14#define SM_PERM_BLOB 0x03
15
16
17/* Keystore maintenance functions */
18void sm_init_keystore(struct device *dev);
19u32 sm_detect_keystore_units(struct device *dev);
20int sm_establish_keystore(struct device *dev, u32 unit);
21void sm_release_keystore(struct device *dev, u32 unit);
22void caam_sm_shutdown(struct platform_device *pdev);
23int caam_sm_example_init(struct platform_device *pdev);
24
25/* Keystore accessor functions */
26extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
27 u32 *slot);
28extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
29extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
30 const u8 *key_data, u32 key_length);
31extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
32 u32 key_length, u8 *key_data);
33extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
34 u32 inslot, u32 outslot, u16 secretlen,
35 u8 *keymod, u16 keymodlen);
36extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
37 u32 inslot, u32 outslot, u16 secretlen,
38 u8 *keymod, u16 keymodlen);
39
40/* Data structure to hold per-slot information */
41struct keystore_data_slot_info {
42 u8 allocated; /* Track slot assignments */
43 u32 key_length; /* Size of the key */
44};
45
46/* Data structure to hold keystore information */
47struct keystore_data {
48 void *base_address; /* Base of the Secure Partition */
49 u32 slot_count; /* Number of slots in the keystore */
50 struct keystore_data_slot_info *slot; /* Per-slot information */
51};
52
53/* store the detected attributes of a secure memory page */
54struct sm_page_descriptor {
55 u16 phys_pagenum; /* may be discontiguous */
56 u16 own_part; /* Owning partition */
57 void *pg_base; /* Calculated virtual address */
58 struct keystore_data *ksdata;
59};
60
61struct caam_drv_private_sm {
62 struct device *parentdev; /* this ends up as the controller */
63 struct device *smringdev; /* ring that owns this instance */
64 spinlock_t kslock ____cacheline_aligned;
65
66 /* Default parameters for geometry */
67 u32 max_pages; /* maximum pages this instance can support */
68 u32 top_partition; /* highest partition number in this instance */
69 u32 top_page; /* highest page number in this instance */
70 u32 page_size; /* page size */
71 u32 slot_size; /* selected size of each storage block */
72
73 /* Partition/Page Allocation Map */
74 u32 localpages; /* Number of pages we can access */
75 struct sm_page_descriptor *pagedesc; /* Allocated per-page */
76
77 /* Installed handlers for keystore access */
78 int (*data_init)(struct device *dev, u32 unit);
79 void (*data_cleanup)(struct device *dev, u32 unit);
80 int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
81 int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
82 void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
83 u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
84 u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
85 u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
86};
87
88#endif /* SM_H */
diff --git a/drivers/crypto/caam/sm_store.c b/drivers/crypto/caam/sm_store.c
new file mode 100644
index 000000000000..6e63aa3807e5
--- /dev/null
+++ b/drivers/crypto/caam/sm_store.c
@@ -0,0 +1,896 @@
1
2/*
3 * CAAM Secure Memory Storage Interface
4 * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
5 *
6 * Loosely based on the SHW Keystore API for SCC/SCC2
7 * Experimental implementation and NOT intended for upstream use. Expect
8 * this interface to be amended significantly in the future once it becomes
9 * integrated into live applications.
10 *
11 * Known issues:
12 *
13 * - Executes one instance of an secure memory "driver". This is tied to the
14 * fact that job rings can't run as standalone instances in the present
15 * configuration.
16 *
17 * - It does not expose a userspace interface. The value of a userspace
18 * interface for access to secrets is a point for further architectural
19 * discussion.
20 *
21 * - Partition/permission management is not part of this interface. It
22 * depends on some level of "knowledge" agreed upon between bootloader,
23 * provisioning applications, and OS-hosted software (which uses this
24 * driver).
25 *
26 * - No means of identifying the location or purpose of secrets managed by
27 * this interface exists; "slot location" and format of a given secret
28 * needs to be agreed upon between bootloader, provisioner, and OS-hosted
29 * application.
30 */
31
32#include "compat.h"
33#include "regs.h"
34#include "jr.h"
35#include "desc.h"
36#include "intern.h"
37#include "error.h"
38#include "sm.h"
39
40#ifdef SM_DEBUG_CONT
41void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
42{
43 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
44 u32 i, *smdata;
45
46 dev_info(dev, "physical page %d content at 0x%08x\n",
47 pgdesc->phys_pagenum, pgdesc->pg_base);
48 smdata = pgdesc->pg_base;
49 for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
50 dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
51 (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
52 smdata[i+3]);
53}
54#endif
55
56/*
57 * Construct a secure memory blob encapsulation job descriptor
58 *
59 * - desc pointer to hold new (to be allocated) pointer to the generated
60 * descriptor for later use. Calling thread can kfree the
61 * descriptor after execution.
62 * - keymod Physical pointer to key modifier (contiguous piece).
63 * - keymodsz Size of key modifier in bytes (should normally be 8).
64 * - secretbuf Physical pointer (within an accessible secure memory page)
65 * of the secret to be encapsulated.
66 * - outbuf Physical pointer (within an accessible secure memory page)
67 * of the encapsulated output. This will be larger than the
68 * input secret because of the added encapsulation data.
69 * - secretsz Size of input secret, in bytes.
70 * - auth If nonzero, use AES-CCM for encapsulation, else use ECB
71 *
72 * Note: this uses 32-bit pointers at present
73 */
74#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
75static int blob_encap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
76 dma_addr_t secretbuf, dma_addr_t outbuf,
77 u16 secretsz, bool auth)
78{
79 u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
80 u16 dsize, idx;
81
82 memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
83 idx = 1;
84
85 /* Load key modifier */
86 tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
87 ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
88 (keymodsz & LDST_LEN_MASK);
89
90 tmpdesc[idx++] = (u32)keymod;
91
92 /* Encapsulate to secure memory */
93 tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
94 tmpdesc[idx++] = (u32)secretbuf;
95
96 /* Add space for BKEK and MAC tag */
97 tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + (32 + 16));
98
99 tmpdesc[idx++] = (u32)outbuf;
100 tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
101 OP_PCL_BLOB_PTXT_SECMEM;
102 if (auth)
103 tmpdesc[idx] |= OP_PCL_BLOB_EKT;
104
105 idx++;
106 tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
107 dsize = idx * sizeof(u32);
108
109 tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
110 if (tdesc == NULL)
111 return 0;
112
113 memcpy(tdesc, tmpdesc, dsize);
114 *desc = tdesc;
115 return dsize;
116}
117
118/*
119 * Construct a secure memory blob decapsulation job descriptor
120 *
121 * - desc pointer to hold new (to be allocated) pointer to the generated
122 * descriptor for later use. Calling thread can kfree the
123 * descriptor after execution.
124 * - keymod Physical pointer to key modifier (contiguous piece).
125 * - keymodsz Size of key modifier in bytes (should normally be 16).
126 * - blobbuf Physical pointer (within an accessible secure memory page)
127 * of the blob to be decapsulated.
128 * - outbuf Physical pointer (within an accessible secure memory page)
129 * of the decapsulated output.
130 * - secretsz Size of input blob, in bytes.
131 * - auth If nonzero, assume AES-CCM for decapsulation, else use ECB
132 *
133 * Note: this uses 32-bit pointers at present
134 */
135static int blob_decap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
136 dma_addr_t blobbuf, dma_addr_t outbuf,
137 u16 blobsz, bool auth)
138{
139 u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
140 u16 dsize, idx;
141
142 memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
143 idx = 1;
144
145 /* Load key modifier */
146 tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
147 ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
148 (keymodsz & LDST_LEN_MASK);
149
150 tmpdesc[idx++] = (u32)keymod;
151
152 /* Compensate BKEK + MAC tag */
153 tmpdesc[idx++] = CMD_SEQ_IN_PTR | (blobsz + 32 + 16);
154
155 tmpdesc[idx++] = (u32)blobbuf;
156 tmpdesc[idx++] = CMD_SEQ_OUT_PTR | blobsz;
157 tmpdesc[idx++] = (u32)outbuf;
158
159 /* Decapsulate from secure memory partition to black blob */
160 tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB |
161 OP_PCL_BLOB_PTXT_SECMEM | OP_PCL_BLOB_BLACK;
162 if (auth)
163 tmpdesc[idx] |= OP_PCL_BLOB_EKT;
164
165 idx++;
166 tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
167 dsize = idx * sizeof(u32);
168
169 tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
170 if (tdesc == NULL)
171 return 0;
172
173 memcpy(tdesc, tmpdesc, dsize);
174 *desc = tdesc;
175 return dsize;
176}
177
178/*
179 * Pseudo-synchronous ring access functions for carrying out key
180 * encapsulation and decapsulation
181 */
182
183struct sm_key_job_result {
184 int error;
185 struct completion completion;
186};
187
188void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context)
189{
190 struct sm_key_job_result *res = context;
191
192 res->error = err; /* save off the error for postprocessing */
193 complete(&res->completion); /* mark us complete */
194}
195
196static int sm_key_job(struct device *ksdev, u32 *jobdesc)
197{
198 struct sm_key_job_result testres;
199 struct caam_drv_private_sm *kspriv;
200 int rtn = 0;
201
202 kspriv = dev_get_drvdata(ksdev);
203
204 init_completion(&testres.completion);
205
206 rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done,
207 &testres);
208 if (!rtn) {
209 wait_for_completion_interruptible(&testres.completion);
210 rtn = testres.error;
211 }
212 return rtn;
213}
214
215/*
216 * Following section establishes the default methods for keystore access
217 * They are NOT intended for use external to this module
218 *
219 * In the present version, these are the only means for the higher-level
220 * interface to deal with the mechanics of accessing the phyiscal keystore
221 */
222
223
224int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
225{
226 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
227 struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
228 u32 i;
229#ifdef SM_DEBUG
230 dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size);
231#endif
232
233 if (size > smpriv->slot_size)
234 return -EKEYREJECTED;
235
236 for (i = 0; i < ksdata->slot_count; i++) {
237 if (ksdata->slot[i].allocated == 0) {
238 ksdata->slot[i].allocated = 1;
239 (*slot) = i;
240#ifdef SM_DEBUG
241 dev_info(dev, "slot_alloc(): new slot %d allocated\n",
242 *slot);
243#endif
244 return 0;
245 }
246 }
247
248 return -ENOSPC;
249}
250EXPORT_SYMBOL(slot_alloc);
251
252int slot_dealloc(struct device *dev, u32 unit, u32 slot)
253{
254 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
255 struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
256 u8 __iomem *slotdata;
257
258#ifdef SM_DEBUG
259 dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot);
260#endif
261 if (slot >= ksdata->slot_count)
262 return -EINVAL;
263 slotdata = ksdata->base_address + slot * smpriv->slot_size;
264
265 if (ksdata->slot[slot].allocated == 1) {
266 /* Forcibly overwrite the data from the keystore */
267 memset(ksdata->base_address + slot * smpriv->slot_size, 0,
268 smpriv->slot_size);
269
270 ksdata->slot[slot].allocated = 0;
271#ifdef SM_DEBUG
272 dev_info(dev, "slot_dealloc(): slot %d released\n", slot);
273#endif
274 return 0;
275 }
276
277 return -EINVAL;
278}
279EXPORT_SYMBOL(slot_dealloc);
280
281void *slot_get_address(struct device *dev, u32 unit, u32 slot)
282{
283 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
284 struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
285
286 if (slot >= ksdata->slot_count)
287 return NULL;
288
289#ifdef SM_DEBUG
290 dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot,
291 (u32)ksdata->base_address + slot * smpriv->slot_size);
292#endif
293
294 return ksdata->base_address + slot * smpriv->slot_size;
295}
296
297u32 slot_get_base(struct device *dev, u32 unit, u32 slot)
298{
299 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
300 struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
301
302 /*
303 * There could potentially be more than one secure partition object
304 * associated with this keystore. For now, there is just one.
305 */
306
307 (void)slot;
308
309#ifdef SM_DEBUG
310 dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n",
311 slot, (u32)ksdata->base_address);
312#endif
313
314 return (u32)(ksdata->base_address);
315}
316
317u32 slot_get_offset(struct device *dev, u32 unit, u32 slot)
318{
319 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
320 struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
321
322 if (slot >= ksdata->slot_count)
323 return -EINVAL;
324
325#ifdef SM_DEBUG
326 dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot,
327 slot * smpriv->slot_size);
328#endif
329
330 return slot * smpriv->slot_size;
331}
332
333u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot)
334{
335 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
336
337
338#ifdef SM_DEBUG
339 dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot,
340 smpriv->slot_size);
341#endif
342 /* All slots are the same size in the default implementation */
343 return smpriv->slot_size;
344}
345
346
347
348int kso_init_data(struct device *dev, u32 unit)
349{
350 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
351 int retval = -EINVAL;
352 struct keystore_data *keystore_data = NULL;
353 u32 slot_count;
354 u32 keystore_data_size;
355
356 /*
357 * Calculate the required size of the keystore data structure, based
358 * on the number of keys that can fit in the partition.
359 */
360 slot_count = smpriv->page_size / smpriv->slot_size;
361#ifdef SM_DEBUG
362 dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count);
363#endif
364
365 keystore_data_size = sizeof(struct keystore_data) +
366 slot_count *
367 sizeof(struct keystore_data_slot_info);
368
369 keystore_data = kzalloc(keystore_data_size, GFP_KERNEL);
370
371 if (keystore_data == NULL) {
372 retval = -ENOSPC;
373 goto out;
374 }
375
376#ifdef SM_DEBUG
377 dev_info(dev, "kso_init_data: keystore data size = %d\n",
378 keystore_data_size);
379#endif
380
381 /*
382 * Place the slot information structure directly after the keystore data
383 * structure.
384 */
385 keystore_data->slot = (struct keystore_data_slot_info *)
386 (keystore_data + 1);
387 keystore_data->slot_count = slot_count;
388
389 smpriv->pagedesc[unit].ksdata = keystore_data;
390 smpriv->pagedesc[unit].ksdata->base_address =
391 smpriv->pagedesc[unit].pg_base;
392
393 retval = 0;
394
395out:
396 if (retval != 0)
397 if (keystore_data != NULL)
398 kfree(keystore_data);
399
400
401 return retval;
402}
403
404void kso_cleanup_data(struct device *dev, u32 unit)
405{
406 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
407 struct keystore_data *keystore_data = NULL;
408
409 if (smpriv->pagedesc[unit].ksdata != NULL)
410 keystore_data = smpriv->pagedesc[unit].ksdata;
411
412 /* Release the allocated keystore management data */
413 kfree(smpriv->pagedesc[unit].ksdata);
414
415 return;
416}
417
418
419
420/*
421 * Keystore management section
422 */
423
424void sm_init_keystore(struct device *dev)
425{
426 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
427
428 smpriv->data_init = kso_init_data;
429 smpriv->data_cleanup = kso_cleanup_data;
430 smpriv->slot_alloc = slot_alloc;
431 smpriv->slot_dealloc = slot_dealloc;
432 smpriv->slot_get_address = slot_get_address;
433 smpriv->slot_get_base = slot_get_base;
434 smpriv->slot_get_offset = slot_get_offset;
435 smpriv->slot_get_slot_size = slot_get_slot_size;
436#ifdef SM_DEBUG
437 dev_info(dev, "sm_init_keystore(): handlers installed\n");
438#endif
439}
440EXPORT_SYMBOL(sm_init_keystore);
441
442/* Return available pages/units */
443u32 sm_detect_keystore_units(struct device *dev)
444{
445 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
446
447 return smpriv->localpages;
448}
449EXPORT_SYMBOL(sm_detect_keystore_units);
450
451/*
452 * Do any keystore specific initializations
453 */
454int sm_establish_keystore(struct device *dev, u32 unit)
455{
456 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
457
458#ifdef SM_DEBUG
459 dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit);
460#endif
461
462 if (smpriv->data_init == NULL)
463 return -EINVAL;
464
465 /* Call the data_init function for any user setup */
466 return smpriv->data_init(dev, unit);
467}
468EXPORT_SYMBOL(sm_establish_keystore);
469
470void sm_release_keystore(struct device *dev, u32 unit)
471{
472 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
473
474#ifdef SM_DEBUG
475 dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit);
476#endif
477 if ((smpriv != NULL) && (smpriv->data_cleanup != NULL))
478 smpriv->data_cleanup(dev, unit);
479
480 return;
481}
482EXPORT_SYMBOL(sm_release_keystore);
483
484/*
485 * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to
486 * the keystore
487 */
488int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
489{
490 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
491 int retval = -EINVAL;
492
493 spin_lock(&smpriv->kslock);
494
495 if ((smpriv->slot_alloc == NULL) ||
496 (smpriv->pagedesc[unit].ksdata == NULL))
497 goto out;
498
499 retval = smpriv->slot_alloc(dev, unit, size, slot);
500
501out:
502 spin_unlock(&smpriv->kslock);
503 return retval;
504}
505EXPORT_SYMBOL(sm_keystore_slot_alloc);
506
507int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot)
508{
509 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
510 int retval = -EINVAL;
511
512 spin_lock(&smpriv->kslock);
513
514 if ((smpriv->slot_alloc == NULL) ||
515 (smpriv->pagedesc[unit].ksdata == NULL))
516 goto out;
517
518 retval = smpriv->slot_dealloc(dev, unit, slot);
519out:
520 spin_unlock(&smpriv->kslock);
521 return retval;
522}
523EXPORT_SYMBOL(sm_keystore_slot_dealloc);
524
525int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
526 const u8 *key_data, u32 key_length)
527{
528 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
529 int retval = -EINVAL;
530 u32 slot_size;
531 u32 i;
532 u8 __iomem *slot_location;
533
534 spin_lock(&smpriv->kslock);
535
536 slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
537
538 if (key_length > slot_size) {
539 retval = -EFBIG;
540 goto out;
541 }
542
543 slot_location = smpriv->slot_get_address(dev, unit, slot);
544
545 for (i = 0; i < key_length; i++)
546 slot_location[i] = key_data[i];
547
548 retval = 0;
549
550out:
551 spin_unlock(&smpriv->kslock);
552 return retval;
553}
554EXPORT_SYMBOL(sm_keystore_slot_load);
555
556int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
557 u32 key_length, u8 *key_data)
558{
559 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
560 int retval = -EINVAL;
561 u8 __iomem *slot_addr;
562 u32 slot_size;
563
564 spin_lock(&smpriv->kslock);
565
566 slot_addr = smpriv->slot_get_address(dev, unit, slot);
567 slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
568
569 if (key_length > slot_size) {
570 retval = -EKEYREJECTED;
571 goto out;
572 }
573
574 memcpy(key_data, slot_addr, key_length);
575 retval = 0;
576
577out:
578 spin_unlock(&smpriv->kslock);
579 return retval;
580}
581EXPORT_SYMBOL(sm_keystore_slot_read);
582
583int sm_keystore_slot_encapsulate(struct device *dev, u32 unit, u32 inslot,
584 u32 outslot, u16 secretlen, u8 *keymod,
585 u16 keymodlen)
586{
587 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
588 int retval = 0;
589 u32 slot_length, dsize, jstat;
590 u32 __iomem *encapdesc = NULL;
591 u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
592 dma_addr_t keymod_dma;
593
594 /* Ensure that the full blob will fit in the key slot */
595 slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
596 if ((secretlen + 48) > slot_length)
597 goto out;
598
599 /* Get the base addresses of both keystore slots */
600 inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
601 outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
602
603 /* Build the key modifier */
604 lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
605 memcpy(lkeymod, keymod, keymodlen);
606 keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
607 dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
608
609 /* Build the encapsulation job descriptor */
610 dsize = blob_encap_desc(&encapdesc, keymod_dma, keymodlen,
611 __pa(inpslotaddr), __pa(outslotaddr),
612 secretlen, 0);
613 if (!dsize) {
614 dev_err(dev, "can't alloc an encap descriptor\n");
615 retval = -ENOMEM;
616 goto out;
617 }
618 jstat = sm_key_job(dev, encapdesc);
619
620 dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
621 kfree(encapdesc);
622
623out:
624 return retval;
625
626}
627EXPORT_SYMBOL(sm_keystore_slot_encapsulate);
628
629int sm_keystore_slot_decapsulate(struct device *dev, u32 unit, u32 inslot,
630 u32 outslot, u16 secretlen, u8 *keymod,
631 u16 keymodlen)
632{
633 struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
634 int retval = 0;
635 u32 slot_length, dsize, jstat;
636 u32 __iomem *decapdesc = NULL;
637 u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
638 dma_addr_t keymod_dma;
639
640 /* Ensure that the decap data will fit in the key slot */
641 slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
642 if (secretlen > slot_length)
643 goto out;
644
645 /* Get the base addresses of both keystore slots */
646 inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
647 outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
648
649 /* Build the key modifier */
650 lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
651 memcpy(lkeymod, keymod, keymodlen);
652 keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
653 dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
654
655 /* Build the decapsulation job descriptor */
656 dsize = blob_decap_desc(&decapdesc, keymod_dma, keymodlen,
657 __pa(inpslotaddr), __pa(outslotaddr),
658 secretlen, 0);
659 if (!dsize) {
660 dev_err(dev, "can't alloc a decap descriptor\n");
661 retval = -ENOMEM;
662 goto out;
663 }
664 jstat = sm_key_job(dev, decapdesc);
665
666 dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
667 kfree(decapdesc);
668
669out:
670 return retval;
671
672}
673EXPORT_SYMBOL(sm_keystore_slot_decapsulate);
674
675
676/*
677 * Initialization/shutdown subsystem
678 * Assumes statically-invoked startup/shutdown from the controller driver
679 * for the present time, to be reworked when a device tree becomes
680 * available. This code will not modularize in present form.
681 *
682 * Also, simply uses ring 0 for execution at the present
683 */
684
685int caam_sm_startup(struct platform_device *pdev)
686{
687 struct device *ctrldev, *smdev;
688 struct caam_drv_private *ctrlpriv;
689 struct caam_drv_private_sm *smpriv;
690 struct caam_drv_private_jr *jrpriv; /* need this for reg page */
691 struct platform_device *sm_pdev;
692 struct sm_page_descriptor *lpagedesc;
693 u32 page, pgstat, lpagect, detectedpage;
694
695 struct device_node *np;
696 ctrldev = &pdev->dev;
697 ctrlpriv = dev_get_drvdata(ctrldev);
698
699 /*
700 * Set up the private block for secure memory
701 * Only one instance is possible
702 */
703 smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL);
704 if (smpriv == NULL) {
705 dev_err(ctrldev, "can't alloc private mem for secure memory\n");
706 return -ENOMEM;
707 }
708 smpriv->parentdev = ctrldev; /* copy of parent dev is handy */
709
710 /* Create the dev */
711#ifdef CONFIG_OF
712 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
713 sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev);
714#else
715 sm_pdev = platform_device_register_data(ctrldev, "caam_sm", 0,
716 smpriv,
717 sizeof(struct caam_drv_private_sm));
718#endif
719 if (sm_pdev == NULL) {
720 kfree(smpriv);
721 return -EINVAL;
722 }
723 smdev = &sm_pdev->dev;
724 dev_set_drvdata(smdev, smpriv);
725 ctrlpriv->smdev = smdev;
726
727 /*
728 * Collect configuration limit data for reference
729 * This batch comes from the partition data/vid registers in perfmon
730 */
731 smpriv->max_pages = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
732 & SMPART_MAX_NUMPG_MASK) >>
733 SMPART_MAX_NUMPG_SHIFT) + 1;
734 smpriv->top_partition = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
735 & SMPART_MAX_PNUM_MASK) >>
736 SMPART_MAX_PNUM_SHIFT) + 1;
737 smpriv->top_page = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
738 & SMPART_MAX_PG_MASK) >> SMPART_MAX_PG_SHIFT) + 1;
739 smpriv->page_size = 1024 << ((rd_reg32(&ctrlpriv->ctrl->perfmon.smvid)
740 & SMVID_PG_SIZE_MASK) >> SMVID_PG_SIZE_SHIFT);
741 smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE;
742
743#ifdef SM_DEBUG
744 dev_info(smdev, "max pages = %d, top partition = %d\n",
745 smpriv->max_pages, smpriv->top_partition);
746 dev_info(smdev, "top page = %d, page size = %d (total = %d)\n",
747 smpriv->top_page, smpriv->page_size,
748 smpriv->top_page * smpriv->page_size);
749 dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size);
750#endif
751
752 /*
753 * Now probe for partitions/pages to which we have access. Note that
754 * these have likely been set up by a bootloader or platform
755 * provisioning application, so we have to assume that we "inherit"
756 * a configuration and work within the constraints of what it might be.
757 *
758 * Assume use of the zeroth ring in the present iteration (until
759 * we can divorce the controller and ring drivers, and then assign
760 * an SM instance to any ring instance).
761 */
762 smpriv->smringdev = ctrlpriv->jrdev[0];
763 jrpriv = dev_get_drvdata(smpriv->smringdev);
764 lpagect = 0;
765 lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
766 * smpriv->max_pages, GFP_KERNEL);
767 if (lpagedesc == NULL) {
768 kfree(smpriv);
769 return -ENOMEM;
770 }
771
772 for (page = 0; page < smpriv->max_pages; page++) {
773 wr_reg32(&jrpriv->rregs->sm_cmd,
774 ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
775 (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK));
776 pgstat = rd_reg32(&jrpriv->rregs->sm_status);
777 if (((pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT)
778 == SMCS_PGOWN_OWNED) { /* our page? */
779 lpagedesc[page].phys_pagenum =
780 (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT;
781 lpagedesc[page].own_part =
782 (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK;
783 lpagedesc[page].pg_base = ctrlpriv->sm_base +
784 ((smpriv->page_size * page) / sizeof(u32));
785 lpagect++;
786#ifdef SM_DEBUG
787 dev_info(smdev,
788 "physical page %d, owning partition = %d\n",
789 lpagedesc[page].phys_pagenum,
790 lpagedesc[page].own_part);
791#endif
792 }
793 }
794
795 smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect,
796 GFP_KERNEL);
797 if (smpriv->pagedesc == NULL) {
798 kfree(lpagedesc);
799 kfree(smpriv);
800 return -ENOMEM;
801 }
802 smpriv->localpages = lpagect;
803
804 detectedpage = 0;
805 for (page = 0; page < smpriv->max_pages; page++) {
806 if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */
807 memcpy(&smpriv->pagedesc[detectedpage],
808 &lpagedesc[page],
809 sizeof(struct sm_page_descriptor));
810#ifdef SM_DEBUG_CONT
811 sm_show_page(smdev, &smpriv->pagedesc[detectedpage]);
812#endif
813 detectedpage++;
814 }
815 }
816
817 kfree(lpagedesc);
818
819 sm_init_keystore(smdev);
820
821 return 0;
822}
823
824void caam_sm_shutdown(struct platform_device *pdev)
825{
826 struct device *ctrldev, *smdev;
827 struct caam_drv_private *priv;
828 struct caam_drv_private_sm *smpriv;
829
830 ctrldev = &pdev->dev;
831 priv = dev_get_drvdata(ctrldev);
832 smdev = priv->smdev;
833 smpriv = dev_get_drvdata(smdev);
834
835 kfree(smpriv->pagedesc);
836 kfree(smpriv);
837}
838EXPORT_SYMBOL(caam_sm_shutdown);
839#ifdef CONFIG_OF
840static void __exit caam_sm_exit(void)
841{
842 struct device_node *dev_node;
843 struct platform_device *pdev;
844
845 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
846 if (!dev_node) {
847 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
848 if (!dev_node)
849 return;
850 }
851
852 pdev = of_find_device_by_node(dev_node);
853 if (!pdev)
854 return;
855
856 of_node_put(dev_node);
857
858 caam_sm_shutdown(pdev);
859
860 return;
861}
862
863static int __init caam_sm_init(void)
864{
865 struct device_node *dev_node;
866 struct platform_device *pdev;
867
868 /*
869 * Do of_find_compatible_node() then of_find_device_by_node()
870 * once a functional device tree is available
871 */
872 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
873 if (!dev_node) {
874 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
875 if (!dev_node)
876 return -ENODEV;
877 }
878
879 pdev = of_find_device_by_node(dev_node);
880 if (!pdev)
881 return -ENODEV;
882
883 of_node_get(dev_node);
884
885 caam_sm_startup(pdev);
886
887 return 0;
888}
889
890module_init(caam_sm_init);
891module_exit(caam_sm_exit);
892
893MODULE_LICENSE("Dual BSD/GPL");
894MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore");
895MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
896#endif
diff --git a/drivers/crypto/caam/sm_test.c b/drivers/crypto/caam/sm_test.c
new file mode 100644
index 000000000000..43590ca52155
--- /dev/null
+++ b/drivers/crypto/caam/sm_test.c
@@ -0,0 +1,844 @@
1/*
2 * Secure Memory / Keystore Exemplification Module
3 * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
4 *
5 * Serves as a functional example, and as a self-contained unit test for
6 * the functionality contained in sm_store.c.
7 *
8 * The example function, caam_sm_example_init(), runs a thread that:
9 *
10 * - initializes a set of fixed keys
11 * - stores one copy in clear buffers
12 * - stores them again in secure memory
13 * - extracts stored keys back out for use
14 * - intializes 3 data buffers for a test:
15 * (1) containing cleartext
16 * (2) to hold ciphertext encrypted with an extracted black key
17 * (3) to hold extracted cleartext decrypted with an equivalent clear key
18 *
19 * The function then builds simple job descriptors that reference the key
20 * material and buffers as initialized, and executes an encryption job
21 * with a black key, and a decryption job using a the same key held in the
22 * clear. The output of the decryption job is compared to the original
23 * cleartext; if they don't compare correctly, one can assume a key problem
24 * exists, where the function will exit with an error.
25 *
26 * This module can use a substantial amount of refactoring, which may occur
27 * after the API gets some mileage. Furthermore, expect this module to
28 * eventually disappear once the API is integrated into "real" software.
29 */
30
31#include "compat.h"
32#include "intern.h"
33#include "desc.h"
34#include "error.h"
35#include "jr.h"
36#include "sm.h"
37
38static u8 skeymod[] = {
39 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
40 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
41};
42static u8 symkey[] = {
43 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
44 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
45 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
46 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
47};
48
49static u8 symdata[] = {
50 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07,
51 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
52 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
53 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
54 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
55 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
56 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
57 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
58 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
59 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
60 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
61 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
62 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
63 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
64 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
65 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
66 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
67 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
68 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
69 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
70 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
71 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
72 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
73 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
74 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
75 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
76 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
77 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
78 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
79 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
80 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
81 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
82};
83
84static int mk_job_desc(u32 *desc, dma_addr_t key, u16 keysz, dma_addr_t indata,
85 dma_addr_t outdata, u16 sz, u32 cipherdir, u32 keymode)
86{
87 desc[1] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK) | keymode;
88 desc[2] = (u32)key;
89 desc[3] = CMD_OPERATION | OP_TYPE_CLASS1_ALG | OP_ALG_AAI_ECB |
90 cipherdir;
91 desc[4] = CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 |
92 FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1 | sz;
93 desc[5] = (u32)indata;
94 desc[6] = CMD_FIFO_STORE | FIFOST_TYPE_MESSAGE_DATA | sz;
95 desc[7] = (u32)outdata;
96
97 desc[0] = CMD_DESC_HDR | HDR_ONE | (8 & HDR_DESCLEN_MASK);
98 return 8 * sizeof(u32);
99}
100
101struct exec_test_result {
102 int error;
103 struct completion completion;
104};
105
106void exec_test_done(struct device *dev, u32 *desc, u32 err, void *context)
107{
108 struct exec_test_result *res = context;
109
110 if (err) {
111 char tmp[CAAM_ERROR_STR_MAX];
112 dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
113 }
114
115 res->error = err;
116 complete(&res->completion);
117}
118
119static int exec_test_job(struct device *ksdev, u32 *jobdesc)
120{
121 struct exec_test_result testres;
122 struct caam_drv_private_sm *kspriv;
123 int rtn = 0;
124
125 kspriv = dev_get_drvdata(ksdev);
126
127 init_completion(&testres.completion);
128
129 rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, exec_test_done,
130 &testres);
131 if (!rtn) {
132 wait_for_completion_interruptible(&testres.completion);
133 rtn = testres.error;
134 }
135 return rtn;
136}
137
138
139int caam_sm_example_init(struct platform_device *pdev)
140{
141 struct device *ctrldev, *ksdev;
142 struct caam_drv_private *ctrlpriv;
143 struct caam_drv_private_sm *kspriv;
144 u32 unit, units, jdescsz;
145 int stat, jstat, rtnval = 0;
146 u8 __iomem *syminp, *symint, *symout = NULL;
147 dma_addr_t syminp_dma, symint_dma, symout_dma;
148 u8 __iomem *black_key_des, *black_key_aes128;
149 u8 __iomem *black_key_aes256;
150 dma_addr_t black_key_des_dma, black_key_aes128_dma;
151 dma_addr_t black_key_aes256_dma;
152 u8 __iomem *clear_key_des, *clear_key_aes128, *clear_key_aes256;
153 dma_addr_t clear_key_des_dma, clear_key_aes128_dma;
154 dma_addr_t clear_key_aes256_dma;
155 u32 __iomem *jdesc;
156 u32 keyslot_des, keyslot_aes128, keyslot_aes256 = 0;
157
158 jdesc = NULL;
159 black_key_des = black_key_aes128 = black_key_aes256 = NULL;
160 clear_key_des = clear_key_aes128 = clear_key_aes256 = NULL;
161
162 /* We can lose this cruft once we can get a pdev by name */
163 ctrldev = &pdev->dev;
164 ctrlpriv = dev_get_drvdata(ctrldev);
165 ksdev = ctrlpriv->smdev;
166 kspriv = dev_get_drvdata(ksdev);
167 if (kspriv == NULL)
168 return -ENODEV;
169
170 /* Now that we have the dev for the single SM instance, connect */
171#ifdef SM_TEST_DETAIL
172 dev_info(ksdev, "caam_sm_test_init() running\n");
173#endif
174 /* Probe to see what keystores are available to us */
175 units = sm_detect_keystore_units(ksdev);
176 if (!units)
177 dev_err(ksdev, "caam_sm_test: no keystore units available\n");
178
179 /*
180 * MX6 bootloader stores some stuff in unit 0, so let's
181 * use 1 or above
182 */
183 if (units < 2) {
184 dev_err(ksdev, "caam_sm_test: insufficient keystore units\n");
185 return -ENODEV;
186 }
187 unit = 1;
188
189#ifdef SM_TEST_DETAIL
190 dev_info(ksdev, "caam_sm_test: %d keystore units available\n", units);
191#endif
192
193 /* Initialize/Establish Keystore */
194 sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */
195
196 /*
197 * Top of main test thread
198 */
199
200 /* Allocate test data blocks (input, intermediate, output) */
201 syminp = kmalloc(256, GFP_KERNEL | GFP_DMA);
202 symint = kmalloc(256, GFP_KERNEL | GFP_DMA);
203 symout = kmalloc(256, GFP_KERNEL | GFP_DMA);
204 if ((syminp == NULL) || (symint == NULL) || (symout == NULL)) {
205 rtnval = -ENOMEM;
206 dev_err(ksdev, "caam_sm_test: can't get test data buffers\n");
207 goto freemem;
208 }
209
210 /* Allocate storage for 3 black keys: encapsulated 8, 16, 32 */
211 black_key_des = kmalloc(16, GFP_KERNEL | GFP_DMA); /* padded to 16... */
212 black_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
213 black_key_aes256 = kmalloc(16, GFP_KERNEL | GFP_DMA);
214 if ((black_key_des == NULL) || (black_key_aes128 == NULL) ||
215 (black_key_aes256 == NULL)) {
216 rtnval = -ENOMEM;
217 dev_err(ksdev, "caam_sm_test: can't black key buffers\n");
218 goto freemem;
219 }
220
221 clear_key_des = kmalloc(8, GFP_KERNEL | GFP_DMA);
222 clear_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
223 clear_key_aes256 = kmalloc(32, GFP_KERNEL | GFP_DMA);
224 if ((clear_key_des == NULL) || (clear_key_aes128 == NULL) ||
225 (clear_key_aes256 == NULL)) {
226 rtnval = -ENOMEM;
227 dev_err(ksdev, "caam_sm_test: can't get clear key buffers\n");
228 goto freemem;
229 }
230
231 /* Allocate storage for job descriptor */
232 jdesc = kmalloc(8 * sizeof(u32), GFP_KERNEL | GFP_DMA);
233 if (jdesc == NULL) {
234 rtnval = -ENOMEM;
235 dev_err(ksdev, "caam_sm_test: can't get descriptor buffers\n");
236 goto freemem;
237 }
238
239#ifdef SM_TEST_DETAIL
240 dev_info(ksdev, "caam_sm_test: all buffers allocated\n");
241#endif
242
243 /* Load up input data block, clear outputs */
244 memcpy(syminp, symdata, 256);
245 memset(symint, 0, 256);
246 memset(symout, 0, 256);
247#ifdef SM_TEST_DETAIL
248 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
249 "0x%02x 0x%02x 0x%02x 0x%02x\n",
250 syminp[0], syminp[1], syminp[2], syminp[3],
251 syminp[4], syminp[5], syminp[6], syminp[7]);
252 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
253 "0x%02x 0x%02x 0x%02x 0x%02x\n",
254 symint[0], symint[1], symint[2], symint[3],
255 symint[4], symint[5], symint[6], symint[7]);
256 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
257 "0x%02x 0x%02x 0x%02x 0x%02x\n",
258 symout[0], symout[1], symout[2], symout[3],
259 symout[4], symout[5], symout[6], symout[7]);
260
261 dev_info(ksdev, "caam_sm_test: data buffers initialized\n");
262#endif
263
264 /* Load up clear keys */
265 memcpy(clear_key_des, symkey, 8);
266 memcpy(clear_key_aes128, symkey, 16);
267 memcpy(clear_key_aes256, symkey, 32);
268
269#ifdef SM_TEST_DETAIL
270 dev_info(ksdev, "caam_sm_test: all clear keys loaded\n");
271#endif
272
273 /*
274 * Place clear keys in keystore.
275 * All the interesting stuff happens here.
276 */
277 /* 8 bit DES key */
278 stat = sm_keystore_slot_alloc(ksdev, unit, 8, &keyslot_des);
279 if (stat)
280 goto freemem;
281#ifdef SM_TEST_DETAIL
282 dev_info(ksdev, "caam_sm_test: 8 byte key slot in %d\n", keyslot_des);
283#endif
284 stat = sm_keystore_slot_load(ksdev, unit, keyslot_des, clear_key_des,
285 8);
286 if (stat) {
287#ifdef SM_TEST_DETAIL
288 dev_info(ksdev, "caam_sm_test: can't load 8 byte key in %d\n",
289 keyslot_des);
290#endif
291 sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
292 goto freemem;
293 }
294
295 /* 16 bit AES key */
296 stat = sm_keystore_slot_alloc(ksdev, unit, 16, &keyslot_aes128);
297 if (stat) {
298 sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
299 goto freemem;
300 }
301#ifdef SM_TEST_DETAIL
302 dev_info(ksdev, "caam_sm_test: 16 byte key slot in %d\n",
303 keyslot_aes128);
304#endif
305 stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes128,
306 clear_key_aes128, 16);
307 if (stat) {
308#ifdef SM_TEST_DETAIL
309 dev_info(ksdev, "caam_sm_test: can't load 16 byte key in %d\n",
310 keyslot_aes128);
311#endif
312 sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
313 sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
314 goto freemem;
315 }
316
317 /* 32 bit AES key */
318 stat = sm_keystore_slot_alloc(ksdev, unit, 32, &keyslot_aes256);
319 if (stat) {
320 sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
321 sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
322 goto freemem;
323 }
324#ifdef SM_TEST_DETAIL
325 dev_info(ksdev, "caam_sm_test: 32 byte key slot in %d\n",
326 keyslot_aes256);
327#endif
328 stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes256,
329 clear_key_aes256, 32);
330 if (stat) {
331#ifdef SM_TEST_DETAIL
332 dev_info(ksdev, "caam_sm_test: can't load 32 byte key in %d\n",
333 keyslot_aes128);
334#endif
335 sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
336 sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
337 sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
338 goto freemem;
339 }
340
341 /* Encapsulate all keys as SM blobs */
342 stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_des,
343 keyslot_des, 8, skeymod, 8);
344 if (stat) {
345 dev_info(ksdev, "caam_sm_test: can't encapsulate DES key\n");
346 goto freekeys;
347 }
348
349 stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes128,
350 keyslot_aes128, 16, skeymod, 8);
351 if (stat) {
352 dev_info(ksdev, "caam_sm_test: can't encapsulate AES128 key\n");
353 goto freekeys;
354 }
355
356 stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes256,
357 keyslot_aes256, 32, skeymod, 8);
358 if (stat) {
359 dev_info(ksdev, "caam_sm_test: can't encapsulate AES256 key\n");
360 goto freekeys;
361 }
362
363 /* Now decapsulate as black key blobs */
364 stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_des,
365 keyslot_des, 8, skeymod, 8);
366 if (stat) {
367 dev_info(ksdev, "caam_sm_test: can't decapsulate DES key\n");
368 goto freekeys;
369 }
370
371 stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes128,
372 keyslot_aes128, 16, skeymod, 8);
373 if (stat) {
374 dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
375 goto freekeys;
376 }
377
378 stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes256,
379 keyslot_aes256, 32, skeymod, 8);
380 if (stat) {
381 dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
382 goto freekeys;
383 }
384
385 /* Extract 8/16/32 byte black keys */
386 sm_keystore_slot_read(ksdev, unit, keyslot_des, 8, black_key_des);
387 sm_keystore_slot_read(ksdev, unit, keyslot_aes128, 16,
388 black_key_aes128);
389 sm_keystore_slot_read(ksdev, unit, keyslot_aes256, 32,
390 black_key_aes256);
391
392#ifdef SM_TEST_DETAIL
393 dev_info(ksdev, "caam_sm_test: all black keys extracted\n");
394#endif
395
396 /* DES encrypt using 8 byte black key */
397 black_key_des_dma = dma_map_single(ksdev, black_key_des, 8,
398 DMA_TO_DEVICE);
399 dma_sync_single_for_device(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
400 syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
401 dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
402 symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
403
404 jdescsz = mk_job_desc(jdesc, black_key_des_dma, 8, syminp_dma,
405 symint_dma, 256,
406 OP_ALG_ENCRYPT | OP_ALG_ALGSEL_DES, 0);
407
408#ifdef SM_TEST_DETAIL
409 dev_info(ksdev, "jobdesc:\n");
410 dev_info(ksdev, "0x%08x\n", jdesc[0]);
411 dev_info(ksdev, "0x%08x\n", jdesc[1]);
412 dev_info(ksdev, "0x%08x\n", jdesc[2]);
413 dev_info(ksdev, "0x%08x\n", jdesc[3]);
414 dev_info(ksdev, "0x%08x\n", jdesc[4]);
415 dev_info(ksdev, "0x%08x\n", jdesc[5]);
416 dev_info(ksdev, "0x%08x\n", jdesc[6]);
417 dev_info(ksdev, "0x%08x\n", jdesc[7]);
418#endif
419
420 jstat = exec_test_job(ksdev, jdesc);
421
422 dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
423 dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
424 dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
425 dma_unmap_single(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
426
427#ifdef SM_TEST_DETAIL
428 dev_info(ksdev, "input block:\n");
429 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
430 "0x%02x 0x%02x 0x%02x 0x%02x\n",
431 syminp[0], syminp[1], syminp[2], syminp[3],
432 syminp[4], syminp[5], syminp[6], syminp[7]);
433 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
434 "0x%02x 0x%02x 0x%02x 0x%02x\n",
435 syminp[8], syminp[9], syminp[10], syminp[11],
436 syminp[12], syminp[13], syminp[14], syminp[15]);
437 dev_info(ksdev, "intermediate block:\n");
438 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
439 "0x%02x 0x%02x 0x%02x 0x%02x\n",
440 symint[0], symint[1], symint[2], symint[3],
441 symint[4], symint[5], symint[6], symint[7]);
442 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
443 "0x%02x 0x%02x 0x%02x 0x%02x\n",
444 symint[8], symint[9], symint[10], symint[11],
445 symint[12], symint[13], symint[14], symint[15]);
446 dev_info(ksdev, "caam_sm_test: encrypt cycle with 8 byte key\n");
447#endif
448
449 /* DES decrypt using 8 byte clear key */
450 clear_key_des_dma = dma_map_single(ksdev, clear_key_des, 8,
451 DMA_TO_DEVICE);
452 dma_sync_single_for_device(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
453 symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
454 dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
455 symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
456
457 jdescsz = mk_job_desc(jdesc, clear_key_des_dma, 8, symint_dma,
458 symout_dma, 256,
459 OP_ALG_DECRYPT | OP_ALG_ALGSEL_DES, 0);
460
461#ifdef SM_TEST_DETAIL
462 dev_info(ksdev, "jobdesc:\n");
463 dev_info(ksdev, "0x%08x\n", jdesc[0]);
464 dev_info(ksdev, "0x%08x\n", jdesc[1]);
465 dev_info(ksdev, "0x%08x\n", jdesc[2]);
466 dev_info(ksdev, "0x%08x\n", jdesc[3]);
467 dev_info(ksdev, "0x%08x\n", jdesc[4]);
468 dev_info(ksdev, "0x%08x\n", jdesc[5]);
469 dev_info(ksdev, "0x%08x\n", jdesc[6]);
470 dev_info(ksdev, "0x%08x\n", jdesc[7]);
471#endif
472
473 jstat = exec_test_job(ksdev, jdesc);
474
475 dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
476 dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
477 dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
478 dma_unmap_single(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
479
480#ifdef SM_TEST_DETAIL
481 dev_info(ksdev, "intermediate block:\n");
482 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
483 "0x%02x 0x%02x 0x%02x 0x%02x\n",
484 symint[0], symint[1], symint[2], symint[3],
485 symint[4], symint[5], symint[6], symint[7]);
486 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
487 "0x%02x 0x%02x 0x%02x 0x%02x\n",
488 symint[8], symint[9], symint[10], symint[11],
489 symint[12], symint[13], symint[14], symint[15]);
490 dev_info(ksdev, "decrypted block:\n");
491 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
492 "0x%02x 0x%02x 0x%02x 0x%02x\n",
493 symout[0], symout[1], symout[2], symout[3],
494 symout[4], symout[5], symout[6], symout[7]);
495 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
496 "0x%02x 0x%02x 0x%02x 0x%02x\n",
497 symout[8], symout[9], symout[10], symout[11],
498 symout[12], symout[13], symout[14], symout[15]);
499 dev_info(ksdev, "caam_sm_test: decrypt cycle with 8 byte key\n");
500#endif
501
502 /* Check result */
503 if (memcmp(symout, syminp, 256)) {
504 dev_info(ksdev, "caam_sm_test: 8-byte key test mismatch\n");
505 rtnval = -1;
506 goto freekeys;
507 } else
508 dev_info(ksdev, "caam_sm_test: 8-byte key test match OK\n");
509
510 /* AES-128 encrypt using 16 byte black key */
511 black_key_aes128_dma = dma_map_single(ksdev, black_key_aes128, 16,
512 DMA_TO_DEVICE);
513 dma_sync_single_for_device(ksdev, black_key_aes128_dma, 16,
514 DMA_TO_DEVICE);
515 syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
516 dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
517 symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
518
519 jdescsz = mk_job_desc(jdesc, black_key_aes128_dma, 16, syminp_dma,
520 symint_dma, 256,
521 OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
522
523#ifdef SM_TEST_DETAIL
524 dev_info(ksdev, "jobdesc:\n");
525 dev_info(ksdev, "0x%08x\n", jdesc[0]);
526 dev_info(ksdev, "0x%08x\n", jdesc[1]);
527 dev_info(ksdev, "0x%08x\n", jdesc[2]);
528 dev_info(ksdev, "0x%08x\n", jdesc[3]);
529 dev_info(ksdev, "0x%08x\n", jdesc[4]);
530 dev_info(ksdev, "0x%08x\n", jdesc[5]);
531 dev_info(ksdev, "0x%08x\n", jdesc[6]);
532 dev_info(ksdev, "0x%08x\n", jdesc[7]);
533#endif
534
535 jstat = exec_test_job(ksdev, jdesc);
536
537 dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
538 dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
539 dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
540 dma_unmap_single(ksdev, black_key_aes128_dma, 16, DMA_TO_DEVICE);
541
542#ifdef SM_TEST_DETAIL
543 dev_info(ksdev, "input block:\n");
544 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
545 "0x%02x 0x%02x 0x%02x 0x%02x\n",
546 syminp[0], syminp[1], syminp[2], syminp[3],
547 syminp[4], syminp[5], syminp[6], syminp[7]);
548 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
549 "0x%02x 0x%02x 0x%02x 0x%02x\n",
550 syminp[8], syminp[9], syminp[10], syminp[11],
551 syminp[12], syminp[13], syminp[14], syminp[15]);
552 dev_info(ksdev, "intermediate block:\n");
553 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
554 "0x%02x 0x%02x 0x%02x 0x%02x\n",
555 symint[0], symint[1], symint[2], symint[3],
556 symint[4], symint[5], symint[6], symint[7]);
557 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
558 "0x%02x 0x%02x 0x%02x 0x%02x\n",
559 symint[8], symint[9], symint[10], symint[11],
560 symint[12], symint[13], symint[14], symint[15]);
561 dev_info(ksdev, "caam_sm_test: encrypt cycle with 16 byte key\n");
562#endif
563
564 /* AES-128 decrypt using 16 byte clear key */
565 clear_key_aes128_dma = dma_map_single(ksdev, clear_key_aes128, 16,
566 DMA_TO_DEVICE);
567 dma_sync_single_for_device(ksdev, clear_key_aes128_dma, 16,
568 DMA_TO_DEVICE);
569 symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
570 dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
571 symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
572
573 jdescsz = mk_job_desc(jdesc, clear_key_aes128_dma, 16, symint_dma,
574 symout_dma, 256,
575 OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
576
577#ifdef SM_TEST_DETAIL
578 dev_info(ksdev, "jobdesc:\n");
579 dev_info(ksdev, "0x%08x\n", jdesc[0]);
580 dev_info(ksdev, "0x%08x\n", jdesc[1]);
581 dev_info(ksdev, "0x%08x\n", jdesc[2]);
582 dev_info(ksdev, "0x%08x\n", jdesc[3]);
583 dev_info(ksdev, "0x%08x\n", jdesc[4]);
584 dev_info(ksdev, "0x%08x\n", jdesc[5]);
585 dev_info(ksdev, "0x%08x\n", jdesc[6]);
586 dev_info(ksdev, "0x%08x\n", jdesc[7]);
587#endif
588 jstat = exec_test_job(ksdev, jdesc);
589
590 dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
591 dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
592 dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
593 dma_unmap_single(ksdev, clear_key_aes128_dma, 16, DMA_TO_DEVICE);
594
595#ifdef SM_TEST_DETAIL
596 dev_info(ksdev, "intermediate block:\n");
597 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
598 "0x%02x 0x%02x 0x%02x 0x%02x\n",
599 symint[0], symint[1], symint[2], symint[3],
600 symint[4], symint[5], symint[6], symint[7]);
601 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
602 "0x%02x 0x%02x 0x%02x 0x%02x\n",
603 symint[8], symint[9], symint[10], symint[11],
604 symint[12], symint[13], symint[14], symint[15]);
605 dev_info(ksdev, "decrypted block:\n");
606 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
607 "0x%02x 0x%02x 0x%02x 0x%02x\n",
608 symout[0], symout[1], symout[2], symout[3],
609 symout[4], symout[5], symout[6], symout[7]);
610 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
611 "0x%02x 0x%02x 0x%02x 0x%02x\n",
612 symout[8], symout[9], symout[10], symout[11],
613 symout[12], symout[13], symout[14], symout[15]);
614 dev_info(ksdev, "caam_sm_test: decrypt cycle with 16 byte key\n");
615#endif
616
617 /* Check result */
618 if (memcmp(symout, syminp, 256)) {
619 dev_info(ksdev, "caam_sm_test: 16-byte key test mismatch\n");
620 rtnval = -1;
621 goto freekeys;
622 } else
623 dev_info(ksdev, "caam_sm_test: 16-byte key test match OK\n");
624
625 /* AES-256 encrypt using 32 byte black key */
626 black_key_aes256_dma = dma_map_single(ksdev, black_key_aes256, 32,
627 DMA_TO_DEVICE);
628 dma_sync_single_for_device(ksdev, black_key_aes256_dma, 32,
629 DMA_TO_DEVICE);
630 syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
631 dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
632 symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
633
634 jdescsz = mk_job_desc(jdesc, black_key_aes256_dma, 32, syminp_dma,
635 symint_dma, 256,
636 OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
637
638#ifdef SM_TEST_DETAIL
639 dev_info(ksdev, "jobdesc:\n");
640 dev_info(ksdev, "0x%08x\n", jdesc[0]);
641 dev_info(ksdev, "0x%08x\n", jdesc[1]);
642 dev_info(ksdev, "0x%08x\n", jdesc[2]);
643 dev_info(ksdev, "0x%08x\n", jdesc[3]);
644 dev_info(ksdev, "0x%08x\n", jdesc[4]);
645 dev_info(ksdev, "0x%08x\n", jdesc[5]);
646 dev_info(ksdev, "0x%08x\n", jdesc[6]);
647 dev_info(ksdev, "0x%08x\n", jdesc[7]);
648#endif
649
650 jstat = exec_test_job(ksdev, jdesc);
651
652 dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
653 dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
654 dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
655 dma_unmap_single(ksdev, black_key_aes256_dma, 32, DMA_TO_DEVICE);
656
657#ifdef SM_TEST_DETAIL
658 dev_info(ksdev, "input block:\n");
659 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
660 "0x%02x 0x%02x 0x%02x 0x%02x\n",
661 syminp[0], syminp[1], syminp[2], syminp[3],
662 syminp[4], syminp[5], syminp[6], syminp[7]);
663 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
664 "0x%02x 0x%02x 0x%02x 0x%02x\n",
665 syminp[8], syminp[9], syminp[10], syminp[11],
666 syminp[12], syminp[13], syminp[14], syminp[15]);
667 dev_info(ksdev, "intermediate block:\n");
668 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
669 "0x%02x 0x%02x 0x%02x 0x%02x\n",
670 symint[0], symint[1], symint[2], symint[3],
671 symint[4], symint[5], symint[6], symint[7]);
672 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
673 "0x%02x 0x%02x 0x%02x 0x%02x\n",
674 symint[8], symint[9], symint[10], symint[11],
675 symint[12], symint[13], symint[14], symint[15]);
676 dev_info(ksdev, "caam_sm_test: encrypt cycle with 32 byte key\n");
677#endif
678
679 /* AES-256 decrypt using 32-byte black key */
680 clear_key_aes256_dma = dma_map_single(ksdev, clear_key_aes256, 32,
681 DMA_TO_DEVICE);
682 dma_sync_single_for_device(ksdev, clear_key_aes256_dma, 32,
683 DMA_TO_DEVICE);
684 symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
685 dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
686 symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
687
688 jdescsz = mk_job_desc(jdesc, clear_key_aes256_dma, 32, symint_dma,
689 symout_dma, 256,
690 OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
691
692#ifdef SM_TEST_DETAIL
693 dev_info(ksdev, "jobdesc:\n");
694 dev_info(ksdev, "0x%08x\n", jdesc[0]);
695 dev_info(ksdev, "0x%08x\n", jdesc[1]);
696 dev_info(ksdev, "0x%08x\n", jdesc[2]);
697 dev_info(ksdev, "0x%08x\n", jdesc[3]);
698 dev_info(ksdev, "0x%08x\n", jdesc[4]);
699 dev_info(ksdev, "0x%08x\n", jdesc[5]);
700 dev_info(ksdev, "0x%08x\n", jdesc[6]);
701 dev_info(ksdev, "0x%08x\n", jdesc[7]);
702#endif
703
704 jstat = exec_test_job(ksdev, jdesc);
705
706 dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
707 dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
708 dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
709 dma_unmap_single(ksdev, clear_key_aes256_dma, 32, DMA_TO_DEVICE);
710
711#ifdef SM_TEST_DETAIL
712 dev_info(ksdev, "intermediate block:\n");
713 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
714 "0x%02x 0x%02x 0x%02x 0x%02x\n",
715 symint[0], symint[1], symint[2], symint[3],
716 symint[4], symint[5], symint[6], symint[7]);
717 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
718 "0x%02x 0x%02x 0x%02x 0x%02x\n",
719 symint[8], symint[9], symint[10], symint[11],
720 symint[12], symint[13], symint[14], symint[15]);
721 dev_info(ksdev, "decrypted block:\n");
722 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
723 "0x%02x 0x%02x 0x%02x 0x%02x\n",
724 symout[0], symout[1], symout[2], symout[3],
725 symout[4], symout[5], symout[6], symout[7]);
726 dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
727 "0x%02x 0x%02x 0x%02x 0x%02x\n",
728 symout[8], symout[9], symout[10], symout[11],
729 symout[12], symout[13], symout[14], symout[15]);
730 dev_info(ksdev, "caam_sm_test: decrypt cycle with 32 byte key\n");
731#endif
732
733 /* Check result */
734 if (memcmp(symout, syminp, 256)) {
735 dev_info(ksdev, "caam_sm_test: 32-byte key test mismatch\n");
736 rtnval = -1;
737 goto freekeys;
738 } else
739 dev_info(ksdev, "caam_sm_test: 32-byte key test match OK\n");
740
741
742 /* Remove 8/16/32 byte keys from keystore */
743freekeys:
744 stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
745 if (stat)
746 dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
747 keyslot_des);
748
749 stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
750 if (stat)
751 dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
752 keyslot_aes128);
753
754 stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
755 if (stat)
756 dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
757 keyslot_aes256);
758
759
760 /* Free resources */
761freemem:
762#ifdef SM_TEST_DETAIL
763 dev_info(ksdev, "caam_sm_test: cleaning up\n");
764#endif
765 kfree(syminp);
766 kfree(symint);
767 kfree(symout);
768 kfree(clear_key_des);
769 kfree(clear_key_aes128);
770 kfree(clear_key_aes256);
771 kfree(black_key_des);
772 kfree(black_key_aes128);
773 kfree(black_key_aes256);
774 kfree(jdesc);
775
776 /* Disconnect from keystore and leave */
777 sm_release_keystore(ksdev, unit);
778
779 return rtnval;
780}
781EXPORT_SYMBOL(caam_sm_example_init);
782
783void caam_sm_example_shutdown(void)
784{
785 /* unused in present version */
786 struct device_node *dev_node;
787 struct platform_device *pdev;
788
789 /*
790 * Do of_find_compatible_node() then of_find_device_by_node()
791 * once a functional device tree is available
792 */
793 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
794 if (!dev_node) {
795 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
796 if (!dev_node)
797 return;
798 }
799
800 pdev = of_find_device_by_node(dev_node);
801 if (!pdev)
802 return;
803
804 of_node_get(dev_node);
805
806}
807
808static int __init caam_sm_test_init(void)
809{
810 struct device_node *dev_node;
811 struct platform_device *pdev;
812
813 /*
814 * Do of_find_compatible_node() then of_find_device_by_node()
815 * once a functional device tree is available
816 */
817 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
818 if (!dev_node) {
819 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
820 if (!dev_node)
821 return -ENODEV;
822 }
823
824 pdev = of_find_device_by_node(dev_node);
825 if (!pdev)
826 return -ENODEV;
827
828 of_node_put(dev_node);
829
830 caam_sm_example_init(pdev);
831
832 return 0;
833}
834
835
836/* Module-based initialization needs to wait for dev tree */
837#ifdef CONFIG_OF
838module_init(caam_sm_test_init);
839module_exit(caam_sm_example_shutdown);
840
841MODULE_LICENSE("Dual BSD/GPL");
842MODULE_DESCRIPTION("FSL CAAM Keystore Usage Example");
843MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
844#endif
diff --git a/drivers/crypto/caam/snvsregs.h b/drivers/crypto/caam/snvsregs.h
new file mode 100644
index 000000000000..677e8906e3d0
--- /dev/null
+++ b/drivers/crypto/caam/snvsregs.h
@@ -0,0 +1,237 @@
1/*
2 * SNVS hardware register-level view
3 *
4 * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
5 */
6
7#ifndef SNVSREGS_H
8#define SNVSREGS_H
9
10#include <linux/types.h>
11#include <linux/io.h>
12
13/*
14 * SNVS High Power Domain
15 * Includes security violations, HA counter, RTC, alarm
16 */
17struct snvs_hp {
18 u32 lock;
19 u32 cmd;
20 u32 ctl;
21 u32 secvio_int_en; /* Security Violation Interrupt Enable */
22 u32 secvio_int_ctl; /* Security Violation Interrupt Control */
23 u32 status;
24 u32 secvio_status; /* Security Violation Status */
25 u32 ha_counteriv; /* High Assurance Counter IV */
26 u32 ha_counter; /* High Assurance Counter */
27 u32 rtc_msb; /* Real Time Clock/Counter MSB */
28 u32 rtc_lsb; /* Real Time Counter LSB */
29 u32 time_alarm_msb; /* Time Alarm MSB */
30 u32 time_alarm_lsb; /* Time Alarm LSB */
31};
32
33#define HP_LOCK_HAC_LCK 0x00040000
34#define HP_LOCK_HPSICR_LCK 0x00020000
35#define HP_LOCK_HPSVCR_LCK 0x00010000
36#define HP_LOCK_MKEYSEL_LCK 0x00000200
37#define HP_LOCK_TAMPCFG_LCK 0x00000100
38#define HP_LOCK_TAMPFLT_LCK 0x00000080
39#define HP_LOCK_SECVIO_LCK 0x00000040
40#define HP_LOCK_GENP_LCK 0x00000020
41#define HP_LOCK_MONOCTR_LCK 0x00000010
42#define HP_LOCK_CALIB_LCK 0x00000008
43#define HP_LOCK_SRTC_LCK 0x00000004
44#define HP_LOCK_ZMK_RD_LCK 0x00000002
45#define HP_LOCK_ZMK_WT_LCK 0x00000001
46
47#define HP_CMD_NONPRIV_AXS 0x80000000
48#define HP_CMD_HAC_STOP 0x00080000
49#define HP_CMD_HAC_CLEAR 0x00040000
50#define HP_CMD_HAC_LOAD 0x00020000
51#define HP_CMD_HAC_CFG_EN 0x00010000
52#define HP_CMD_SNVS_MSTR_KEY 0x00002000
53#define HP_CMD_PROG_ZMK 0x00001000
54#define HP_CMD_SW_LPSV 0x00000400
55#define HP_CMD_SW_FSV 0x00000200
56#define HP_CMD_SW_SV 0x00000100
57#define HP_CMD_LP_SWR_DIS 0x00000020
58#define HP_CMD_LP_SWR 0x00000010
59#define HP_CMD_SSM_SFNS_DIS 0x00000004
60#define HP_CMD_SSM_ST_DIS 0x00000002
61#define HP_CMD_SMM_ST 0x00000001
62
63#define HP_CTL_TIME_SYNC 0x00010000
64#define HP_CTL_CAL_VAL_SHIFT 10
65#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
66#define HP_CTL_CALIB_EN 0x00000100
67#define HP_CTL_PI_FREQ_SHIFT 4
68#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
69#define HP_CTL_PI_EN 0x00000008
70#define HP_CTL_TIMEALARM_EN 0x00000002
71#define HP_CTL_RTC_EN 0x00000001
72
73#define HP_SECVIO_INTEN_EN 0x10000000
74#define HP_SECVIO_INTEN_SRC5 0x00000020
75#define HP_SECVIO_INTEN_SRC4 0x00000010
76#define HP_SECVIO_INTEN_SRC3 0x00000008
77#define HP_SECVIO_INTEN_SRC2 0x00000004
78#define HP_SECVIO_INTEN_SRC1 0x00000002
79#define HP_SECVIO_INTEN_SRC0 0x00000001
80#define HP_SECVIO_INTEN_ALL 0x8000003f
81
82#define HP_SECVIO_ICTL_CFG_SHIFT 30
83#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
84#define HP_SECVIO_ICTL_CFG5_SHIFT 5
85#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
86#define HP_SECVIO_ICTL_CFG_DISABLE 0
87#define HP_SECVIO_ICTL_CFG_NONFATAL 1
88#define HP_SECVIO_ICTL_CFG_FATAL 2
89#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
90#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
91#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
92#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
93#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
94
95#define HP_STATUS_ZMK_ZERO 0x80000000
96#define HP_STATUS_OTPMK_ZERO 0x08000000
97#define HP_STATUS_OTPMK_SYN_SHIFT 16
98#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
99#define HP_STATUS_SSM_ST_SHIFT 8
100#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
101#define HP_STATUS_SSM_ST_INIT 0
102#define HP_STATUS_SSM_ST_HARDFAIL 1
103#define HP_STATUS_SSM_ST_SOFTFAIL 3
104#define HP_STATUS_SSM_ST_INITINT 8
105#define HP_STATUS_SSM_ST_CHECK 9
106#define HP_STATUS_SSM_ST_NONSECURE 11
107#define HP_STATUS_SSM_ST_TRUSTED 13
108#define HP_STATUS_SSM_ST_SECURE 15
109
110#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
111#define HP_SECVIOST_ZMK_SYN_SHIFT 16
112#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
113#define HP_SECVIOST_SECVIO5 0x00000020
114#define HP_SECVIOST_SECVIO4 0x00000010
115#define HP_SECVIOST_SECVIO3 0x00000008
116#define HP_SECVIOST_SECVIO2 0x00000004
117#define HP_SECVIOST_SECVIO1 0x00000002
118#define HP_SECVIOST_SECVIO0 0x00000001
119#define HP_SECVIOST_SECVIOMASK 0x0000003f
120
121/*
122 * SNVS Low Power Domain
123 * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
124 */
125struct snvs_lp {
126 u32 lock;
127 u32 ctl;
128 u32 mstr_key_ctl; /* Master Key Control */
129 u32 secvio_ctl; /* Security Violation Control */
130 u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
131 u32 tamper_det_cfg; /* Tamper Detectors Configuration */
132 u32 status;
133 u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
134 u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
135 u32 time_alarm; /* Time Alarm */
136 u32 smc_msb; /* Secure Monotonic Counter MSB */
137 u32 smc_lsb; /* Secure Monotonic Counter LSB */
138 u32 pwr_glitch_det; /* Power Glitch Detector */
139 u32 gen_purpose;
140 u32 zmk[8]; /* Zeroizable Master Key */
141};
142
143#define LP_LOCK_MKEYSEL_LCK 0x00000200
144#define LP_LOCK_TAMPDET_LCK 0x00000100
145#define LP_LOCK_TAMPFLT_LCK 0x00000080
146#define LP_LOCK_SECVIO_LCK 0x00000040
147#define LP_LOCK_GENP_LCK 0x00000020
148#define LP_LOCK_MONOCTR_LCK 0x00000010
149#define LP_LOCK_CALIB_LCK 0x00000008
150#define LP_LOCK_SRTC_LCK 0x00000004
151#define LP_LOCK_ZMK_RD_LCK 0x00000002
152#define LP_LOCK_ZMK_WT_LCK 0x00000001
153
154#define LP_CTL_CAL_VAL_SHIFT 10
155#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
156#define LP_CTL_CALIB_EN 0x00000100
157#define LP_CTL_SRTC_INVAL_EN 0x00000010
158#define LP_CTL_WAKE_INT_EN 0x00000008
159#define LP_CTL_MONOCTR_EN 0x00000004
160#define LP_CTL_TIMEALARM_EN 0x00000002
161#define LP_CTL_SRTC_EN 0x00000001
162
163#define LP_MKEYCTL_ZMKECC_SHIFT 8
164#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
165#define LP_MKEYCTL_ZMKECC_EN 0x00000010
166#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
167#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
168#define LP_MKEYCTL_MKSEL_SHIFT 0
169#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
170#define LP_MKEYCTL_MK_OTP 0
171#define LP_MKEYCTL_MK_ZMK 2
172#define LP_MKEYCTL_MK_COMB 3
173
174#define LP_SECVIO_CTL_SRC5 0x20
175#define LP_SECVIO_CTL_SRC4 0x10
176#define LP_SECVIO_CTL_SRC3 0x08
177#define LP_SECVIO_CTL_SRC2 0x04
178#define LP_SECVIO_CTL_SRC1 0x02
179#define LP_SECVIO_CTL_SRC0 0x01
180
181#define LP_TAMPFILT_EXT2_EN 0x80000000
182#define LP_TAMPFILT_EXT2_SHIFT 24
183#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
184#define LP_TAMPFILT_EXT1_EN 0x00800000
185#define LP_TAMPFILT_EXT1_SHIFT 16
186#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
187#define LP_TAMPFILT_WM_EN 0x00000080
188#define LP_TAMPFILT_WM_SHIFT 0
189#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
190
191#define LP_TAMPDET_OSC_BPS 0x10000000
192#define LP_TAMPDET_VRC_SHIFT 24
193#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
194#define LP_TAMPDET_HTDC_SHIFT 20
195#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
196#define LP_TAMPDET_LTDC_SHIFT 16
197#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
198#define LP_TAMPDET_POR_OBS 0x00008000
199#define LP_TAMPDET_PFD_OBS 0x00004000
200#define LP_TAMPDET_ET2_EN 0x00000400
201#define LP_TAMPDET_ET1_EN 0x00000200
202#define LP_TAMPDET_WMT2_EN 0x00000100
203#define LP_TAMPDET_WMT1_EN 0x00000080
204#define LP_TAMPDET_VT_EN 0x00000040
205#define LP_TAMPDET_TT_EN 0x00000020
206#define LP_TAMPDET_CT_EN 0x00000010
207#define LP_TAMPDET_MCR_EN 0x00000004
208#define LP_TAMPDET_SRTCR_EN 0x00000002
209
210#define LP_STATUS_SECURE
211#define LP_STATUS_NONSECURE
212#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
213#define LP_STATUS_EXT_SECVIO 0x00010000
214#define LP_STATUS_ET2 0x00000400
215#define LP_STATUS_ET1 0x00000200
216#define LP_STATUS_WMT2 0x00000100
217#define LP_STATUS_WMT1 0x00000080
218#define LP_STATUS_VTD 0x00000040
219#define LP_STATUS_TTD 0x00000020
220#define LP_STATUS_CTD 0x00000010
221#define LP_STATUS_PGD 0x00000008
222#define LP_STATUS_MCR 0x00000004
223#define LP_STATUS_SRTCR 0x00000002
224#define LP_STATUS_LPTA 0x00000001
225
226/* Full SNVS register page, including version/options */
227struct snvs_full {
228 struct snvs_hp hp;
229 struct snvs_lp lp;
230 u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
231
232 /* Version / Revision / Option ID space - end of register page */
233 u32 vid; /* 0xbf8 HP Version ID (VID 1) */
234 u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
235};
236
237#endif /* SNVSREGS_H */