915a2cdb47faba84db0b2371d4f5f26c7b48298a
[openwrt/staging/ldir.git] /
1 From df1b397d7c5e79052fa56d1b256ededcd301a27a Mon Sep 17 00:00:00 2001
2 From: Franck LENORMAND <franck.lenormand@nxp.com>
3 Date: Fri, 5 Oct 2018 16:41:54 +0200
4 Subject: [PATCH] MLK-19801-2 crypto: caam - add support of tagged keys in
5 caamalg
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 A tagged key is a key which has been tagged with metadata
11 using tag_object.h API.
12
13 We add the support for these keys to caamalg.
14
15 For each algo of caamalg which supports tagged keys , it is done by:
16 - Creating a modified version of the algo
17 - Registering the modified version
18 - When the modified transform is used, it gets
19 the load parameter of the key.
20
21 Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
22 (cherry picked from commit 88dee97d985890dbf37cafa7934c476d0ecfd0b3)
23 (Vipul: Fixed merge conflicts)
24 Conflicts:
25 drivers/crypto/caam/caamalg.c
26 Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
27 (cherry picked from commit 5adebac40a7a8065c074f4a69f4ad760c67233f5)
28
29 -port from ablkcipher to current skcipher implementation
30 -since in linux-imx true key_inline was always true: a. simplify
31 the descriptors and b. use key_cmd_opt to differentiate b/w tk and non-tk
32 cases
33 -change commit headline prefix
34
35 Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
36 ---
37 drivers/crypto/caam/Makefile | 3 +-
38 drivers/crypto/caam/caamalg.c | 91 +++++++++++++++++++++++++++++++++++++-
39 drivers/crypto/caam/caamalg_desc.c | 20 +++++++--
40 drivers/crypto/caam/desc_constr.h | 4 ++
41 drivers/crypto/caam/tag_object.c | 6 +--
42 drivers/crypto/caam/tag_object.h | 6 +--
43 6 files changed, 118 insertions(+), 12 deletions(-)
44
45 --- a/drivers/crypto/caam/Makefile
46 +++ b/drivers/crypto/caam/Makefile
47 @@ -15,6 +15,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_
48 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
49
50 caam-y := ctrl.o
51 +caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
52 caam_jr-y := jr.o key_gen.o
53 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
54 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
55 @@ -24,7 +25,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC
56 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o
57 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o
58 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
59 -caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
60 +#caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
61
62 caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
63 ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
64 --- a/drivers/crypto/caam/caamalg.c
65 +++ b/drivers/crypto/caam/caamalg.c
66 @@ -57,6 +57,10 @@
67 #include "key_gen.h"
68 #include "caamalg_desc.h"
69
70 +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
71 +#include "tag_object.h"
72 +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
73 +
74 /*
75 * crypto alg
76 */
77 @@ -83,6 +87,7 @@ struct caam_alg_entry {
78 bool rfc3686;
79 bool geniv;
80 bool nodkp;
81 + bool support_tagged_key;
82 };
83
84 struct caam_aead_alg {
85 @@ -739,6 +744,44 @@ static int skcipher_setkey(struct crypto
86 ctx->cdata.key_virt = key;
87 ctx->cdata.key_inline = true;
88
89 +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
90 + /*
91 + * Check if the key is not in plaintext format
92 + */
93 + if (alg->caam.support_tagged_key) {
94 + struct tag_object_conf *tagged_key_conf;
95 + int ret;
96 +
97 + /* Get the configuration */
98 + ret = get_tag_object_conf(ctx->cdata.key_virt,
99 + ctx->cdata.keylen, &tagged_key_conf);
100 + if (ret) {
101 + dev_err(jrdev,
102 + "caam algorithms can't process tagged key\n");
103 + return ret;
104 + }
105 +
106 + /* Only support black key */
107 + if (!is_bk_conf(tagged_key_conf)) {
108 + dev_err(jrdev,
109 + "The tagged key provided is not a black key\n");
110 + return -EINVAL;
111 + }
112 +
113 + get_blackey_conf(&tagged_key_conf->conf.bk_conf,
114 + &ctx->cdata.key_real_len,
115 + &ctx->cdata.key_cmd_opt);
116 +
117 + ret = get_tagged_data(ctx->cdata.key_virt, ctx->cdata.keylen,
118 + &ctx->cdata.key_virt, &ctx->cdata.keylen);
119 + if (ret) {
120 + dev_err(jrdev,
121 + "caam algorithms wrong data from tagged key\n");
122 + return ret;
123 + }
124 + }
125 +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
126 +
127 /* skcipher_encrypt shared descriptor */
128 desc = ctx->sh_desc_enc;
129 cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
130 @@ -824,6 +867,14 @@ static int arc4_skcipher_setkey(struct c
131 return skcipher_setkey(skcipher, key, keylen, 0);
132 }
133
134 +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
135 +static int tk_skcipher_setkey(struct crypto_skcipher *skcipher,
136 + const u8 *key, unsigned int keylen)
137 +{
138 + return skcipher_setkey(skcipher, key, keylen, 0);
139 +}
140 +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
141 +
142 static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
143 const u8 *key, unsigned int keylen)
144 {
145 @@ -1924,6 +1975,25 @@ static struct caam_skcipher_alg driver_a
146 },
147 .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
148 },
149 +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
150 + {
151 + .skcipher = {
152 + .base = {
153 + .cra_name = "tk(cbc(aes))",
154 + .cra_driver_name = "tk-cbc-aes-caam",
155 + .cra_blocksize = AES_BLOCK_SIZE,
156 + },
157 + .setkey = tk_skcipher_setkey,
158 + .encrypt = skcipher_encrypt,
159 + .decrypt = skcipher_decrypt,
160 + .min_keysize = TAG_MIN_SIZE,
161 + .max_keysize = CAAM_MAX_KEY_SIZE,
162 + .ivsize = AES_BLOCK_SIZE,
163 + },
164 + .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
165 + .caam.support_tagged_key = true,
166 + },
167 +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
168 {
169 .skcipher = {
170 .base = {
171 @@ -2043,6 +2113,24 @@ static struct caam_skcipher_alg driver_a
172 },
173 .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
174 },
175 +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
176 + {
177 + .skcipher = {
178 + .base = {
179 + .cra_name = "tk(ecb(aes))",
180 + .cra_driver_name = "tk-ecb-aes-caam",
181 + .cra_blocksize = AES_BLOCK_SIZE,
182 + },
183 + .setkey = tk_skcipher_setkey,
184 + .encrypt = skcipher_encrypt,
185 + .decrypt = skcipher_decrypt,
186 + .min_keysize = TAG_MIN_SIZE,
187 + .max_keysize = CAAM_MAX_KEY_SIZE,
188 + },
189 + .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
190 + .caam.support_tagged_key = true,
191 + },
192 +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
193 {
194 .skcipher = {
195 .base = {
196 @@ -3507,7 +3595,8 @@ static void caam_skcipher_alg_init(struc
197 struct skcipher_alg *alg = &t_alg->skcipher;
198
199 alg->base.cra_module = THIS_MODULE;
200 - alg->base.cra_priority = CAAM_CRA_PRIORITY;
201 + alg->base.cra_priority =
202 + t_alg->caam.support_tagged_key ? 1 : CAAM_CRA_PRIORITY;
203 alg->base.cra_ctxsize = sizeof(struct caam_ctx);
204 alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
205
206 --- a/drivers/crypto/caam/caamalg_desc.c
207 +++ b/drivers/crypto/caam/caamalg_desc.c
208 @@ -1386,8 +1386,14 @@ void cnstr_shdsc_skcipher_encap(u32 * co
209 JUMP_COND_SHRD);
210
211 /* Load class1 key only */
212 - append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
213 - cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
214 + if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) &&
215 + cdata->key_cmd_opt)
216 + append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
217 + cdata->key_real_len, CLASS_1 |
218 + KEY_DEST_CLASS_REG | cdata->key_cmd_opt);
219 + else
220 + append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
221 + cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
222
223 /* Load nonce into CONTEXT1 reg */
224 if (is_rfc3686) {
225 @@ -1458,8 +1464,14 @@ void cnstr_shdsc_skcipher_decap(u32 * co
226 JUMP_COND_SHRD);
227
228 /* Load class1 key only */
229 - append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
230 - cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
231 + if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) &&
232 + cdata->key_cmd_opt)
233 + append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
234 + cdata->key_real_len, CLASS_1 |
235 + KEY_DEST_CLASS_REG | cdata->key_cmd_opt);
236 + else
237 + append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
238 + cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
239
240 /* Load nonce into CONTEXT1 reg */
241 if (is_rfc3686) {
242 --- a/drivers/crypto/caam/desc_constr.h
243 +++ b/drivers/crypto/caam/desc_constr.h
244 @@ -500,6 +500,8 @@ do { \
245 * @key_virt: virtual address where algorithm key resides
246 * @key_inline: true - key can be inlined in the descriptor; false - key is
247 * referenced by the descriptor
248 + * @key_real_len: size of the key to be loaded by the CAAM
249 + * @key_cmd_opt: optional parameters for KEY command
250 */
251 struct alginfo {
252 u32 algtype;
253 @@ -508,6 +510,8 @@ struct alginfo {
254 dma_addr_t key_dma;
255 const void *key_virt;
256 bool key_inline;
257 + u32 key_real_len;
258 + u32 key_cmd_opt;
259 };
260
261 /**
262 --- a/drivers/crypto/caam/tag_object.c
263 +++ b/drivers/crypto/caam/tag_object.c
264 @@ -128,7 +128,7 @@ EXPORT_SYMBOL(is_valid_tag_object_conf);
265 *
266 * Return: 0 if success, else error code
267 */
268 -int get_tag_object_conf(void *buffer, size_t size,
269 +int get_tag_object_conf(const void *buffer, size_t size,
270 struct tag_object_conf **tag_obj_conf)
271 {
272 bool is_valid;
273 @@ -240,8 +240,8 @@ EXPORT_SYMBOL(get_blackey_conf);
274 *
275 * Return: 0 if success, else error code
276 */
277 -int get_tagged_data(void *tagged_object, size_t tagged_object_size,
278 - void **data, u32 *data_size)
279 +int get_tagged_data(const void *tagged_object, size_t tagged_object_size,
280 + const void **data, u32 *data_size)
281 {
282 struct tagged_object *tago =
283 (struct tagged_object *)tagged_object;
284 --- a/drivers/crypto/caam/tag_object.h
285 +++ b/drivers/crypto/caam/tag_object.h
286 @@ -80,7 +80,7 @@ bool is_valid_tag_object_conf(const stru
287 void init_tag_object_header(struct conf_header *conf_header,
288 enum tag_type type);
289
290 -int get_tag_object_conf(void *buffer, size_t buffer_size,
291 +int get_tag_object_conf(const void *buffer, size_t buffer_size,
292 struct tag_object_conf **tag_obj_conf);
293
294 int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf,
295 @@ -94,7 +94,7 @@ void get_blackey_conf(const struct black
296 void init_blackey_conf(struct blackey_conf *blackey_conf,
297 size_t len, bool ccm, bool tk);
298
299 -int get_tagged_data(void *buffer, size_t buffer_size,
300 - void **data, u32 *data_size);
301 +int get_tagged_data(const void *buffer, size_t buffer_size,
302 + const void **data, u32 *data_size);
303
304 #endif /* _TAG_OBJECT_H_ */