diff options
-rw-r--r-- | drivers/crypto/ccp/Makefile | 1 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-crypto-des3.c | 254 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-crypto-main.c | 10 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-crypto.h | 22 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-dev-v3.c | 1 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-dev-v5.c | 54 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-dev.h | 14 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-ops.c | 198 | ||||
-rw-r--r-- | include/linux/ccp.h | 57 |
9 files changed, 608 insertions, 3 deletions
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index 346ceb8f17bd..d2044b793aa8 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile | |||
@@ -12,4 +12,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ | |||
12 | ccp-crypto-aes.o \ | 12 | ccp-crypto-aes.o \ |
13 | ccp-crypto-aes-cmac.o \ | 13 | ccp-crypto-aes-cmac.o \ |
14 | ccp-crypto-aes-xts.o \ | 14 | ccp-crypto-aes-xts.o \ |
15 | ccp-crypto-des3.o \ | ||
15 | ccp-crypto-sha.o | 16 | ccp-crypto-sha.o |
diff --git a/drivers/crypto/ccp/ccp-crypto-des3.c b/drivers/crypto/ccp/ccp-crypto-des3.c new file mode 100644 index 000000000000..5af7347ae03c --- /dev/null +++ b/drivers/crypto/ccp/ccp-crypto-des3.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | * AMD Cryptographic Coprocessor (CCP) DES3 crypto API support | ||
3 | * | ||
4 | * Copyright (C) 2016 Advanced Micro Devices, Inc. | ||
5 | * | ||
6 | * Author: Gary R Hook <ghook@amd.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/scatterlist.h> | ||
17 | #include <linux/crypto.h> | ||
18 | #include <crypto/algapi.h> | ||
19 | #include <crypto/scatterwalk.h> | ||
20 | #include <crypto/des.h> | ||
21 | |||
22 | #include "ccp-crypto.h" | ||
23 | |||
24 | static int ccp_des3_complete(struct crypto_async_request *async_req, int ret) | ||
25 | { | ||
26 | struct ablkcipher_request *req = ablkcipher_request_cast(async_req); | ||
27 | struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
28 | struct ccp_des3_req_ctx *rctx = ablkcipher_request_ctx(req); | ||
29 | |||
30 | if (ret) | ||
31 | return ret; | ||
32 | |||
33 | if (ctx->u.des3.mode != CCP_DES3_MODE_ECB) | ||
34 | memcpy(req->info, rctx->iv, DES3_EDE_BLOCK_SIZE); | ||
35 | |||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int ccp_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, | ||
40 | unsigned int key_len) | ||
41 | { | ||
42 | struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm)); | ||
43 | struct ccp_crypto_ablkcipher_alg *alg = | ||
44 | ccp_crypto_ablkcipher_alg(crypto_ablkcipher_tfm(tfm)); | ||
45 | u32 *flags = &tfm->base.crt_flags; | ||
46 | |||
47 | |||
48 | /* From des_generic.c: | ||
49 | * | ||
50 | * RFC2451: | ||
51 | * If the first two or last two independent 64-bit keys are | ||
52 | * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the | ||
53 | * same as DES. Implementers MUST reject keys that exhibit this | ||
54 | * property. | ||
55 | */ | ||
56 | const u32 *K = (const u32 *)key; | ||
57 | |||
58 | if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || | ||
59 | !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && | ||
60 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | ||
61 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | |||
65 | /* It's not clear that there is any support for a keysize of 112. | ||
66 | * If needed, the caller should make K1 == K3 | ||
67 | */ | ||
68 | ctx->u.des3.type = CCP_DES3_TYPE_168; | ||
69 | ctx->u.des3.mode = alg->mode; | ||
70 | ctx->u.des3.key_len = key_len; | ||
71 | |||
72 | memcpy(ctx->u.des3.key, key, key_len); | ||
73 | sg_init_one(&ctx->u.des3.key_sg, ctx->u.des3.key, key_len); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int ccp_des3_crypt(struct ablkcipher_request *req, bool encrypt) | ||
79 | { | ||
80 | struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
81 | struct ccp_des3_req_ctx *rctx = ablkcipher_request_ctx(req); | ||
82 | struct scatterlist *iv_sg = NULL; | ||
83 | unsigned int iv_len = 0; | ||
84 | int ret; | ||
85 | |||
86 | if (!ctx->u.des3.key_len) | ||
87 | return -EINVAL; | ||
88 | |||
89 | if (((ctx->u.des3.mode == CCP_DES3_MODE_ECB) || | ||
90 | (ctx->u.des3.mode == CCP_DES3_MODE_CBC)) && | ||
91 | (req->nbytes & (DES3_EDE_BLOCK_SIZE - 1))) | ||
92 | return -EINVAL; | ||
93 | |||
94 | if (ctx->u.des3.mode != CCP_DES3_MODE_ECB) { | ||
95 | if (!req->info) | ||
96 | return -EINVAL; | ||
97 | |||
98 | memcpy(rctx->iv, req->info, DES3_EDE_BLOCK_SIZE); | ||
99 | iv_sg = &rctx->iv_sg; | ||
100 | iv_len = DES3_EDE_BLOCK_SIZE; | ||
101 | sg_init_one(iv_sg, rctx->iv, iv_len); | ||
102 | } | ||
103 | |||
104 | memset(&rctx->cmd, 0, sizeof(rctx->cmd)); | ||
105 | INIT_LIST_HEAD(&rctx->cmd.entry); | ||
106 | rctx->cmd.engine = CCP_ENGINE_DES3; | ||
107 | rctx->cmd.u.des3.type = ctx->u.des3.type; | ||
108 | rctx->cmd.u.des3.mode = ctx->u.des3.mode; | ||
109 | rctx->cmd.u.des3.action = (encrypt) | ||
110 | ? CCP_DES3_ACTION_ENCRYPT | ||
111 | : CCP_DES3_ACTION_DECRYPT; | ||
112 | rctx->cmd.u.des3.key = &ctx->u.des3.key_sg; | ||
113 | rctx->cmd.u.des3.key_len = ctx->u.des3.key_len; | ||
114 | rctx->cmd.u.des3.iv = iv_sg; | ||
115 | rctx->cmd.u.des3.iv_len = iv_len; | ||
116 | rctx->cmd.u.des3.src = req->src; | ||
117 | rctx->cmd.u.des3.src_len = req->nbytes; | ||
118 | rctx->cmd.u.des3.dst = req->dst; | ||
119 | |||
120 | ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd); | ||
121 | |||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | static int ccp_des3_encrypt(struct ablkcipher_request *req) | ||
126 | { | ||
127 | return ccp_des3_crypt(req, true); | ||
128 | } | ||
129 | |||
130 | static int ccp_des3_decrypt(struct ablkcipher_request *req) | ||
131 | { | ||
132 | return ccp_des3_crypt(req, false); | ||
133 | } | ||
134 | |||
135 | static int ccp_des3_cra_init(struct crypto_tfm *tfm) | ||
136 | { | ||
137 | struct ccp_ctx *ctx = crypto_tfm_ctx(tfm); | ||
138 | |||
139 | ctx->complete = ccp_des3_complete; | ||
140 | ctx->u.des3.key_len = 0; | ||
141 | |||
142 | tfm->crt_ablkcipher.reqsize = sizeof(struct ccp_des3_req_ctx); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void ccp_des3_cra_exit(struct crypto_tfm *tfm) | ||
148 | { | ||
149 | } | ||
150 | |||
151 | static struct crypto_alg ccp_des3_defaults = { | ||
152 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | | ||
153 | CRYPTO_ALG_ASYNC | | ||
154 | CRYPTO_ALG_KERN_DRIVER_ONLY | | ||
155 | CRYPTO_ALG_NEED_FALLBACK, | ||
156 | .cra_blocksize = DES3_EDE_BLOCK_SIZE, | ||
157 | .cra_ctxsize = sizeof(struct ccp_ctx), | ||
158 | .cra_priority = CCP_CRA_PRIORITY, | ||
159 | .cra_type = &crypto_ablkcipher_type, | ||
160 | .cra_init = ccp_des3_cra_init, | ||
161 | .cra_exit = ccp_des3_cra_exit, | ||
162 | .cra_module = THIS_MODULE, | ||
163 | .cra_ablkcipher = { | ||
164 | .setkey = ccp_des3_setkey, | ||
165 | .encrypt = ccp_des3_encrypt, | ||
166 | .decrypt = ccp_des3_decrypt, | ||
167 | .min_keysize = DES3_EDE_KEY_SIZE, | ||
168 | .max_keysize = DES3_EDE_KEY_SIZE, | ||
169 | }, | ||
170 | }; | ||
171 | |||
172 | struct ccp_des3_def { | ||
173 | enum ccp_des3_mode mode; | ||
174 | unsigned int version; | ||
175 | const char *name; | ||
176 | const char *driver_name; | ||
177 | unsigned int blocksize; | ||
178 | unsigned int ivsize; | ||
179 | struct crypto_alg *alg_defaults; | ||
180 | }; | ||
181 | |||
182 | static struct ccp_des3_def des3_algs[] = { | ||
183 | { | ||
184 | .mode = CCP_DES3_MODE_ECB, | ||
185 | .version = CCP_VERSION(5, 0), | ||
186 | .name = "ecb(des3_ede)", | ||
187 | .driver_name = "ecb-des3-ccp", | ||
188 | .blocksize = DES3_EDE_BLOCK_SIZE, | ||
189 | .ivsize = 0, | ||
190 | .alg_defaults = &ccp_des3_defaults, | ||
191 | }, | ||
192 | { | ||
193 | .mode = CCP_DES3_MODE_CBC, | ||
194 | .version = CCP_VERSION(5, 0), | ||
195 | .name = "cbc(des3_ede)", | ||
196 | .driver_name = "cbc-des3-ccp", | ||
197 | .blocksize = DES3_EDE_BLOCK_SIZE, | ||
198 | .ivsize = DES3_EDE_BLOCK_SIZE, | ||
199 | .alg_defaults = &ccp_des3_defaults, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static int ccp_register_des3_alg(struct list_head *head, | ||
204 | const struct ccp_des3_def *def) | ||
205 | { | ||
206 | struct ccp_crypto_ablkcipher_alg *ccp_alg; | ||
207 | struct crypto_alg *alg; | ||
208 | int ret; | ||
209 | |||
210 | ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); | ||
211 | if (!ccp_alg) | ||
212 | return -ENOMEM; | ||
213 | |||
214 | INIT_LIST_HEAD(&ccp_alg->entry); | ||
215 | |||
216 | ccp_alg->mode = def->mode; | ||
217 | |||
218 | /* Copy the defaults and override as necessary */ | ||
219 | alg = &ccp_alg->alg; | ||
220 | *alg = *def->alg_defaults; | ||
221 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name); | ||
222 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | ||
223 | def->driver_name); | ||
224 | alg->cra_blocksize = def->blocksize; | ||
225 | alg->cra_ablkcipher.ivsize = def->ivsize; | ||
226 | |||
227 | ret = crypto_register_alg(alg); | ||
228 | if (ret) { | ||
229 | pr_err("%s ablkcipher algorithm registration error (%d)\n", | ||
230 | alg->cra_name, ret); | ||
231 | kfree(ccp_alg); | ||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | list_add(&ccp_alg->entry, head); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | int ccp_register_des3_algs(struct list_head *head) | ||
241 | { | ||
242 | int i, ret; | ||
243 | unsigned int ccpversion = ccp_version(); | ||
244 | |||
245 | for (i = 0; i < ARRAY_SIZE(des3_algs); i++) { | ||
246 | if (des3_algs[i].version > ccpversion) | ||
247 | continue; | ||
248 | ret = ccp_register_des3_alg(head, &des3_algs[i]); | ||
249 | if (ret) | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | return 0; | ||
254 | } | ||
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c index e0380e59c361..3f1e36d7a8bf 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c | |||
@@ -33,6 +33,10 @@ static unsigned int sha_disable; | |||
33 | module_param(sha_disable, uint, 0444); | 33 | module_param(sha_disable, uint, 0444); |
34 | MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value"); | 34 | MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value"); |
35 | 35 | ||
36 | static unsigned int des3_disable; | ||
37 | module_param(des3_disable, uint, 0444); | ||
38 | MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value"); | ||
39 | |||
36 | /* List heads for the supported algorithms */ | 40 | /* List heads for the supported algorithms */ |
37 | static LIST_HEAD(hash_algs); | 41 | static LIST_HEAD(hash_algs); |
38 | static LIST_HEAD(cipher_algs); | 42 | static LIST_HEAD(cipher_algs); |
@@ -337,6 +341,12 @@ static int ccp_register_algs(void) | |||
337 | return ret; | 341 | return ret; |
338 | } | 342 | } |
339 | 343 | ||
344 | if (!des3_disable) { | ||
345 | ret = ccp_register_des3_algs(&cipher_algs); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | } | ||
349 | |||
340 | if (!sha_disable) { | 350 | if (!sha_disable) { |
341 | ret = ccp_register_sha_algs(&hash_algs); | 351 | ret = ccp_register_sha_algs(&hash_algs); |
342 | if (ret) | 352 | if (ret) |
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h index 95cce2764139..8c8bd3ff9f48 100644 --- a/drivers/crypto/ccp/ccp-crypto.h +++ b/drivers/crypto/ccp/ccp-crypto.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <crypto/hash.h> | 23 | #include <crypto/hash.h> |
24 | #include <crypto/sha.h> | 24 | #include <crypto/sha.h> |
25 | 25 | ||
26 | #define CCP_LOG_LEVEL KERN_INFO | ||
27 | |||
26 | #define CCP_CRA_PRIORITY 300 | 28 | #define CCP_CRA_PRIORITY 300 |
27 | 29 | ||
28 | struct ccp_crypto_ablkcipher_alg { | 30 | struct ccp_crypto_ablkcipher_alg { |
@@ -137,6 +139,24 @@ struct ccp_aes_cmac_exp_ctx { | |||
137 | u8 buf[AES_BLOCK_SIZE]; | 139 | u8 buf[AES_BLOCK_SIZE]; |
138 | }; | 140 | }; |
139 | 141 | ||
142 | /***** 3DES related defines *****/ | ||
143 | struct ccp_des3_ctx { | ||
144 | enum ccp_engine engine; | ||
145 | enum ccp_des3_type type; | ||
146 | enum ccp_des3_mode mode; | ||
147 | |||
148 | struct scatterlist key_sg; | ||
149 | unsigned int key_len; | ||
150 | u8 key[AES_MAX_KEY_SIZE]; | ||
151 | }; | ||
152 | |||
153 | struct ccp_des3_req_ctx { | ||
154 | struct scatterlist iv_sg; | ||
155 | u8 iv[AES_BLOCK_SIZE]; | ||
156 | |||
157 | struct ccp_cmd cmd; | ||
158 | }; | ||
159 | |||
140 | /* SHA-related defines | 160 | /* SHA-related defines |
141 | * These values must be large enough to accommodate any variant | 161 | * These values must be large enough to accommodate any variant |
142 | */ | 162 | */ |
@@ -201,6 +221,7 @@ struct ccp_ctx { | |||
201 | union { | 221 | union { |
202 | struct ccp_aes_ctx aes; | 222 | struct ccp_aes_ctx aes; |
203 | struct ccp_sha_ctx sha; | 223 | struct ccp_sha_ctx sha; |
224 | struct ccp_des3_ctx des3; | ||
204 | } u; | 225 | } u; |
205 | }; | 226 | }; |
206 | 227 | ||
@@ -213,5 +234,6 @@ int ccp_register_aes_algs(struct list_head *head); | |||
213 | int ccp_register_aes_cmac_algs(struct list_head *head); | 234 | int ccp_register_aes_cmac_algs(struct list_head *head); |
214 | int ccp_register_aes_xts_algs(struct list_head *head); | 235 | int ccp_register_aes_xts_algs(struct list_head *head); |
215 | int ccp_register_sha_algs(struct list_head *head); | 236 | int ccp_register_sha_algs(struct list_head *head); |
237 | int ccp_register_des3_algs(struct list_head *head); | ||
216 | 238 | ||
217 | #endif | 239 | #endif |
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 7bc09989e18a..a3689a66cb1d 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c | |||
@@ -553,6 +553,7 @@ static irqreturn_t ccp_irq_handler(int irq, void *data) | |||
553 | static const struct ccp_actions ccp3_actions = { | 553 | static const struct ccp_actions ccp3_actions = { |
554 | .aes = ccp_perform_aes, | 554 | .aes = ccp_perform_aes, |
555 | .xts_aes = ccp_perform_xts_aes, | 555 | .xts_aes = ccp_perform_xts_aes, |
556 | .des3 = NULL, | ||
556 | .sha = ccp_perform_sha, | 557 | .sha = ccp_perform_sha, |
557 | .rsa = ccp_perform_rsa, | 558 | .rsa = ccp_perform_rsa, |
558 | .passthru = ccp_perform_passthru, | 559 | .passthru = ccp_perform_passthru, |
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 41cc853f8569..fc5666eb59f2 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c | |||
@@ -108,6 +108,12 @@ union ccp_function { | |||
108 | u16 type:2; | 108 | u16 type:2; |
109 | } aes_xts; | 109 | } aes_xts; |
110 | struct { | 110 | struct { |
111 | u16 size:7; | ||
112 | u16 encrypt:1; | ||
113 | u16 mode:5; | ||
114 | u16 type:2; | ||
115 | } des3; | ||
116 | struct { | ||
111 | u16 rsvd1:10; | 117 | u16 rsvd1:10; |
112 | u16 type:4; | 118 | u16 type:4; |
113 | u16 rsvd2:1; | 119 | u16 rsvd2:1; |
@@ -139,6 +145,10 @@ union ccp_function { | |||
139 | #define CCP_AES_TYPE(p) ((p)->aes.type) | 145 | #define CCP_AES_TYPE(p) ((p)->aes.type) |
140 | #define CCP_XTS_SIZE(p) ((p)->aes_xts.size) | 146 | #define CCP_XTS_SIZE(p) ((p)->aes_xts.size) |
141 | #define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt) | 147 | #define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt) |
148 | #define CCP_DES3_SIZE(p) ((p)->des3.size) | ||
149 | #define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt) | ||
150 | #define CCP_DES3_MODE(p) ((p)->des3.mode) | ||
151 | #define CCP_DES3_TYPE(p) ((p)->des3.type) | ||
142 | #define CCP_SHA_TYPE(p) ((p)->sha.type) | 152 | #define CCP_SHA_TYPE(p) ((p)->sha.type) |
143 | #define CCP_RSA_SIZE(p) ((p)->rsa.size) | 153 | #define CCP_RSA_SIZE(p) ((p)->rsa.size) |
144 | #define CCP_PT_BYTESWAP(p) ((p)->pt.byteswap) | 154 | #define CCP_PT_BYTESWAP(p) ((p)->pt.byteswap) |
@@ -388,6 +398,47 @@ static int ccp5_perform_sha(struct ccp_op *op) | |||
388 | return ccp5_do_cmd(&desc, op->cmd_q); | 398 | return ccp5_do_cmd(&desc, op->cmd_q); |
389 | } | 399 | } |
390 | 400 | ||
401 | static int ccp5_perform_des3(struct ccp_op *op) | ||
402 | { | ||
403 | struct ccp5_desc desc; | ||
404 | union ccp_function function; | ||
405 | u32 key_addr = op->sb_key * LSB_ITEM_SIZE; | ||
406 | |||
407 | /* Zero out all the fields of the command desc */ | ||
408 | memset(&desc, 0, sizeof(struct ccp5_desc)); | ||
409 | |||
410 | CCP5_CMD_ENGINE(&desc) = CCP_ENGINE_DES3; | ||
411 | |||
412 | CCP5_CMD_SOC(&desc) = op->soc; | ||
413 | CCP5_CMD_IOC(&desc) = 1; | ||
414 | CCP5_CMD_INIT(&desc) = op->init; | ||
415 | CCP5_CMD_EOM(&desc) = op->eom; | ||
416 | CCP5_CMD_PROT(&desc) = 0; | ||
417 | |||
418 | function.raw = 0; | ||
419 | CCP_DES3_ENCRYPT(&function) = op->u.des3.action; | ||
420 | CCP_DES3_MODE(&function) = op->u.des3.mode; | ||
421 | CCP_DES3_TYPE(&function) = op->u.des3.type; | ||
422 | CCP5_CMD_FUNCTION(&desc) = cpu_to_le32(function.raw); | ||
423 | |||
424 | CCP5_CMD_LEN(&desc) = cpu_to_le32(op->src.u.dma.length); | ||
425 | |||
426 | CCP5_CMD_SRC_LO(&desc) = cpu_to_le32(ccp_addr_lo(&op->src.u.dma)); | ||
427 | CCP5_CMD_SRC_HI(&desc) = cpu_to_le32(ccp_addr_hi(&op->src.u.dma)); | ||
428 | CCP5_CMD_SRC_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SYSTEM); | ||
429 | |||
430 | CCP5_CMD_DST_LO(&desc) = cpu_to_le32(ccp_addr_lo(&op->dst.u.dma)); | ||
431 | CCP5_CMD_DST_HI(&desc) = cpu_to_le32(ccp_addr_hi(&op->dst.u.dma)); | ||
432 | CCP5_CMD_DST_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SYSTEM); | ||
433 | |||
434 | CCP5_CMD_KEY_LO(&desc) = cpu_to_le32(lower_32_bits(key_addr)); | ||
435 | CCP5_CMD_KEY_HI(&desc) = 0; | ||
436 | CCP5_CMD_KEY_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SB); | ||
437 | CCP5_CMD_LSB_ID(&desc) = cpu_to_le32(op->sb_ctx); | ||
438 | |||
439 | return ccp5_do_cmd(&desc, op->cmd_q); | ||
440 | } | ||
441 | |||
391 | static int ccp5_perform_rsa(struct ccp_op *op) | 442 | static int ccp5_perform_rsa(struct ccp_op *op) |
392 | { | 443 | { |
393 | struct ccp5_desc desc; | 444 | struct ccp5_desc desc; |
@@ -435,6 +486,7 @@ static int ccp5_perform_passthru(struct ccp_op *op) | |||
435 | struct ccp_dma_info *saddr = &op->src.u.dma; | 486 | struct ccp_dma_info *saddr = &op->src.u.dma; |
436 | struct ccp_dma_info *daddr = &op->dst.u.dma; | 487 | struct ccp_dma_info *daddr = &op->dst.u.dma; |
437 | 488 | ||
489 | |||
438 | memset(&desc, 0, Q_DESC_SIZE); | 490 | memset(&desc, 0, Q_DESC_SIZE); |
439 | 491 | ||
440 | CCP5_CMD_ENGINE(&desc) = CCP_ENGINE_PASSTHRU; | 492 | CCP5_CMD_ENGINE(&desc) = CCP_ENGINE_PASSTHRU; |
@@ -729,6 +781,7 @@ static int ccp5_init(struct ccp_device *ccp) | |||
729 | 781 | ||
730 | dev_dbg(dev, "queue #%u available\n", i); | 782 | dev_dbg(dev, "queue #%u available\n", i); |
731 | } | 783 | } |
784 | |||
732 | if (ccp->cmd_q_count == 0) { | 785 | if (ccp->cmd_q_count == 0) { |
733 | dev_notice(dev, "no command queues available\n"); | 786 | dev_notice(dev, "no command queues available\n"); |
734 | ret = -EIO; | 787 | ret = -EIO; |
@@ -994,6 +1047,7 @@ static const struct ccp_actions ccp5_actions = { | |||
994 | .aes = ccp5_perform_aes, | 1047 | .aes = ccp5_perform_aes, |
995 | .xts_aes = ccp5_perform_xts_aes, | 1048 | .xts_aes = ccp5_perform_xts_aes, |
996 | .sha = ccp5_perform_sha, | 1049 | .sha = ccp5_perform_sha, |
1050 | .des3 = ccp5_perform_des3, | ||
997 | .rsa = ccp5_perform_rsa, | 1051 | .rsa = ccp5_perform_rsa, |
998 | .passthru = ccp5_perform_passthru, | 1052 | .passthru = ccp5_perform_passthru, |
999 | .ecc = ccp5_perform_ecc, | 1053 | .ecc = ccp5_perform_ecc, |
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index 2b5c01fade05..754e9c2f6ee3 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h | |||
@@ -190,6 +190,9 @@ | |||
190 | #define CCP_XTS_AES_KEY_SB_COUNT 1 | 190 | #define CCP_XTS_AES_KEY_SB_COUNT 1 |
191 | #define CCP_XTS_AES_CTX_SB_COUNT 1 | 191 | #define CCP_XTS_AES_CTX_SB_COUNT 1 |
192 | 192 | ||
193 | #define CCP_DES3_KEY_SB_COUNT 1 | ||
194 | #define CCP_DES3_CTX_SB_COUNT 1 | ||
195 | |||
193 | #define CCP_SHA_SB_COUNT 1 | 196 | #define CCP_SHA_SB_COUNT 1 |
194 | 197 | ||
195 | #define CCP_RSA_MAX_WIDTH 4096 | 198 | #define CCP_RSA_MAX_WIDTH 4096 |
@@ -475,6 +478,12 @@ struct ccp_xts_aes_op { | |||
475 | enum ccp_xts_aes_unit_size unit_size; | 478 | enum ccp_xts_aes_unit_size unit_size; |
476 | }; | 479 | }; |
477 | 480 | ||
481 | struct ccp_des3_op { | ||
482 | enum ccp_des3_type type; | ||
483 | enum ccp_des3_mode mode; | ||
484 | enum ccp_des3_action action; | ||
485 | }; | ||
486 | |||
478 | struct ccp_sha_op { | 487 | struct ccp_sha_op { |
479 | enum ccp_sha_type type; | 488 | enum ccp_sha_type type; |
480 | u64 msg_bits; | 489 | u64 msg_bits; |
@@ -512,6 +521,7 @@ struct ccp_op { | |||
512 | union { | 521 | union { |
513 | struct ccp_aes_op aes; | 522 | struct ccp_aes_op aes; |
514 | struct ccp_xts_aes_op xts; | 523 | struct ccp_xts_aes_op xts; |
524 | struct ccp_des3_op des3; | ||
515 | struct ccp_sha_op sha; | 525 | struct ccp_sha_op sha; |
516 | struct ccp_rsa_op rsa; | 526 | struct ccp_rsa_op rsa; |
517 | struct ccp_passthru_op passthru; | 527 | struct ccp_passthru_op passthru; |
@@ -620,13 +630,13 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp); | |||
620 | struct ccp_actions { | 630 | struct ccp_actions { |
621 | int (*aes)(struct ccp_op *); | 631 | int (*aes)(struct ccp_op *); |
622 | int (*xts_aes)(struct ccp_op *); | 632 | int (*xts_aes)(struct ccp_op *); |
633 | int (*des3)(struct ccp_op *); | ||
623 | int (*sha)(struct ccp_op *); | 634 | int (*sha)(struct ccp_op *); |
624 | int (*rsa)(struct ccp_op *); | 635 | int (*rsa)(struct ccp_op *); |
625 | int (*passthru)(struct ccp_op *); | 636 | int (*passthru)(struct ccp_op *); |
626 | int (*ecc)(struct ccp_op *); | 637 | int (*ecc)(struct ccp_op *); |
627 | u32 (*sballoc)(struct ccp_cmd_queue *, unsigned int); | 638 | u32 (*sballoc)(struct ccp_cmd_queue *, unsigned int); |
628 | void (*sbfree)(struct ccp_cmd_queue *, unsigned int, | 639 | void (*sbfree)(struct ccp_cmd_queue *, unsigned int, unsigned int); |
629 | unsigned int); | ||
630 | unsigned int (*get_free_slots)(struct ccp_cmd_queue *); | 640 | unsigned int (*get_free_slots)(struct ccp_cmd_queue *); |
631 | int (*init)(struct ccp_device *); | 641 | int (*init)(struct ccp_device *); |
632 | void (*destroy)(struct ccp_device *); | 642 | void (*destroy)(struct ccp_device *); |
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index 0d820802cd92..0de961a22ab4 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <crypto/scatterwalk.h> | 18 | #include <crypto/scatterwalk.h> |
19 | #include <crypto/des.h> | ||
19 | #include <linux/ccp.h> | 20 | #include <linux/ccp.h> |
20 | 21 | ||
21 | #include "ccp-dev.h" | 22 | #include "ccp-dev.h" |
@@ -939,6 +940,200 @@ e_key: | |||
939 | return ret; | 940 | return ret; |
940 | } | 941 | } |
941 | 942 | ||
943 | static int ccp_run_des3_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) | ||
944 | { | ||
945 | struct ccp_des3_engine *des3 = &cmd->u.des3; | ||
946 | |||
947 | struct ccp_dm_workarea key, ctx; | ||
948 | struct ccp_data src, dst; | ||
949 | struct ccp_op op; | ||
950 | unsigned int dm_offset; | ||
951 | unsigned int len_singlekey; | ||
952 | bool in_place = false; | ||
953 | int ret; | ||
954 | |||
955 | /* Error checks */ | ||
956 | if (!cmd_q->ccp->vdata->perform->des3) | ||
957 | return -EINVAL; | ||
958 | |||
959 | if (des3->key_len != DES3_EDE_KEY_SIZE) | ||
960 | return -EINVAL; | ||
961 | |||
962 | if (((des3->mode == CCP_DES3_MODE_ECB) || | ||
963 | (des3->mode == CCP_DES3_MODE_CBC)) && | ||
964 | (des3->src_len & (DES3_EDE_BLOCK_SIZE - 1))) | ||
965 | return -EINVAL; | ||
966 | |||
967 | if (!des3->key || !des3->src || !des3->dst) | ||
968 | return -EINVAL; | ||
969 | |||
970 | if (des3->mode != CCP_DES3_MODE_ECB) { | ||
971 | if (des3->iv_len != DES3_EDE_BLOCK_SIZE) | ||
972 | return -EINVAL; | ||
973 | |||
974 | if (!des3->iv) | ||
975 | return -EINVAL; | ||
976 | } | ||
977 | |||
978 | ret = -EIO; | ||
979 | /* Zero out all the fields of the command desc */ | ||
980 | memset(&op, 0, sizeof(op)); | ||
981 | |||
982 | /* Set up the Function field */ | ||
983 | op.cmd_q = cmd_q; | ||
984 | op.jobid = CCP_NEW_JOBID(cmd_q->ccp); | ||
985 | op.sb_key = cmd_q->sb_key; | ||
986 | |||
987 | op.init = (des3->mode == CCP_DES3_MODE_ECB) ? 0 : 1; | ||
988 | op.u.des3.type = des3->type; | ||
989 | op.u.des3.mode = des3->mode; | ||
990 | op.u.des3.action = des3->action; | ||
991 | |||
992 | /* | ||
993 | * All supported key sizes fit in a single (32-byte) KSB entry and | ||
994 | * (like AES) must be in little endian format. Use the 256-bit byte | ||
995 | * swap passthru option to convert from big endian to little endian. | ||
996 | */ | ||
997 | ret = ccp_init_dm_workarea(&key, cmd_q, | ||
998 | CCP_DES3_KEY_SB_COUNT * CCP_SB_BYTES, | ||
999 | DMA_TO_DEVICE); | ||
1000 | if (ret) | ||
1001 | return ret; | ||
1002 | |||
1003 | /* | ||
1004 | * The contents of the key triplet are in the reverse order of what | ||
1005 | * is required by the engine. Copy the 3 pieces individually to put | ||
1006 | * them where they belong. | ||
1007 | */ | ||
1008 | dm_offset = CCP_SB_BYTES - des3->key_len; /* Basic offset */ | ||
1009 | |||
1010 | len_singlekey = des3->key_len / 3; | ||
1011 | ccp_set_dm_area(&key, dm_offset + 2 * len_singlekey, | ||
1012 | des3->key, 0, len_singlekey); | ||
1013 | ccp_set_dm_area(&key, dm_offset + len_singlekey, | ||
1014 | des3->key, len_singlekey, len_singlekey); | ||
1015 | ccp_set_dm_area(&key, dm_offset, | ||
1016 | des3->key, 2 * len_singlekey, len_singlekey); | ||
1017 | |||
1018 | /* Copy the key to the SB */ | ||
1019 | ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key, | ||
1020 | CCP_PASSTHRU_BYTESWAP_256BIT); | ||
1021 | if (ret) { | ||
1022 | cmd->engine_error = cmd_q->cmd_error; | ||
1023 | goto e_key; | ||
1024 | } | ||
1025 | |||
1026 | /* | ||
1027 | * The DES3 context fits in a single (32-byte) KSB entry and | ||
1028 | * must be in little endian format. Use the 256-bit byte swap | ||
1029 | * passthru option to convert from big endian to little endian. | ||
1030 | */ | ||
1031 | if (des3->mode != CCP_DES3_MODE_ECB) { | ||
1032 | u32 load_mode; | ||
1033 | |||
1034 | op.sb_ctx = cmd_q->sb_ctx; | ||
1035 | |||
1036 | ret = ccp_init_dm_workarea(&ctx, cmd_q, | ||
1037 | CCP_DES3_CTX_SB_COUNT * CCP_SB_BYTES, | ||
1038 | DMA_BIDIRECTIONAL); | ||
1039 | if (ret) | ||
1040 | goto e_key; | ||
1041 | |||
1042 | /* Load the context into the LSB */ | ||
1043 | dm_offset = CCP_SB_BYTES - des3->iv_len; | ||
1044 | ccp_set_dm_area(&ctx, dm_offset, des3->iv, 0, des3->iv_len); | ||
1045 | |||
1046 | if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) | ||
1047 | load_mode = CCP_PASSTHRU_BYTESWAP_NOOP; | ||
1048 | else | ||
1049 | load_mode = CCP_PASSTHRU_BYTESWAP_256BIT; | ||
1050 | ret = ccp_copy_to_sb(cmd_q, &ctx, op.jobid, op.sb_ctx, | ||
1051 | load_mode); | ||
1052 | if (ret) { | ||
1053 | cmd->engine_error = cmd_q->cmd_error; | ||
1054 | goto e_ctx; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | /* | ||
1059 | * Prepare the input and output data workareas. For in-place | ||
1060 | * operations we need to set the dma direction to BIDIRECTIONAL | ||
1061 | * and copy the src workarea to the dst workarea. | ||
1062 | */ | ||
1063 | if (sg_virt(des3->src) == sg_virt(des3->dst)) | ||
1064 | in_place = true; | ||
1065 | |||
1066 | ret = ccp_init_data(&src, cmd_q, des3->src, des3->src_len, | ||
1067 | DES3_EDE_BLOCK_SIZE, | ||
1068 | in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); | ||
1069 | if (ret) | ||
1070 | goto e_ctx; | ||
1071 | |||
1072 | if (in_place) | ||
1073 | dst = src; | ||
1074 | else { | ||
1075 | ret = ccp_init_data(&dst, cmd_q, des3->dst, des3->src_len, | ||
1076 | DES3_EDE_BLOCK_SIZE, DMA_FROM_DEVICE); | ||
1077 | if (ret) | ||
1078 | goto e_src; | ||
1079 | } | ||
1080 | |||
1081 | /* Send data to the CCP DES3 engine */ | ||
1082 | while (src.sg_wa.bytes_left) { | ||
1083 | ccp_prepare_data(&src, &dst, &op, DES3_EDE_BLOCK_SIZE, true); | ||
1084 | if (!src.sg_wa.bytes_left) { | ||
1085 | op.eom = 1; | ||
1086 | |||
1087 | /* Since we don't retrieve the context in ECB mode | ||
1088 | * we have to wait for the operation to complete | ||
1089 | * on the last piece of data | ||
1090 | */ | ||
1091 | op.soc = 0; | ||
1092 | } | ||
1093 | |||
1094 | ret = cmd_q->ccp->vdata->perform->des3(&op); | ||
1095 | if (ret) { | ||
1096 | cmd->engine_error = cmd_q->cmd_error; | ||
1097 | goto e_dst; | ||
1098 | } | ||
1099 | |||
1100 | ccp_process_data(&src, &dst, &op); | ||
1101 | } | ||
1102 | |||
1103 | if (des3->mode != CCP_DES3_MODE_ECB) { | ||
1104 | /* Retrieve the context and make BE */ | ||
1105 | ret = ccp_copy_from_sb(cmd_q, &ctx, op.jobid, op.sb_ctx, | ||
1106 | CCP_PASSTHRU_BYTESWAP_256BIT); | ||
1107 | if (ret) { | ||
1108 | cmd->engine_error = cmd_q->cmd_error; | ||
1109 | goto e_dst; | ||
1110 | } | ||
1111 | |||
1112 | /* ...but we only need the last DES3_EDE_BLOCK_SIZE bytes */ | ||
1113 | if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) | ||
1114 | dm_offset = CCP_SB_BYTES - des3->iv_len; | ||
1115 | else | ||
1116 | dm_offset = 0; | ||
1117 | ccp_get_dm_area(&ctx, dm_offset, des3->iv, 0, | ||
1118 | DES3_EDE_BLOCK_SIZE); | ||
1119 | } | ||
1120 | e_dst: | ||
1121 | if (!in_place) | ||
1122 | ccp_free_data(&dst, cmd_q); | ||
1123 | |||
1124 | e_src: | ||
1125 | ccp_free_data(&src, cmd_q); | ||
1126 | |||
1127 | e_ctx: | ||
1128 | if (des3->mode != CCP_DES3_MODE_ECB) | ||
1129 | ccp_dm_free(&ctx); | ||
1130 | |||
1131 | e_key: | ||
1132 | ccp_dm_free(&key); | ||
1133 | |||
1134 | return ret; | ||
1135 | } | ||
1136 | |||
942 | static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) | 1137 | static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) |
943 | { | 1138 | { |
944 | struct ccp_sha_engine *sha = &cmd->u.sha; | 1139 | struct ccp_sha_engine *sha = &cmd->u.sha; |
@@ -1903,6 +2098,9 @@ int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) | |||
1903 | case CCP_ENGINE_XTS_AES_128: | 2098 | case CCP_ENGINE_XTS_AES_128: |
1904 | ret = ccp_run_xts_aes_cmd(cmd_q, cmd); | 2099 | ret = ccp_run_xts_aes_cmd(cmd_q, cmd); |
1905 | break; | 2100 | break; |
2101 | case CCP_ENGINE_DES3: | ||
2102 | ret = ccp_run_des3_cmd(cmd_q, cmd); | ||
2103 | break; | ||
1906 | case CCP_ENGINE_SHA: | 2104 | case CCP_ENGINE_SHA: |
1907 | ret = ccp_run_sha_cmd(cmd_q, cmd); | 2105 | ret = ccp_run_sha_cmd(cmd_q, cmd); |
1908 | break; | 2106 | break; |
diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 90a1fbe84219..fa0261748920 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h | |||
@@ -292,6 +292,60 @@ struct ccp_sha_engine { | |||
292 | * final sha cmd */ | 292 | * final sha cmd */ |
293 | }; | 293 | }; |
294 | 294 | ||
295 | /***** 3DES engine *****/ | ||
296 | enum ccp_des3_mode { | ||
297 | CCP_DES3_MODE_ECB = 0, | ||
298 | CCP_DES3_MODE_CBC, | ||
299 | CCP_DES3_MODE_CFB, | ||
300 | CCP_DES3_MODE__LAST, | ||
301 | }; | ||
302 | |||
303 | enum ccp_des3_type { | ||
304 | CCP_DES3_TYPE_168 = 1, | ||
305 | CCP_DES3_TYPE__LAST, | ||
306 | }; | ||
307 | |||
308 | enum ccp_des3_action { | ||
309 | CCP_DES3_ACTION_DECRYPT = 0, | ||
310 | CCP_DES3_ACTION_ENCRYPT, | ||
311 | CCP_DES3_ACTION__LAST, | ||
312 | }; | ||
313 | |||
314 | /** | ||
315 | * struct ccp_des3_engine - CCP SHA operation | ||
316 | * @type: Type of 3DES operation | ||
317 | * @mode: cipher mode | ||
318 | * @action: 3DES operation (decrypt/encrypt) | ||
319 | * @key: key to be used for this 3DES operation | ||
320 | * @key_len: length of key (in bytes) | ||
321 | * @iv: IV to be used for this AES operation | ||
322 | * @iv_len: length in bytes of iv | ||
323 | * @src: input data to be used for this operation | ||
324 | * @src_len: length of input data used for this operation (in bytes) | ||
325 | * @dst: output data produced by this operation | ||
326 | * | ||
327 | * Variables required to be set when calling ccp_enqueue_cmd(): | ||
328 | * - type, mode, action, key, key_len, src, dst, src_len | ||
329 | * - iv, iv_len for any mode other than ECB | ||
330 | * | ||
331 | * The iv variable is used as both input and output. On completion of the | ||
332 | * 3DES operation the new IV overwrites the old IV. | ||
333 | */ | ||
334 | struct ccp_des3_engine { | ||
335 | enum ccp_des3_type type; | ||
336 | enum ccp_des3_mode mode; | ||
337 | enum ccp_des3_action action; | ||
338 | |||
339 | struct scatterlist *key; | ||
340 | u32 key_len; /* In bytes */ | ||
341 | |||
342 | struct scatterlist *iv; | ||
343 | u32 iv_len; /* In bytes */ | ||
344 | |||
345 | struct scatterlist *src, *dst; | ||
346 | u64 src_len; /* In bytes */ | ||
347 | }; | ||
348 | |||
295 | /***** RSA engine *****/ | 349 | /***** RSA engine *****/ |
296 | /** | 350 | /** |
297 | * struct ccp_rsa_engine - CCP RSA operation | 351 | * struct ccp_rsa_engine - CCP RSA operation |
@@ -541,7 +595,7 @@ struct ccp_ecc_engine { | |||
541 | enum ccp_engine { | 595 | enum ccp_engine { |
542 | CCP_ENGINE_AES = 0, | 596 | CCP_ENGINE_AES = 0, |
543 | CCP_ENGINE_XTS_AES_128, | 597 | CCP_ENGINE_XTS_AES_128, |
544 | CCP_ENGINE_RSVD1, | 598 | CCP_ENGINE_DES3, |
545 | CCP_ENGINE_SHA, | 599 | CCP_ENGINE_SHA, |
546 | CCP_ENGINE_RSA, | 600 | CCP_ENGINE_RSA, |
547 | CCP_ENGINE_PASSTHRU, | 601 | CCP_ENGINE_PASSTHRU, |
@@ -589,6 +643,7 @@ struct ccp_cmd { | |||
589 | union { | 643 | union { |
590 | struct ccp_aes_engine aes; | 644 | struct ccp_aes_engine aes; |
591 | struct ccp_xts_aes_engine xts; | 645 | struct ccp_xts_aes_engine xts; |
646 | struct ccp_des3_engine des3; | ||
592 | struct ccp_sha_engine sha; | 647 | struct ccp_sha_engine sha; |
593 | struct ccp_rsa_engine rsa; | 648 | struct ccp_rsa_engine rsa; |
594 | struct ccp_passthru_engine passthru; | 649 | struct ccp_passthru_engine passthru; |