xref: /openbmc/linux/drivers/crypto/cavium/cpt/cptvf_algs.c (revision 9e27c99104707f083dccd3b4d79762859b5a0614)
125763b3cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c694b233SGeorge Cherian 
3c694b233SGeorge Cherian /*
4c694b233SGeorge Cherian  * Copyright (C) 2016 Cavium, Inc.
5c694b233SGeorge Cherian  */
6c694b233SGeorge Cherian 
7c694b233SGeorge Cherian #include <crypto/aes.h>
8c694b233SGeorge Cherian #include <crypto/algapi.h>
9c694b233SGeorge Cherian #include <crypto/authenc.h>
100e1cbe97SArd Biesheuvel #include <crypto/internal/des.h>
11c694b233SGeorge Cherian #include <crypto/xts.h>
12c694b233SGeorge Cherian #include <linux/crypto.h>
13c694b233SGeorge Cherian #include <linux/err.h>
14c694b233SGeorge Cherian #include <linux/list.h>
15c694b233SGeorge Cherian #include <linux/scatterlist.h>
16c694b233SGeorge Cherian 
17c694b233SGeorge Cherian #include "cptvf.h"
18c694b233SGeorge Cherian #include "cptvf_algs.h"
19c694b233SGeorge Cherian 
20c694b233SGeorge Cherian struct cpt_device_handle {
21c694b233SGeorge Cherian 	void *cdev[MAX_DEVICES];
22c694b233SGeorge Cherian 	u32 dev_count;
23c694b233SGeorge Cherian };
24c694b233SGeorge Cherian 
25c694b233SGeorge Cherian static struct cpt_device_handle dev_handle;
26c694b233SGeorge Cherian 
27c694b233SGeorge Cherian static void cvm_callback(u32 status, void *arg)
28c694b233SGeorge Cherian {
29c694b233SGeorge Cherian 	struct crypto_async_request *req = (struct crypto_async_request *)arg;
30c694b233SGeorge Cherian 
31c694b233SGeorge Cherian 	req->complete(req, !status);
32c694b233SGeorge Cherian }
33c694b233SGeorge Cherian 
34c694b233SGeorge Cherian static inline void update_input_iv(struct cpt_request_info *req_info,
35c694b233SGeorge Cherian 				   u8 *iv, u32 enc_iv_len,
36c694b233SGeorge Cherian 				   u32 *argcnt)
37c694b233SGeorge Cherian {
38c694b233SGeorge Cherian 	/* Setting the iv information */
39c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (void *)iv;
40c694b233SGeorge Cherian 	req_info->in[*argcnt].size = enc_iv_len;
41c694b233SGeorge Cherian 	req_info->req.dlen += enc_iv_len;
42c694b233SGeorge Cherian 
43c694b233SGeorge Cherian 	++(*argcnt);
44c694b233SGeorge Cherian }
45c694b233SGeorge Cherian 
46c694b233SGeorge Cherian static inline void update_output_iv(struct cpt_request_info *req_info,
47c694b233SGeorge Cherian 				    u8 *iv, u32 enc_iv_len,
48c694b233SGeorge Cherian 				    u32 *argcnt)
49c694b233SGeorge Cherian {
50c694b233SGeorge Cherian 	/* Setting the iv information */
51c694b233SGeorge Cherian 	req_info->out[*argcnt].vptr = (void *)iv;
52c694b233SGeorge Cherian 	req_info->out[*argcnt].size = enc_iv_len;
53c694b233SGeorge Cherian 	req_info->rlen += enc_iv_len;
54c694b233SGeorge Cherian 
55c694b233SGeorge Cherian 	++(*argcnt);
56c694b233SGeorge Cherian }
57c694b233SGeorge Cherian 
58c694b233SGeorge Cherian static inline void update_input_data(struct cpt_request_info *req_info,
59c694b233SGeorge Cherian 				     struct scatterlist *inp_sg,
60c694b233SGeorge Cherian 				     u32 nbytes, u32 *argcnt)
61c694b233SGeorge Cherian {
62c694b233SGeorge Cherian 	req_info->req.dlen += nbytes;
63c694b233SGeorge Cherian 
64c694b233SGeorge Cherian 	while (nbytes) {
65c694b233SGeorge Cherian 		u32 len = min(nbytes, inp_sg->length);
66c694b233SGeorge Cherian 		u8 *ptr = sg_virt(inp_sg);
67c694b233SGeorge Cherian 
68c694b233SGeorge Cherian 		req_info->in[*argcnt].vptr = (void *)ptr;
69c694b233SGeorge Cherian 		req_info->in[*argcnt].size = len;
70c694b233SGeorge Cherian 		nbytes -= len;
71c694b233SGeorge Cherian 
72c694b233SGeorge Cherian 		++(*argcnt);
73c694b233SGeorge Cherian 		++inp_sg;
74c694b233SGeorge Cherian 	}
75c694b233SGeorge Cherian }
76c694b233SGeorge Cherian 
77c694b233SGeorge Cherian static inline void update_output_data(struct cpt_request_info *req_info,
78c694b233SGeorge Cherian 				      struct scatterlist *outp_sg,
79c694b233SGeorge Cherian 				      u32 nbytes, u32 *argcnt)
80c694b233SGeorge Cherian {
81c694b233SGeorge Cherian 	req_info->rlen += nbytes;
82c694b233SGeorge Cherian 
83c694b233SGeorge Cherian 	while (nbytes) {
84c694b233SGeorge Cherian 		u32 len = min(nbytes, outp_sg->length);
85c694b233SGeorge Cherian 		u8 *ptr = sg_virt(outp_sg);
86c694b233SGeorge Cherian 
87c694b233SGeorge Cherian 		req_info->out[*argcnt].vptr = (void *)ptr;
88c694b233SGeorge Cherian 		req_info->out[*argcnt].size = len;
89c694b233SGeorge Cherian 		nbytes -= len;
90c694b233SGeorge Cherian 		++(*argcnt);
91c694b233SGeorge Cherian 		++outp_sg;
92c694b233SGeorge Cherian 	}
93c694b233SGeorge Cherian }
94c694b233SGeorge Cherian 
95ac0d3d13SArd Biesheuvel static inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc,
96c694b233SGeorge Cherian 				 u32 *argcnt)
97c694b233SGeorge Cherian {
98ac0d3d13SArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
99ac0d3d13SArd Biesheuvel 	struct cvm_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
100ac0d3d13SArd Biesheuvel 	struct cvm_req_ctx *rctx = skcipher_request_ctx(req);
101c694b233SGeorge Cherian 	struct fc_context *fctx = &rctx->fctx;
102c694b233SGeorge Cherian 	u64 *offset_control = &rctx->control_word;
103ac0d3d13SArd Biesheuvel 	u32 enc_iv_len = crypto_skcipher_ivsize(tfm);
104c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
105c694b233SGeorge Cherian 	u64 *ctrl_flags = NULL;
106c694b233SGeorge Cherian 
107c694b233SGeorge Cherian 	req_info->ctrl.s.grp = 0;
108c694b233SGeorge Cherian 	req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER;
109c694b233SGeorge Cherian 	req_info->ctrl.s.se_req = SE_CORE_REQ;
110c694b233SGeorge Cherian 
111c694b233SGeorge Cherian 	req_info->req.opcode.s.major = MAJOR_OP_FC |
112c694b233SGeorge Cherian 					DMA_MODE_FLAG(DMA_GATHER_SCATTER);
113c694b233SGeorge Cherian 	if (enc)
114c694b233SGeorge Cherian 		req_info->req.opcode.s.minor = 2;
115c694b233SGeorge Cherian 	else
116c694b233SGeorge Cherian 		req_info->req.opcode.s.minor = 3;
117c694b233SGeorge Cherian 
118ac0d3d13SArd Biesheuvel 	req_info->req.param1 = req->cryptlen; /* Encryption Data length */
119c694b233SGeorge Cherian 	req_info->req.param2 = 0; /*Auth data length */
120c694b233SGeorge Cherian 
121e2eb769eSGeorge Cherian 	fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;
122e2eb769eSGeorge Cherian 	fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;
123c694b233SGeorge Cherian 	fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR;
124c694b233SGeorge Cherian 
125e2eb769eSGeorge Cherian 	if (ctx->cipher_type == AES_XTS)
126c694b233SGeorge Cherian 		memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);
127c694b233SGeorge Cherian 	else
128c694b233SGeorge Cherian 		memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);
129c694b233SGeorge Cherian 	ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags;
130c694b233SGeorge Cherian 	*ctrl_flags = cpu_to_be64(*ctrl_flags);
131c694b233SGeorge Cherian 
132c694b233SGeorge Cherian 	*offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16));
133c694b233SGeorge Cherian 	/* Storing  Packet Data Information in offset
134c694b233SGeorge Cherian 	 * Control Word First 8 bytes
135c694b233SGeorge Cherian 	 */
136c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (u8 *)offset_control;
137c694b233SGeorge Cherian 	req_info->in[*argcnt].size = CONTROL_WORD_LEN;
138c694b233SGeorge Cherian 	req_info->req.dlen += CONTROL_WORD_LEN;
139c694b233SGeorge Cherian 	++(*argcnt);
140c694b233SGeorge Cherian 
141c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (u8 *)fctx;
142c694b233SGeorge Cherian 	req_info->in[*argcnt].size = sizeof(struct fc_context);
143c694b233SGeorge Cherian 	req_info->req.dlen += sizeof(struct fc_context);
144c694b233SGeorge Cherian 
145c694b233SGeorge Cherian 	++(*argcnt);
146c694b233SGeorge Cherian 
147c694b233SGeorge Cherian 	return 0;
148c694b233SGeorge Cherian }
149c694b233SGeorge Cherian 
150ac0d3d13SArd Biesheuvel static inline u32 create_input_list(struct skcipher_request  *req, u32 enc,
151c694b233SGeorge Cherian 				    u32 enc_iv_len)
152c694b233SGeorge Cherian {
153ac0d3d13SArd Biesheuvel 	struct cvm_req_ctx *rctx = skcipher_request_ctx(req);
154c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
155c694b233SGeorge Cherian 	u32 argcnt =  0;
156c694b233SGeorge Cherian 
157e2eb769eSGeorge Cherian 	create_ctx_hdr(req, enc, &argcnt);
158ac0d3d13SArd Biesheuvel 	update_input_iv(req_info, req->iv, enc_iv_len, &argcnt);
159ac0d3d13SArd Biesheuvel 	update_input_data(req_info, req->src, req->cryptlen, &argcnt);
160c694b233SGeorge Cherian 	req_info->incnt = argcnt;
161c694b233SGeorge Cherian 
162c694b233SGeorge Cherian 	return 0;
163c694b233SGeorge Cherian }
164c694b233SGeorge Cherian 
165ac0d3d13SArd Biesheuvel static inline void store_cb_info(struct skcipher_request *req,
166c694b233SGeorge Cherian 				 struct cpt_request_info *req_info)
167c694b233SGeorge Cherian {
168c694b233SGeorge Cherian 	req_info->callback = (void *)cvm_callback;
169c694b233SGeorge Cherian 	req_info->callback_arg = (void *)&req->base;
170c694b233SGeorge Cherian }
171c694b233SGeorge Cherian 
172ac0d3d13SArd Biesheuvel static inline void create_output_list(struct skcipher_request *req,
173c694b233SGeorge Cherian 				      u32 enc_iv_len)
174c694b233SGeorge Cherian {
175ac0d3d13SArd Biesheuvel 	struct cvm_req_ctx *rctx = skcipher_request_ctx(req);
176c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
177c694b233SGeorge Cherian 	u32 argcnt = 0;
178c694b233SGeorge Cherian 
179c694b233SGeorge Cherian 	/* OUTPUT Buffer Processing
180c694b233SGeorge Cherian 	 * AES encryption/decryption output would be
181c694b233SGeorge Cherian 	 * received in the following format
182c694b233SGeorge Cherian 	 *
183c694b233SGeorge Cherian 	 * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
184c694b233SGeorge Cherian 	 * [ 16 Bytes/     [   Request Enc/Dec/ DATA Len AES CBC ]
185c694b233SGeorge Cherian 	 */
186c694b233SGeorge Cherian 	/* Reading IV information */
187ac0d3d13SArd Biesheuvel 	update_output_iv(req_info, req->iv, enc_iv_len, &argcnt);
188ac0d3d13SArd Biesheuvel 	update_output_data(req_info, req->dst, req->cryptlen, &argcnt);
189c694b233SGeorge Cherian 	req_info->outcnt = argcnt;
190c694b233SGeorge Cherian }
191c694b233SGeorge Cherian 
192ac0d3d13SArd Biesheuvel static inline int cvm_enc_dec(struct skcipher_request *req, u32 enc)
193c694b233SGeorge Cherian {
194ac0d3d13SArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
195ac0d3d13SArd Biesheuvel 	struct cvm_req_ctx *rctx = skcipher_request_ctx(req);
196ac0d3d13SArd Biesheuvel 	u32 enc_iv_len = crypto_skcipher_ivsize(tfm);
197c694b233SGeorge Cherian 	struct fc_context *fctx = &rctx->fctx;
198c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
199c694b233SGeorge Cherian 	void *cdev = NULL;
200c694b233SGeorge Cherian 	int status;
201c694b233SGeorge Cherian 
202c694b233SGeorge Cherian 	memset(req_info, 0, sizeof(struct cpt_request_info));
203*9e27c991SMikulas Patocka 	req_info->may_sleep = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) != 0;
204c694b233SGeorge Cherian 	memset(fctx, 0, sizeof(struct fc_context));
205e2eb769eSGeorge Cherian 	create_input_list(req, enc, enc_iv_len);
206e2eb769eSGeorge Cherian 	create_output_list(req, enc_iv_len);
207c694b233SGeorge Cherian 	store_cb_info(req, req_info);
208c694b233SGeorge Cherian 	cdev = dev_handle.cdev[smp_processor_id()];
209c694b233SGeorge Cherian 	status = cptvf_do_request(cdev, req_info);
210c694b233SGeorge Cherian 	/* We perform an asynchronous send and once
211c694b233SGeorge Cherian 	 * the request is completed the driver would
212c694b233SGeorge Cherian 	 * intimate through  registered call back functions
213c694b233SGeorge Cherian 	 */
214c694b233SGeorge Cherian 
215c694b233SGeorge Cherian 	if (status)
216c694b233SGeorge Cherian 		return status;
217c694b233SGeorge Cherian 	else
218c694b233SGeorge Cherian 		return -EINPROGRESS;
219c694b233SGeorge Cherian }
220c694b233SGeorge Cherian 
221ac0d3d13SArd Biesheuvel static int cvm_encrypt(struct skcipher_request *req)
222c694b233SGeorge Cherian {
223e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, true);
224c694b233SGeorge Cherian }
225c694b233SGeorge Cherian 
226ac0d3d13SArd Biesheuvel static int cvm_decrypt(struct skcipher_request *req)
227c694b233SGeorge Cherian {
228e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, false);
229c694b233SGeorge Cherian }
230c694b233SGeorge Cherian 
231ac0d3d13SArd Biesheuvel static int cvm_xts_setkey(struct crypto_skcipher *cipher, const u8 *key,
232c694b233SGeorge Cherian 		   u32 keylen)
233c694b233SGeorge Cherian {
234ac0d3d13SArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
235c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
236c694b233SGeorge Cherian 	int err;
237c694b233SGeorge Cherian 	const u8 *key1 = key;
238c694b233SGeorge Cherian 	const u8 *key2 = key + (keylen / 2);
239c694b233SGeorge Cherian 
240c694b233SGeorge Cherian 	err = xts_check_key(tfm, key, keylen);
241c694b233SGeorge Cherian 	if (err)
242c694b233SGeorge Cherian 		return err;
243c694b233SGeorge Cherian 	ctx->key_len = keylen;
244c694b233SGeorge Cherian 	memcpy(ctx->enc_key, key1, keylen / 2);
245c694b233SGeorge Cherian 	memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
246e2eb769eSGeorge Cherian 	ctx->cipher_type = AES_XTS;
247e2eb769eSGeorge Cherian 	switch (ctx->key_len) {
248e2eb769eSGeorge Cherian 	case 32:
249e2eb769eSGeorge Cherian 		ctx->key_type = AES_128_BIT;
250e2eb769eSGeorge Cherian 		break;
251e2eb769eSGeorge Cherian 	case 64:
252e2eb769eSGeorge Cherian 		ctx->key_type = AES_256_BIT;
253e2eb769eSGeorge Cherian 		break;
254e2eb769eSGeorge Cherian 	default:
255e2eb769eSGeorge Cherian 		return -EINVAL;
256e2eb769eSGeorge Cherian 	}
257c694b233SGeorge Cherian 
258c694b233SGeorge Cherian 	return 0;
259c694b233SGeorge Cherian }
260c694b233SGeorge Cherian 
261e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen)
262e2eb769eSGeorge Cherian {
263e2eb769eSGeorge Cherian 	if ((keylen == 16) || (keylen == 24) || (keylen == 32)) {
264e2eb769eSGeorge Cherian 		ctx->key_len = keylen;
265e2eb769eSGeorge Cherian 		switch (ctx->key_len) {
266e2eb769eSGeorge Cherian 		case 16:
267e2eb769eSGeorge Cherian 			ctx->key_type = AES_128_BIT;
268e2eb769eSGeorge Cherian 			break;
269e2eb769eSGeorge Cherian 		case 24:
270e2eb769eSGeorge Cherian 			ctx->key_type = AES_192_BIT;
271e2eb769eSGeorge Cherian 			break;
272e2eb769eSGeorge Cherian 		case 32:
273e2eb769eSGeorge Cherian 			ctx->key_type = AES_256_BIT;
274e2eb769eSGeorge Cherian 			break;
275e2eb769eSGeorge Cherian 		default:
276e2eb769eSGeorge Cherian 			return -EINVAL;
277e2eb769eSGeorge Cherian 		}
278e2eb769eSGeorge Cherian 
279e2eb769eSGeorge Cherian 		if (ctx->cipher_type == DES3_CBC)
280e2eb769eSGeorge Cherian 			ctx->key_type = 0;
281e2eb769eSGeorge Cherian 
282e2eb769eSGeorge Cherian 		return 0;
283e2eb769eSGeorge Cherian 	}
284e2eb769eSGeorge Cherian 
285e2eb769eSGeorge Cherian 	return -EINVAL;
286e2eb769eSGeorge Cherian }
287e2eb769eSGeorge Cherian 
288ac0d3d13SArd Biesheuvel static int cvm_setkey(struct crypto_skcipher *cipher, const u8 *key,
289e2eb769eSGeorge Cherian 		      u32 keylen, u8 cipher_type)
290c694b233SGeorge Cherian {
291ac0d3d13SArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
292c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
293c694b233SGeorge Cherian 
294e2eb769eSGeorge Cherian 	ctx->cipher_type = cipher_type;
295e2eb769eSGeorge Cherian 	if (!cvm_validate_keylen(ctx, keylen)) {
296c694b233SGeorge Cherian 		memcpy(ctx->enc_key, key, keylen);
297c694b233SGeorge Cherian 		return 0;
298e2eb769eSGeorge Cherian 	} else {
299c694b233SGeorge Cherian 		return -EINVAL;
300c694b233SGeorge Cherian 	}
301e2eb769eSGeorge Cherian }
302e2eb769eSGeorge Cherian 
303ac0d3d13SArd Biesheuvel static int cvm_cbc_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
304e2eb769eSGeorge Cherian 			      u32 keylen)
305e2eb769eSGeorge Cherian {
306e2eb769eSGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CBC);
307e2eb769eSGeorge Cherian }
308e2eb769eSGeorge Cherian 
309ac0d3d13SArd Biesheuvel static int cvm_ecb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
31010d82222SGeorge Cherian 			      u32 keylen)
31110d82222SGeorge Cherian {
31210d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_ECB);
31310d82222SGeorge Cherian }
31410d82222SGeorge Cherian 
315ac0d3d13SArd Biesheuvel static int cvm_cfb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
31610d82222SGeorge Cherian 			      u32 keylen)
31710d82222SGeorge Cherian {
31810d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CFB);
31910d82222SGeorge Cherian }
32010d82222SGeorge Cherian 
321ac0d3d13SArd Biesheuvel static int cvm_cbc_des3_setkey(struct crypto_skcipher *cipher, const u8 *key,
322e2eb769eSGeorge Cherian 			       u32 keylen)
323e2eb769eSGeorge Cherian {
324ac0d3d13SArd Biesheuvel 	return verify_skcipher_des3_key(cipher, key) ?:
3250e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_CBC);
326e2eb769eSGeorge Cherian }
327c694b233SGeorge Cherian 
328ac0d3d13SArd Biesheuvel static int cvm_ecb_des3_setkey(struct crypto_skcipher *cipher, const u8 *key,
32910d82222SGeorge Cherian 			       u32 keylen)
33010d82222SGeorge Cherian {
331ac0d3d13SArd Biesheuvel 	return verify_skcipher_des3_key(cipher, key) ?:
3320e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_ECB);
33310d82222SGeorge Cherian }
33410d82222SGeorge Cherian 
335ac0d3d13SArd Biesheuvel static int cvm_enc_dec_init(struct crypto_skcipher *tfm)
336c694b233SGeorge Cherian {
337ac0d3d13SArd Biesheuvel 	crypto_skcipher_set_reqsize(tfm, sizeof(struct cvm_req_ctx));
338ac0d3d13SArd Biesheuvel 
339c694b233SGeorge Cherian 	return 0;
340c694b233SGeorge Cherian }
341c694b233SGeorge Cherian 
342ac0d3d13SArd Biesheuvel static struct skcipher_alg algs[] = { {
343ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
344ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
345ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
346ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
347ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
348ac0d3d13SArd Biesheuvel 	.base.cra_name		= "xts(aes)",
349ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-xts-aes",
350ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
351ac0d3d13SArd Biesheuvel 
352c694b233SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
353c694b233SGeorge Cherian 	.min_keysize		= 2 * AES_MIN_KEY_SIZE,
354c694b233SGeorge Cherian 	.max_keysize		= 2 * AES_MAX_KEY_SIZE,
355c694b233SGeorge Cherian 	.setkey			= cvm_xts_setkey,
356e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
357e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
358ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
359c694b233SGeorge Cherian }, {
360ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
361ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
362ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
363ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
364ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
365ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cbc(aes)",
366ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cbc-aes",
367ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
368ac0d3d13SArd Biesheuvel 
369c694b233SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
370c694b233SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
371c694b233SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
372e2eb769eSGeorge Cherian 	.setkey			= cvm_cbc_aes_setkey,
373e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
374e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
375ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
376c694b233SGeorge Cherian }, {
377ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
378ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
379ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
380ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
381ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
382ac0d3d13SArd Biesheuvel 	.base.cra_name		= "ecb(aes)",
383ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-ecb-aes",
384ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
385ac0d3d13SArd Biesheuvel 
38610d82222SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
38710d82222SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
38810d82222SGeorge Cherian 	.setkey			= cvm_ecb_aes_setkey,
38910d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
39010d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
391ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
39210d82222SGeorge Cherian }, {
393ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
394ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
395ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
396ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
397ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
398ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cfb(aes)",
399ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cfb-aes",
400ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
401ac0d3d13SArd Biesheuvel 
40210d82222SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
40310d82222SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
40410d82222SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
40510d82222SGeorge Cherian 	.setkey			= cvm_cfb_aes_setkey,
40610d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
40710d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
408ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
40910d82222SGeorge Cherian }, {
410ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
411ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
412ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_des3_ctx),
413ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
414ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
415ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cbc(des3_ede)",
416ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cbc-des3_ede",
417ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
418ac0d3d13SArd Biesheuvel 
419c694b233SGeorge Cherian 	.min_keysize		= DES3_EDE_KEY_SIZE,
420c694b233SGeorge Cherian 	.max_keysize		= DES3_EDE_KEY_SIZE,
421c694b233SGeorge Cherian 	.ivsize			= DES_BLOCK_SIZE,
422e2eb769eSGeorge Cherian 	.setkey			= cvm_cbc_des3_setkey,
423e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
424e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
425ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
42610d82222SGeorge Cherian }, {
427ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
428ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
429ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_des3_ctx),
430ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
431ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
432ac0d3d13SArd Biesheuvel 	.base.cra_name		= "ecb(des3_ede)",
433ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-ecb-des3_ede",
434ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
435ac0d3d13SArd Biesheuvel 
43610d82222SGeorge Cherian 	.min_keysize		= DES3_EDE_KEY_SIZE,
43710d82222SGeorge Cherian 	.max_keysize		= DES3_EDE_KEY_SIZE,
43810d82222SGeorge Cherian 	.ivsize			= DES_BLOCK_SIZE,
43910d82222SGeorge Cherian 	.setkey			= cvm_ecb_des3_setkey,
44010d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
44110d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
442ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
443c694b233SGeorge Cherian } };
444c694b233SGeorge Cherian 
445c694b233SGeorge Cherian static inline int cav_register_algs(void)
446c694b233SGeorge Cherian {
447c694b233SGeorge Cherian 	int err = 0;
448c694b233SGeorge Cherian 
449ac0d3d13SArd Biesheuvel 	err = crypto_register_skciphers(algs, ARRAY_SIZE(algs));
450c694b233SGeorge Cherian 	if (err)
451c694b233SGeorge Cherian 		return err;
452c694b233SGeorge Cherian 
453c694b233SGeorge Cherian 	return 0;
454c694b233SGeorge Cherian }
455c694b233SGeorge Cherian 
456c694b233SGeorge Cherian static inline void cav_unregister_algs(void)
457c694b233SGeorge Cherian {
458ac0d3d13SArd Biesheuvel 	crypto_unregister_skciphers(algs, ARRAY_SIZE(algs));
459c694b233SGeorge Cherian }
460c694b233SGeorge Cherian 
461c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf)
462c694b233SGeorge Cherian {
463c694b233SGeorge Cherian 	struct pci_dev *pdev = cptvf->pdev;
464c694b233SGeorge Cherian 	u32 dev_count;
465c694b233SGeorge Cherian 
466c694b233SGeorge Cherian 	dev_count = dev_handle.dev_count;
467c694b233SGeorge Cherian 	dev_handle.cdev[dev_count] = cptvf;
468c694b233SGeorge Cherian 	dev_handle.dev_count++;
469c694b233SGeorge Cherian 
470c694b233SGeorge Cherian 	if (dev_count == 3) {
471c694b233SGeorge Cherian 		if (cav_register_algs()) {
472c694b233SGeorge Cherian 			dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
473c694b233SGeorge Cherian 			return -EINVAL;
474c694b233SGeorge Cherian 		}
475c694b233SGeorge Cherian 	}
476c694b233SGeorge Cherian 
477c694b233SGeorge Cherian 	return 0;
478c694b233SGeorge Cherian }
479c694b233SGeorge Cherian 
480c694b233SGeorge Cherian void cvm_crypto_exit(void)
481c694b233SGeorge Cherian {
482c694b233SGeorge Cherian 	u32 dev_count;
483c694b233SGeorge Cherian 
484c694b233SGeorge Cherian 	dev_count = --dev_handle.dev_count;
485c694b233SGeorge Cherian 	if (!dev_count)
486c694b233SGeorge Cherian 		cav_unregister_algs();
487c694b233SGeorge Cherian }
488