]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/crypto/ccp/ccp-crypto-aes.c
crypto: ccp - CCP AES crypto API support
[karo-tx-linux.git] / drivers / crypto / ccp / ccp-crypto-aes.c
1 /*
2  * AMD Cryptographic Coprocessor (CCP) AES crypto API support
3  *
4  * Copyright (C) 2013 Advanced Micro Devices, Inc.
5  *
6  * Author: Tom Lendacky <thomas.lendacky@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/aes.h>
20 #include <crypto/ctr.h>
21 #include <crypto/scatterwalk.h>
22
23 #include "ccp-crypto.h"
24
25
26 static int ccp_aes_complete(struct crypto_async_request *async_req, int ret)
27 {
28         struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
29         struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
30         struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
31
32         if (ret)
33                 return ret;
34
35         if (ctx->u.aes.mode != CCP_AES_MODE_ECB)
36                 memcpy(req->info, rctx->iv, AES_BLOCK_SIZE);
37
38         return 0;
39 }
40
41 static int ccp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
42                           unsigned int key_len)
43 {
44         struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
45         struct ccp_crypto_ablkcipher_alg *alg =
46                 ccp_crypto_ablkcipher_alg(crypto_ablkcipher_tfm(tfm));
47
48         switch (key_len) {
49         case AES_KEYSIZE_128:
50                 ctx->u.aes.type = CCP_AES_TYPE_128;
51                 break;
52         case AES_KEYSIZE_192:
53                 ctx->u.aes.type = CCP_AES_TYPE_192;
54                 break;
55         case AES_KEYSIZE_256:
56                 ctx->u.aes.type = CCP_AES_TYPE_256;
57                 break;
58         default:
59                 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
60                 return -EINVAL;
61         }
62         ctx->u.aes.mode = alg->mode;
63         ctx->u.aes.key_len = key_len;
64
65         memcpy(ctx->u.aes.key, key, key_len);
66         sg_init_one(&ctx->u.aes.key_sg, ctx->u.aes.key, key_len);
67
68         return 0;
69 }
70
71 static int ccp_aes_crypt(struct ablkcipher_request *req, bool encrypt)
72 {
73         struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
74         struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
75         struct scatterlist *iv_sg = NULL;
76         unsigned int iv_len = 0;
77         int ret;
78
79         if (!ctx->u.aes.key_len) {
80                 pr_err("AES key not set\n");
81                 return -EINVAL;
82         }
83
84         if (((ctx->u.aes.mode == CCP_AES_MODE_ECB) ||
85              (ctx->u.aes.mode == CCP_AES_MODE_CBC) ||
86              (ctx->u.aes.mode == CCP_AES_MODE_CFB)) &&
87             (req->nbytes & (AES_BLOCK_SIZE - 1))) {
88                 pr_err("AES request size is not a multiple of the block size\n");
89                 return -EINVAL;
90         }
91
92         if (ctx->u.aes.mode != CCP_AES_MODE_ECB) {
93                 if (!req->info) {
94                         pr_err("AES IV not supplied");
95                         return -EINVAL;
96                 }
97
98                 memcpy(rctx->iv, req->info, AES_BLOCK_SIZE);
99                 iv_sg = &rctx->iv_sg;
100                 iv_len = AES_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_AES;
107         rctx->cmd.u.aes.type = ctx->u.aes.type;
108         rctx->cmd.u.aes.mode = ctx->u.aes.mode;
109         rctx->cmd.u.aes.action =
110                 (encrypt) ? CCP_AES_ACTION_ENCRYPT : CCP_AES_ACTION_DECRYPT;
111         rctx->cmd.u.aes.key = &ctx->u.aes.key_sg;
112         rctx->cmd.u.aes.key_len = ctx->u.aes.key_len;
113         rctx->cmd.u.aes.iv = iv_sg;
114         rctx->cmd.u.aes.iv_len = iv_len;
115         rctx->cmd.u.aes.src = req->src;
116         rctx->cmd.u.aes.src_len = req->nbytes;
117         rctx->cmd.u.aes.dst = req->dst;
118
119         ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd);
120
121         return ret;
122 }
123
124 static int ccp_aes_encrypt(struct ablkcipher_request *req)
125 {
126         return ccp_aes_crypt(req, true);
127 }
128
129 static int ccp_aes_decrypt(struct ablkcipher_request *req)
130 {
131         return ccp_aes_crypt(req, false);
132 }
133
134 static int ccp_aes_cra_init(struct crypto_tfm *tfm)
135 {
136         struct ccp_ctx *ctx = crypto_tfm_ctx(tfm);
137
138         ctx->complete = ccp_aes_complete;
139         ctx->u.aes.key_len = 0;
140
141         tfm->crt_ablkcipher.reqsize = sizeof(struct ccp_aes_req_ctx);
142
143         return 0;
144 }
145
146 static void ccp_aes_cra_exit(struct crypto_tfm *tfm)
147 {
148 }
149
150 static int ccp_aes_rfc3686_complete(struct crypto_async_request *async_req,
151                                     int ret)
152 {
153         struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
154         struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
155
156         /* Restore the original pointer */
157         req->info = rctx->rfc3686_info;
158
159         return ccp_aes_complete(async_req, ret);
160 }
161
162 static int ccp_aes_rfc3686_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
163                                   unsigned int key_len)
164 {
165         struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
166
167         if (key_len < CTR_RFC3686_NONCE_SIZE)
168                 return -EINVAL;
169
170         key_len -= CTR_RFC3686_NONCE_SIZE;
171         memcpy(ctx->u.aes.nonce, key + key_len, CTR_RFC3686_NONCE_SIZE);
172
173         return ccp_aes_setkey(tfm, key, key_len);
174 }
175
176 static int ccp_aes_rfc3686_crypt(struct ablkcipher_request *req, bool encrypt)
177 {
178         struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
179         struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
180         u8 *iv;
181
182         /* Initialize the CTR block */
183         iv = rctx->rfc3686_iv;
184         memcpy(iv, ctx->u.aes.nonce, CTR_RFC3686_NONCE_SIZE);
185
186         iv += CTR_RFC3686_NONCE_SIZE;
187         memcpy(iv, req->info, CTR_RFC3686_IV_SIZE);
188
189         iv += CTR_RFC3686_IV_SIZE;
190         *(__be32 *)iv = cpu_to_be32(1);
191
192         /* Point to the new IV */
193         rctx->rfc3686_info = req->info;
194         req->info = rctx->rfc3686_iv;
195
196         return ccp_aes_crypt(req, encrypt);
197 }
198
199 static int ccp_aes_rfc3686_encrypt(struct ablkcipher_request *req)
200 {
201         return ccp_aes_rfc3686_crypt(req, true);
202 }
203
204 static int ccp_aes_rfc3686_decrypt(struct ablkcipher_request *req)
205 {
206         return ccp_aes_rfc3686_crypt(req, false);
207 }
208
209 static int ccp_aes_rfc3686_cra_init(struct crypto_tfm *tfm)
210 {
211         struct ccp_ctx *ctx = crypto_tfm_ctx(tfm);
212
213         ctx->complete = ccp_aes_rfc3686_complete;
214         ctx->u.aes.key_len = 0;
215
216         tfm->crt_ablkcipher.reqsize = sizeof(struct ccp_aes_req_ctx);
217
218         return 0;
219 }
220
221 static void ccp_aes_rfc3686_cra_exit(struct crypto_tfm *tfm)
222 {
223 }
224
225 static struct crypto_alg ccp_aes_defaults = {
226         .cra_flags      = CRYPTO_ALG_TYPE_ABLKCIPHER |
227                           CRYPTO_ALG_ASYNC |
228                           CRYPTO_ALG_KERN_DRIVER_ONLY |
229                           CRYPTO_ALG_NEED_FALLBACK,
230         .cra_blocksize  = AES_BLOCK_SIZE,
231         .cra_ctxsize    = sizeof(struct ccp_ctx),
232         .cra_priority   = CCP_CRA_PRIORITY,
233         .cra_type       = &crypto_ablkcipher_type,
234         .cra_init       = ccp_aes_cra_init,
235         .cra_exit       = ccp_aes_cra_exit,
236         .cra_module     = THIS_MODULE,
237         .cra_ablkcipher = {
238                 .setkey         = ccp_aes_setkey,
239                 .encrypt        = ccp_aes_encrypt,
240                 .decrypt        = ccp_aes_decrypt,
241                 .min_keysize    = AES_MIN_KEY_SIZE,
242                 .max_keysize    = AES_MAX_KEY_SIZE,
243         },
244 };
245
246 static struct crypto_alg ccp_aes_rfc3686_defaults = {
247         .cra_flags      = CRYPTO_ALG_TYPE_ABLKCIPHER |
248                            CRYPTO_ALG_ASYNC |
249                            CRYPTO_ALG_KERN_DRIVER_ONLY |
250                            CRYPTO_ALG_NEED_FALLBACK,
251         .cra_blocksize  = CTR_RFC3686_BLOCK_SIZE,
252         .cra_ctxsize    = sizeof(struct ccp_ctx),
253         .cra_priority   = CCP_CRA_PRIORITY,
254         .cra_type       = &crypto_ablkcipher_type,
255         .cra_init       = ccp_aes_rfc3686_cra_init,
256         .cra_exit       = ccp_aes_rfc3686_cra_exit,
257         .cra_module     = THIS_MODULE,
258         .cra_ablkcipher = {
259                 .setkey         = ccp_aes_rfc3686_setkey,
260                 .encrypt        = ccp_aes_rfc3686_encrypt,
261                 .decrypt        = ccp_aes_rfc3686_decrypt,
262                 .min_keysize    = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
263                 .max_keysize    = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
264         },
265 };
266
267 struct ccp_aes_def {
268         enum ccp_aes_mode mode;
269         const char *name;
270         const char *driver_name;
271         unsigned int blocksize;
272         unsigned int ivsize;
273         struct crypto_alg *alg_defaults;
274 };
275
276 static struct ccp_aes_def aes_algs[] = {
277         {
278                 .mode           = CCP_AES_MODE_ECB,
279                 .name           = "ecb(aes)",
280                 .driver_name    = "ecb-aes-ccp",
281                 .blocksize      = AES_BLOCK_SIZE,
282                 .ivsize         = 0,
283                 .alg_defaults   = &ccp_aes_defaults,
284         },
285         {
286                 .mode           = CCP_AES_MODE_CBC,
287                 .name           = "cbc(aes)",
288                 .driver_name    = "cbc-aes-ccp",
289                 .blocksize      = AES_BLOCK_SIZE,
290                 .ivsize         = AES_BLOCK_SIZE,
291                 .alg_defaults   = &ccp_aes_defaults,
292         },
293         {
294                 .mode           = CCP_AES_MODE_CFB,
295                 .name           = "cfb(aes)",
296                 .driver_name    = "cfb-aes-ccp",
297                 .blocksize      = AES_BLOCK_SIZE,
298                 .ivsize         = AES_BLOCK_SIZE,
299                 .alg_defaults   = &ccp_aes_defaults,
300         },
301         {
302                 .mode           = CCP_AES_MODE_OFB,
303                 .name           = "ofb(aes)",
304                 .driver_name    = "ofb-aes-ccp",
305                 .blocksize      = 1,
306                 .ivsize         = AES_BLOCK_SIZE,
307                 .alg_defaults   = &ccp_aes_defaults,
308         },
309         {
310                 .mode           = CCP_AES_MODE_CTR,
311                 .name           = "ctr(aes)",
312                 .driver_name    = "ctr-aes-ccp",
313                 .blocksize      = 1,
314                 .ivsize         = AES_BLOCK_SIZE,
315                 .alg_defaults   = &ccp_aes_defaults,
316         },
317         {
318                 .mode           = CCP_AES_MODE_CTR,
319                 .name           = "rfc3686(ctr(aes))",
320                 .driver_name    = "rfc3686-ctr-aes-ccp",
321                 .blocksize      = 1,
322                 .ivsize         = CTR_RFC3686_IV_SIZE,
323                 .alg_defaults   = &ccp_aes_rfc3686_defaults,
324         },
325 };
326
327 static int ccp_register_aes_alg(struct list_head *head,
328                                 const struct ccp_aes_def *def)
329 {
330         struct ccp_crypto_ablkcipher_alg *ccp_alg;
331         struct crypto_alg *alg;
332         int ret;
333
334         ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL);
335         if (!ccp_alg)
336                 return -ENOMEM;
337
338         INIT_LIST_HEAD(&ccp_alg->entry);
339
340         ccp_alg->mode = def->mode;
341
342         /* Copy the defaults and override as necessary */
343         alg = &ccp_alg->alg;
344         memcpy(alg, def->alg_defaults, sizeof(*alg));
345         snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
346         snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
347                  def->driver_name);
348         alg->cra_blocksize = def->blocksize;
349         alg->cra_ablkcipher.ivsize = def->ivsize;
350
351         ret = crypto_register_alg(alg);
352         if (ret) {
353                 pr_err("%s ablkcipher algorithm registration error (%d)\n",
354                         alg->cra_name, ret);
355                 kfree(ccp_alg);
356                 return ret;
357         }
358
359         list_add(&ccp_alg->entry, head);
360
361         return 0;
362 }
363
364 int ccp_register_aes_algs(struct list_head *head)
365 {
366         int i, ret;
367
368         for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
369                 ret = ccp_register_aes_alg(head, &aes_algs[i]);
370                 if (ret)
371                         return ret;
372         }
373
374         return 0;
375 }