xref: /openbmc/linux/drivers/crypto/cavium/cpt/cptvf_algs.c (revision ac0d3d130f909f4d8f402b185a68d76150ebdf78)
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 
95*ac0d3d13SArd Biesheuvel static inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc,
96c694b233SGeorge Cherian 				 u32 *argcnt)
97c694b233SGeorge Cherian {
98*ac0d3d13SArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
99*ac0d3d13SArd Biesheuvel 	struct cvm_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
100*ac0d3d13SArd 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;
103*ac0d3d13SArd 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 
118*ac0d3d13SArd 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 
150*ac0d3d13SArd Biesheuvel static inline u32 create_input_list(struct skcipher_request  *req, u32 enc,
151c694b233SGeorge Cherian 				    u32 enc_iv_len)
152c694b233SGeorge Cherian {
153*ac0d3d13SArd 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);
158*ac0d3d13SArd Biesheuvel 	update_input_iv(req_info, req->iv, enc_iv_len, &argcnt);
159*ac0d3d13SArd 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 
165*ac0d3d13SArd 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 
172*ac0d3d13SArd Biesheuvel static inline void create_output_list(struct skcipher_request *req,
173c694b233SGeorge Cherian 				      u32 enc_iv_len)
174c694b233SGeorge Cherian {
175*ac0d3d13SArd 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 */
187*ac0d3d13SArd Biesheuvel 	update_output_iv(req_info, req->iv, enc_iv_len, &argcnt);
188*ac0d3d13SArd Biesheuvel 	update_output_data(req_info, req->dst, req->cryptlen, &argcnt);
189c694b233SGeorge Cherian 	req_info->outcnt = argcnt;
190c694b233SGeorge Cherian }
191c694b233SGeorge Cherian 
192*ac0d3d13SArd Biesheuvel static inline int cvm_enc_dec(struct skcipher_request *req, u32 enc)
193c694b233SGeorge Cherian {
194*ac0d3d13SArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
195*ac0d3d13SArd Biesheuvel 	struct cvm_req_ctx *rctx = skcipher_request_ctx(req);
196*ac0d3d13SArd 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));
203c694b233SGeorge Cherian 	memset(fctx, 0, sizeof(struct fc_context));
204e2eb769eSGeorge Cherian 	create_input_list(req, enc, enc_iv_len);
205e2eb769eSGeorge Cherian 	create_output_list(req, enc_iv_len);
206c694b233SGeorge Cherian 	store_cb_info(req, req_info);
207c694b233SGeorge Cherian 	cdev = dev_handle.cdev[smp_processor_id()];
208c694b233SGeorge Cherian 	status = cptvf_do_request(cdev, req_info);
209c694b233SGeorge Cherian 	/* We perform an asynchronous send and once
210c694b233SGeorge Cherian 	 * the request is completed the driver would
211c694b233SGeorge Cherian 	 * intimate through  registered call back functions
212c694b233SGeorge Cherian 	 */
213c694b233SGeorge Cherian 
214c694b233SGeorge Cherian 	if (status)
215c694b233SGeorge Cherian 		return status;
216c694b233SGeorge Cherian 	else
217c694b233SGeorge Cherian 		return -EINPROGRESS;
218c694b233SGeorge Cherian }
219c694b233SGeorge Cherian 
220*ac0d3d13SArd Biesheuvel static int cvm_encrypt(struct skcipher_request *req)
221c694b233SGeorge Cherian {
222e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, true);
223c694b233SGeorge Cherian }
224c694b233SGeorge Cherian 
225*ac0d3d13SArd Biesheuvel static int cvm_decrypt(struct skcipher_request *req)
226c694b233SGeorge Cherian {
227e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, false);
228c694b233SGeorge Cherian }
229c694b233SGeorge Cherian 
230*ac0d3d13SArd Biesheuvel static int cvm_xts_setkey(struct crypto_skcipher *cipher, const u8 *key,
231c694b233SGeorge Cherian 		   u32 keylen)
232c694b233SGeorge Cherian {
233*ac0d3d13SArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
234c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
235c694b233SGeorge Cherian 	int err;
236c694b233SGeorge Cherian 	const u8 *key1 = key;
237c694b233SGeorge Cherian 	const u8 *key2 = key + (keylen / 2);
238c694b233SGeorge Cherian 
239c694b233SGeorge Cherian 	err = xts_check_key(tfm, key, keylen);
240c694b233SGeorge Cherian 	if (err)
241c694b233SGeorge Cherian 		return err;
242c694b233SGeorge Cherian 	ctx->key_len = keylen;
243c694b233SGeorge Cherian 	memcpy(ctx->enc_key, key1, keylen / 2);
244c694b233SGeorge Cherian 	memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
245e2eb769eSGeorge Cherian 	ctx->cipher_type = AES_XTS;
246e2eb769eSGeorge Cherian 	switch (ctx->key_len) {
247e2eb769eSGeorge Cherian 	case 32:
248e2eb769eSGeorge Cherian 		ctx->key_type = AES_128_BIT;
249e2eb769eSGeorge Cherian 		break;
250e2eb769eSGeorge Cherian 	case 64:
251e2eb769eSGeorge Cherian 		ctx->key_type = AES_256_BIT;
252e2eb769eSGeorge Cherian 		break;
253e2eb769eSGeorge Cherian 	default:
254e2eb769eSGeorge Cherian 		return -EINVAL;
255e2eb769eSGeorge Cherian 	}
256c694b233SGeorge Cherian 
257c694b233SGeorge Cherian 	return 0;
258c694b233SGeorge Cherian }
259c694b233SGeorge Cherian 
260e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen)
261e2eb769eSGeorge Cherian {
262e2eb769eSGeorge Cherian 	if ((keylen == 16) || (keylen == 24) || (keylen == 32)) {
263e2eb769eSGeorge Cherian 		ctx->key_len = keylen;
264e2eb769eSGeorge Cherian 		switch (ctx->key_len) {
265e2eb769eSGeorge Cherian 		case 16:
266e2eb769eSGeorge Cherian 			ctx->key_type = AES_128_BIT;
267e2eb769eSGeorge Cherian 			break;
268e2eb769eSGeorge Cherian 		case 24:
269e2eb769eSGeorge Cherian 			ctx->key_type = AES_192_BIT;
270e2eb769eSGeorge Cherian 			break;
271e2eb769eSGeorge Cherian 		case 32:
272e2eb769eSGeorge Cherian 			ctx->key_type = AES_256_BIT;
273e2eb769eSGeorge Cherian 			break;
274e2eb769eSGeorge Cherian 		default:
275e2eb769eSGeorge Cherian 			return -EINVAL;
276e2eb769eSGeorge Cherian 		}
277e2eb769eSGeorge Cherian 
278e2eb769eSGeorge Cherian 		if (ctx->cipher_type == DES3_CBC)
279e2eb769eSGeorge Cherian 			ctx->key_type = 0;
280e2eb769eSGeorge Cherian 
281e2eb769eSGeorge Cherian 		return 0;
282e2eb769eSGeorge Cherian 	}
283e2eb769eSGeorge Cherian 
284e2eb769eSGeorge Cherian 	return -EINVAL;
285e2eb769eSGeorge Cherian }
286e2eb769eSGeorge Cherian 
287*ac0d3d13SArd Biesheuvel static int cvm_setkey(struct crypto_skcipher *cipher, const u8 *key,
288e2eb769eSGeorge Cherian 		      u32 keylen, u8 cipher_type)
289c694b233SGeorge Cherian {
290*ac0d3d13SArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
291c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
292c694b233SGeorge Cherian 
293e2eb769eSGeorge Cherian 	ctx->cipher_type = cipher_type;
294e2eb769eSGeorge Cherian 	if (!cvm_validate_keylen(ctx, keylen)) {
295c694b233SGeorge Cherian 		memcpy(ctx->enc_key, key, keylen);
296c694b233SGeorge Cherian 		return 0;
297e2eb769eSGeorge Cherian 	} else {
298*ac0d3d13SArd Biesheuvel 		crypto_skcipher_set_flags(cipher,
299e2eb769eSGeorge Cherian 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
300c694b233SGeorge Cherian 		return -EINVAL;
301c694b233SGeorge Cherian 	}
302e2eb769eSGeorge Cherian }
303e2eb769eSGeorge Cherian 
304*ac0d3d13SArd Biesheuvel static int cvm_cbc_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
305e2eb769eSGeorge Cherian 			      u32 keylen)
306e2eb769eSGeorge Cherian {
307e2eb769eSGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CBC);
308e2eb769eSGeorge Cherian }
309e2eb769eSGeorge Cherian 
310*ac0d3d13SArd Biesheuvel static int cvm_ecb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
31110d82222SGeorge Cherian 			      u32 keylen)
31210d82222SGeorge Cherian {
31310d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_ECB);
31410d82222SGeorge Cherian }
31510d82222SGeorge Cherian 
316*ac0d3d13SArd Biesheuvel static int cvm_cfb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
31710d82222SGeorge Cherian 			      u32 keylen)
31810d82222SGeorge Cherian {
31910d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CFB);
32010d82222SGeorge Cherian }
32110d82222SGeorge Cherian 
322*ac0d3d13SArd Biesheuvel static int cvm_cbc_des3_setkey(struct crypto_skcipher *cipher, const u8 *key,
323e2eb769eSGeorge Cherian 			       u32 keylen)
324e2eb769eSGeorge Cherian {
325*ac0d3d13SArd Biesheuvel 	return verify_skcipher_des3_key(cipher, key) ?:
3260e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_CBC);
327e2eb769eSGeorge Cherian }
328c694b233SGeorge Cherian 
329*ac0d3d13SArd Biesheuvel static int cvm_ecb_des3_setkey(struct crypto_skcipher *cipher, const u8 *key,
33010d82222SGeorge Cherian 			       u32 keylen)
33110d82222SGeorge Cherian {
332*ac0d3d13SArd Biesheuvel 	return verify_skcipher_des3_key(cipher, key) ?:
3330e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_ECB);
33410d82222SGeorge Cherian }
33510d82222SGeorge Cherian 
336*ac0d3d13SArd Biesheuvel static int cvm_enc_dec_init(struct crypto_skcipher *tfm)
337c694b233SGeorge Cherian {
338*ac0d3d13SArd Biesheuvel 	crypto_skcipher_set_reqsize(tfm, sizeof(struct cvm_req_ctx));
339*ac0d3d13SArd Biesheuvel 
340c694b233SGeorge Cherian 	return 0;
341c694b233SGeorge Cherian }
342c694b233SGeorge Cherian 
343*ac0d3d13SArd Biesheuvel static struct skcipher_alg algs[] = { {
344*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
345*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
346*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
347*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
348*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
349*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "xts(aes)",
350*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-xts-aes",
351*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
352*ac0d3d13SArd Biesheuvel 
353c694b233SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
354c694b233SGeorge Cherian 	.min_keysize		= 2 * AES_MIN_KEY_SIZE,
355c694b233SGeorge Cherian 	.max_keysize		= 2 * AES_MAX_KEY_SIZE,
356c694b233SGeorge Cherian 	.setkey			= cvm_xts_setkey,
357e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
358e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
359*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
360c694b233SGeorge Cherian }, {
361*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
362*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
363*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
364*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
365*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
366*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cbc(aes)",
367*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cbc-aes",
368*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
369*ac0d3d13SArd Biesheuvel 
370c694b233SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
371c694b233SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
372c694b233SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
373e2eb769eSGeorge Cherian 	.setkey			= cvm_cbc_aes_setkey,
374e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
375e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
376*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
377c694b233SGeorge Cherian }, {
378*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
379*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
380*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
381*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
382*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
383*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "ecb(aes)",
384*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-ecb-aes",
385*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
386*ac0d3d13SArd Biesheuvel 
38710d82222SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
38810d82222SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
38910d82222SGeorge Cherian 	.setkey			= cvm_ecb_aes_setkey,
39010d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
39110d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
392*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
39310d82222SGeorge Cherian }, {
394*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
395*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
396*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_enc_ctx),
397*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
398*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
399*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cfb(aes)",
400*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cfb-aes",
401*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
402*ac0d3d13SArd Biesheuvel 
40310d82222SGeorge Cherian 	.ivsize			= AES_BLOCK_SIZE,
40410d82222SGeorge Cherian 	.min_keysize		= AES_MIN_KEY_SIZE,
40510d82222SGeorge Cherian 	.max_keysize		= AES_MAX_KEY_SIZE,
40610d82222SGeorge Cherian 	.setkey			= cvm_cfb_aes_setkey,
40710d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
40810d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
409*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
41010d82222SGeorge Cherian }, {
411*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
412*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
413*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_des3_ctx),
414*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
415*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
416*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "cbc(des3_ede)",
417*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-cbc-des3_ede",
418*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
419*ac0d3d13SArd Biesheuvel 
420c694b233SGeorge Cherian 	.min_keysize		= DES3_EDE_KEY_SIZE,
421c694b233SGeorge Cherian 	.max_keysize		= DES3_EDE_KEY_SIZE,
422c694b233SGeorge Cherian 	.ivsize			= DES_BLOCK_SIZE,
423e2eb769eSGeorge Cherian 	.setkey			= cvm_cbc_des3_setkey,
424e2eb769eSGeorge Cherian 	.encrypt		= cvm_encrypt,
425e2eb769eSGeorge Cherian 	.decrypt		= cvm_decrypt,
426*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
42710d82222SGeorge Cherian }, {
428*ac0d3d13SArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_ASYNC,
429*ac0d3d13SArd Biesheuvel 	.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
430*ac0d3d13SArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct cvm_des3_ctx),
431*ac0d3d13SArd Biesheuvel 	.base.cra_alignmask	= 7,
432*ac0d3d13SArd Biesheuvel 	.base.cra_priority	= 4001,
433*ac0d3d13SArd Biesheuvel 	.base.cra_name		= "ecb(des3_ede)",
434*ac0d3d13SArd Biesheuvel 	.base.cra_driver_name	= "cavium-ecb-des3_ede",
435*ac0d3d13SArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
436*ac0d3d13SArd Biesheuvel 
43710d82222SGeorge Cherian 	.min_keysize		= DES3_EDE_KEY_SIZE,
43810d82222SGeorge Cherian 	.max_keysize		= DES3_EDE_KEY_SIZE,
43910d82222SGeorge Cherian 	.ivsize			= DES_BLOCK_SIZE,
44010d82222SGeorge Cherian 	.setkey			= cvm_ecb_des3_setkey,
44110d82222SGeorge Cherian 	.encrypt		= cvm_encrypt,
44210d82222SGeorge Cherian 	.decrypt		= cvm_decrypt,
443*ac0d3d13SArd Biesheuvel 	.init			= cvm_enc_dec_init,
444c694b233SGeorge Cherian } };
445c694b233SGeorge Cherian 
446c694b233SGeorge Cherian static inline int cav_register_algs(void)
447c694b233SGeorge Cherian {
448c694b233SGeorge Cherian 	int err = 0;
449c694b233SGeorge Cherian 
450*ac0d3d13SArd Biesheuvel 	err = crypto_register_skciphers(algs, ARRAY_SIZE(algs));
451c694b233SGeorge Cherian 	if (err)
452c694b233SGeorge Cherian 		return err;
453c694b233SGeorge Cherian 
454c694b233SGeorge Cherian 	return 0;
455c694b233SGeorge Cherian }
456c694b233SGeorge Cherian 
457c694b233SGeorge Cherian static inline void cav_unregister_algs(void)
458c694b233SGeorge Cherian {
459*ac0d3d13SArd Biesheuvel 	crypto_unregister_skciphers(algs, ARRAY_SIZE(algs));
460c694b233SGeorge Cherian }
461c694b233SGeorge Cherian 
462c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf)
463c694b233SGeorge Cherian {
464c694b233SGeorge Cherian 	struct pci_dev *pdev = cptvf->pdev;
465c694b233SGeorge Cherian 	u32 dev_count;
466c694b233SGeorge Cherian 
467c694b233SGeorge Cherian 	dev_count = dev_handle.dev_count;
468c694b233SGeorge Cherian 	dev_handle.cdev[dev_count] = cptvf;
469c694b233SGeorge Cherian 	dev_handle.dev_count++;
470c694b233SGeorge Cherian 
471c694b233SGeorge Cherian 	if (dev_count == 3) {
472c694b233SGeorge Cherian 		if (cav_register_algs()) {
473c694b233SGeorge Cherian 			dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
474c694b233SGeorge Cherian 			return -EINVAL;
475c694b233SGeorge Cherian 		}
476c694b233SGeorge Cherian 	}
477c694b233SGeorge Cherian 
478c694b233SGeorge Cherian 	return 0;
479c694b233SGeorge Cherian }
480c694b233SGeorge Cherian 
481c694b233SGeorge Cherian void cvm_crypto_exit(void)
482c694b233SGeorge Cherian {
483c694b233SGeorge Cherian 	u32 dev_count;
484c694b233SGeorge Cherian 
485c694b233SGeorge Cherian 	dev_count = --dev_handle.dev_count;
486c694b233SGeorge Cherian 	if (!dev_count)
487c694b233SGeorge Cherian 		cav_unregister_algs();
488c694b233SGeorge Cherian }
489