aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2012-06-22 20:48:52 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-06-27 02:42:06 -0400
commit281922a1d4f59bdebbe78c1d9f4c50a967eb6cff (patch)
tree7ad9560f4431b7b8d440b008f7d75af53d914b37 /drivers/crypto/caam
parente13af18a3e33259e264c7fb47b54fbf608137976 (diff)
crypto: caam - add support for SEC v5.x RNG4
The SEC v4.x' RNGB h/w block self-initialized. RNG4, available on SEC versions 5 and beyond, is based on a different standard that requires manual initialization. Also update any new errors From the SEC v5.2 reference manual: The SEC v5.2's RNG4 unit reuses some error IDs, thus the addition of rng_err_id_list over the CHA-independent err_id_list. Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r--drivers/crypto/caam/ctrl.c129
-rw-r--r--drivers/crypto/caam/desc.h5
-rw-r--r--drivers/crypto/caam/error.c44
-rw-r--r--drivers/crypto/caam/regs.h32
4 files changed, 196 insertions, 14 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 9a2db9c30630..ac6abb375c8d 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -2,13 +2,15 @@
2 * CAAM control-plane driver backend 2 * CAAM control-plane driver backend
3 * Controller-level driver, kernel property detection, initialization 3 * Controller-level driver, kernel property detection, initialization
4 * 4 *
5 * Copyright 2008-2011 Freescale Semiconductor, Inc. 5 * Copyright 2008-2012 Freescale Semiconductor, Inc.
6 */ 6 */
7 7
8#include "compat.h" 8#include "compat.h"
9#include "regs.h" 9#include "regs.h"
10#include "intern.h" 10#include "intern.h"
11#include "jr.h" 11#include "jr.h"
12#include "desc_constr.h"
13#include "error.h"
12 14
13static int caam_remove(struct platform_device *pdev) 15static int caam_remove(struct platform_device *pdev)
14{ 16{
@@ -43,10 +45,120 @@ static int caam_remove(struct platform_device *pdev)
43 return ret; 45 return ret;
44} 46}
45 47
48/*
49 * Descriptor to instantiate RNG State Handle 0 in normal mode and
50 * load the JDKEK, TDKEK and TDSK registers
51 */
52static void build_instantiation_desc(u32 *desc)
53{
54 u32 *jump_cmd;
55
56 init_job_desc(desc, 0);
57
58 /* INIT RNG in non-test mode */
59 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
60 OP_ALG_AS_INIT);
61
62 /* wait for done */
63 jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
64 set_jump_tgt_here(desc, jump_cmd);
65
66 /*
67 * load 1 to clear written reg:
68 * resets the done interrrupt and returns the RNG to idle.
69 */
70 append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
71
72 /* generate secure keys (non-test) */
73 append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
74 OP_ALG_RNG4_SK);
75}
76
77struct instantiate_result {
78 struct completion completion;
79 int err;
80};
81
82static void rng4_init_done(struct device *dev, u32 *desc, u32 err,
83 void *context)
84{
85 struct instantiate_result *instantiation = context;
86
87 if (err) {
88 char tmp[CAAM_ERROR_STR_MAX];
89
90 dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
91 }
92
93 instantiation->err = err;
94 complete(&instantiation->completion);
95}
96
97static int instantiate_rng(struct device *jrdev)
98{
99 struct instantiate_result instantiation;
100
101 dma_addr_t desc_dma;
102 u32 *desc;
103 int ret;
104
105 desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA);
106 if (!desc) {
107 dev_err(jrdev, "cannot allocate RNG init descriptor memory\n");
108 return -ENOMEM;
109 }
110
111 build_instantiation_desc(desc);
112 desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc), DMA_TO_DEVICE);
113 init_completion(&instantiation.completion);
114 ret = caam_jr_enqueue(jrdev, desc, rng4_init_done, &instantiation);
115 if (!ret) {
116 wait_for_completion_interruptible(&instantiation.completion);
117 ret = instantiation.err;
118 if (ret)
119 dev_err(jrdev, "unable to instantiate RNG\n");
120 }
121
122 dma_unmap_single(jrdev, desc_dma, desc_bytes(desc), DMA_TO_DEVICE);
123
124 kfree(desc);
125
126 return ret;
127}
128
129/*
130 * By default, the TRNG runs for 200 clocks per sample;
131 * 800 clocks per sample generates better entropy.
132 */
133static void kick_trng(struct platform_device *pdev)
134{
135 struct device *ctrldev = &pdev->dev;
136 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
137 struct caam_full __iomem *topregs;
138 struct rng4tst __iomem *r4tst;
139 u32 val;
140
141 topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
142 r4tst = &topregs->ctrl.r4tst[0];
143
144 /* put RNG4 into program mode */
145 setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
146 /* 800 clocks per sample */
147 val = rd_reg32(&r4tst->rtsdctl);
148 val = (val & ~RTSDCTL_ENT_DLY_MASK) | (800 << RTSDCTL_ENT_DLY_SHIFT);
149 wr_reg32(&r4tst->rtsdctl, val);
150 /* min. freq. count */
151 wr_reg32(&r4tst->rtfrqmin, 400);
152 /* max. freq. count */
153 wr_reg32(&r4tst->rtfrqmax, 6400);
154 /* put RNG4 into run mode */
155 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
156}
157
46/* Probe routine for CAAM top (controller) level */ 158/* Probe routine for CAAM top (controller) level */
47static int caam_probe(struct platform_device *pdev) 159static int caam_probe(struct platform_device *pdev)
48{ 160{
49 int ring, rspec; 161 int ret, ring, rspec;
50 struct device *dev; 162 struct device *dev;
51 struct device_node *nprop, *np; 163 struct device_node *nprop, *np;
52 struct caam_ctrl __iomem *ctrl; 164 struct caam_ctrl __iomem *ctrl;
@@ -146,6 +258,19 @@ static int caam_probe(struct platform_device *pdev)
146 return -ENOMEM; 258 return -ENOMEM;
147 } 259 }
148 260
261 /*
262 * RNG4 based SECs (v5+) need special initialization prior
263 * to executing any descriptors
264 */
265 if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) {
266 kick_trng(pdev);
267 ret = instantiate_rng(ctrlpriv->jrdev[0]);
268 if (ret) {
269 caam_remove(pdev);
270 return ret;
271 }
272 }
273
149 /* NOTE: RTIC detection ought to go here, around Si time */ 274 /* NOTE: RTIC detection ought to go here, around Si time */
150 275
151 /* Initialize queue allocator lock */ 276 /* Initialize queue allocator lock */
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 3e685062d44b..f7f833be8c67 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -1172,6 +1172,11 @@ struct sec4_sg_entry {
1172#define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT) 1172#define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT)
1173#define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT) 1173#define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT)
1174 1174
1175/* RNG4 set */
1176#define OP_ALG_RNG4_SHIFT 4
1177#define OP_ALG_RNG4_MASK (0x1f3 << OP_ALG_RNG4_SHIFT)
1178
1179#define OP_ALG_RNG4_SK (0x100 << OP_ALG_RNG4_SHIFT)
1175 1180
1176#define OP_ALG_AS_SHIFT 2 1181#define OP_ALG_AS_SHIFT 2
1177#define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT) 1182#define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT)
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c
index 7e2d54bffad6..9955ed9643e6 100644
--- a/drivers/crypto/caam/error.c
+++ b/drivers/crypto/caam/error.c
@@ -39,18 +39,20 @@ static void report_ccb_status(u32 status, char *outstr)
39 char *cha_id_list[] = { 39 char *cha_id_list[] = {
40 "", 40 "",
41 "AES", 41 "AES",
42 "DES, 3DES", 42 "DES",
43 "ARC4", 43 "ARC4",
44 "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", 44 "MDHA",
45 "RNG", 45 "RNG",
46 "SNOW f8", 46 "SNOW f8",
47 "Kasumi f8, f9", 47 "Kasumi f8/9",
48 "All Public Key Algorithms", 48 "PKHA",
49 "CRC", 49 "CRCA",
50 "SNOW f9", 50 "SNOW f9",
51 "ZUCE",
52 "ZUCA",
51 }; 53 };
52 char *err_id_list[] = { 54 char *err_id_list[] = {
53 "None. No error.", 55 "No error.",
54 "Mode error.", 56 "Mode error.",
55 "Data size error.", 57 "Data size error.",
56 "Key size error.", 58 "Key size error.",
@@ -67,6 +69,20 @@ static void report_ccb_status(u32 status, char *outstr)
67 "Invalid CHA combination was selected", 69 "Invalid CHA combination was selected",
68 "Invalid CHA selected.", 70 "Invalid CHA selected.",
69 }; 71 };
72 char *rng_err_id_list[] = {
73 "",
74 "",
75 "",
76 "Instantiate",
77 "Not instantiated",
78 "Test instantiate",
79 "Prediction resistance",
80 "",
81 "Prediction resistance and test request",
82 "Uninstantiate",
83 "",
84 "Secure key generation",
85 };
70 u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> 86 u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
71 JRSTA_CCBERR_CHAID_SHIFT; 87 JRSTA_CCBERR_CHAID_SHIFT;
72 u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; 88 u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
@@ -81,7 +97,13 @@ static void report_ccb_status(u32 status, char *outstr)
81 cha_id, sizeof("ff")); 97 cha_id, sizeof("ff"));
82 } 98 }
83 99
84 if (err_id < ARRAY_SIZE(err_id_list)) { 100 if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG &&
101 err_id < ARRAY_SIZE(rng_err_id_list) &&
102 strlen(rng_err_id_list[err_id])) {
103 /* RNG-only error */
104 SPRINTFCAT(outstr, "%s", rng_err_id_list[err_id],
105 strlen(rng_err_id_list[err_id]));
106 } else if (err_id < ARRAY_SIZE(err_id_list)) {
85 SPRINTFCAT(outstr, "%s", err_id_list[err_id], 107 SPRINTFCAT(outstr, "%s", err_id_list[err_id],
86 strlen(err_id_list[err_id])); 108 strlen(err_id_list[err_id]));
87 } else { 109 } else {
@@ -101,10 +123,10 @@ static void report_deco_status(u32 status, char *outstr)
101 u8 value; 123 u8 value;
102 char *error_text; 124 char *error_text;
103 } desc_error_list[] = { 125 } desc_error_list[] = {
104 { 0x00, "None. No error." }, 126 { 0x00, "No error." },
105 { 0x01, "SGT Length Error. The descriptor is trying to read " 127 { 0x01, "SGT Length Error. The descriptor is trying to read "
106 "more data than is contained in the SGT table." }, 128 "more data than is contained in the SGT table." },
107 { 0x02, "Reserved." }, 129 { 0x02, "SGT Null Entry Error." },
108 { 0x03, "Job Ring Control Error. There is a bad value in the " 130 { 0x03, "Job Ring Control Error. There is a bad value in the "
109 "Job Ring Control register." }, 131 "Job Ring Control register." },
110 { 0x04, "Invalid Descriptor Command. The Descriptor Command " 132 { 0x04, "Invalid Descriptor Command. The Descriptor Command "
@@ -116,7 +138,7 @@ static void report_deco_status(u32 status, char *outstr)
116 { 0x09, "Invalid OPERATION Command" }, 138 { 0x09, "Invalid OPERATION Command" },
117 { 0x0A, "Invalid FIFO LOAD Command" }, 139 { 0x0A, "Invalid FIFO LOAD Command" },
118 { 0x0B, "Invalid FIFO STORE Command" }, 140 { 0x0B, "Invalid FIFO STORE Command" },
119 { 0x0C, "Invalid MOVE Command" }, 141 { 0x0C, "Invalid MOVE/MOVE_LEN Command" },
120 { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " 142 { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is "
121 "invalid because the target is not a Job Header " 143 "invalid because the target is not a Job Header "
122 "Command, or the jump is from a Trusted Descriptor to " 144 "Command, or the jump is from a Trusted Descriptor to "
@@ -166,6 +188,8 @@ static void report_deco_status(u32 status, char *outstr)
166 "(input frame; block ciphers) and IPsec decap (output " 188 "(input frame; block ciphers) and IPsec decap (output "
167 "frame, when doing the next header byte update) and " 189 "frame, when doing the next header byte update) and "
168 "DCRC (output frame)." }, 190 "DCRC (output frame)." },
191 { 0x23, "Read Input Frame error" },
192 { 0x24, "JDKEK, TDKEK or TDSK not loaded error" },
169 { 0x80, "DNR (do not run) error" }, 193 { 0x80, "DNR (do not run) error" },
170 { 0x81, "undefined protocol command" }, 194 { 0x81, "undefined protocol command" },
171 { 0x82, "invalid setting in PDB" }, 195 { 0x82, "invalid setting in PDB" },
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index e9f7a70cdd5e..6d9f1d982970 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -167,7 +167,7 @@ struct partid {
167 u32 pidr; /* partition ID, DECO */ 167 u32 pidr; /* partition ID, DECO */
168}; 168};
169 169
170/* RNG test mode (replicated twice in some configurations) */ 170/* RNGB test mode (replicated twice in some configurations) */
171/* Padded out to 0x100 */ 171/* Padded out to 0x100 */
172struct rngtst { 172struct rngtst {
173 u32 mode; /* RTSTMODEx - Test mode */ 173 u32 mode; /* RTSTMODEx - Test mode */
@@ -200,6 +200,31 @@ struct rngtst {
200 u32 rsvd14[15]; 200 u32 rsvd14[15];
201}; 201};
202 202
203/* RNG4 TRNG test registers */
204struct rng4tst {
205#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
206 u32 rtmctl; /* misc. control register */
207 u32 rtscmisc; /* statistical check misc. register */
208 u32 rtpkrrng; /* poker range register */
209 union {
210 u32 rtpkrmax; /* PRGM=1: poker max. limit register */
211 u32 rtpkrsq; /* PRGM=0: poker square calc. result register */
212 };
213#define RTSDCTL_ENT_DLY_SHIFT 16
214#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
215 u32 rtsdctl; /* seed control register */
216 union {
217 u32 rtsblim; /* PRGM=1: sparse bit limit register */
218 u32 rttotsam; /* PRGM=0: total samples register */
219 };
220 u32 rtfrqmin; /* frequency count min. limit register */
221 union {
222 u32 rtfrqmax; /* PRGM=1: freq. count max. limit register */
223 u32 rtfrqcnt; /* PRGM=0: freq. count register */
224 };
225 u32 rsvd1[56];
226};
227
203/* 228/*
204 * caam_ctrl - basic core configuration 229 * caam_ctrl - basic core configuration
205 * starts base + 0x0000 padded out to 0x1000 230 * starts base + 0x0000 padded out to 0x1000
@@ -249,7 +274,10 @@ struct caam_ctrl {
249 274
250 /* RNG Test/Verification/Debug Access 600-7ff */ 275 /* RNG Test/Verification/Debug Access 600-7ff */
251 /* (Useful in Test/Debug modes only...) */ 276 /* (Useful in Test/Debug modes only...) */
252 struct rngtst rtst[2]; 277 union {
278 struct rngtst rtst[2];
279 struct rng4tst r4tst[2];
280 };
253 281
254 u32 rsvd9[448]; 282 u32 rsvd9[448];
255 283