xref: /openbmc/linux/drivers/crypto/cavium/cpt/cptvf_algs.c (revision 0e1cbe9795ace1ea5e1621e52b9d918d9382fcfd)
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>
10*0e1cbe97SArd 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 
95c694b233SGeorge Cherian static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc,
96c694b233SGeorge Cherian 				 u32 *argcnt)
97c694b233SGeorge Cherian {
98c694b233SGeorge Cherian 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
99c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm);
100c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
101c694b233SGeorge Cherian 	struct fc_context *fctx = &rctx->fctx;
102c694b233SGeorge Cherian 	u64 *offset_control = &rctx->control_word;
103c694b233SGeorge Cherian 	u32 enc_iv_len = crypto_ablkcipher_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 
118c694b233SGeorge Cherian 	req_info->req.param1 = req->nbytes; /* 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 
150c694b233SGeorge Cherian static inline u32 create_input_list(struct ablkcipher_request  *req, u32 enc,
151c694b233SGeorge Cherian 				    u32 enc_iv_len)
152c694b233SGeorge Cherian {
153c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_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);
158c694b233SGeorge Cherian 	update_input_iv(req_info, req->info, enc_iv_len, &argcnt);
159c694b233SGeorge Cherian 	update_input_data(req_info, req->src, req->nbytes, &argcnt);
160c694b233SGeorge Cherian 	req_info->incnt = argcnt;
161c694b233SGeorge Cherian 
162c694b233SGeorge Cherian 	return 0;
163c694b233SGeorge Cherian }
164c694b233SGeorge Cherian 
165c694b233SGeorge Cherian static inline void store_cb_info(struct ablkcipher_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 
172c694b233SGeorge Cherian static inline void create_output_list(struct ablkcipher_request *req,
173c694b233SGeorge Cherian 				      u32 enc_iv_len)
174c694b233SGeorge Cherian {
175c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_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 */
187c694b233SGeorge Cherian 	update_output_iv(req_info, req->info, enc_iv_len, &argcnt);
188c694b233SGeorge Cherian 	update_output_data(req_info, req->dst, req->nbytes, &argcnt);
189c694b233SGeorge Cherian 	req_info->outcnt = argcnt;
190c694b233SGeorge Cherian }
191c694b233SGeorge Cherian 
192e2eb769eSGeorge Cherian static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc)
193c694b233SGeorge Cherian {
194c694b233SGeorge Cherian 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
195c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
196c694b233SGeorge Cherian 	u32 enc_iv_len = crypto_ablkcipher_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 
220b8fc3397SColin Ian King static int cvm_encrypt(struct ablkcipher_request *req)
221c694b233SGeorge Cherian {
222e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, true);
223c694b233SGeorge Cherian }
224c694b233SGeorge Cherian 
225b8fc3397SColin Ian King static int cvm_decrypt(struct ablkcipher_request *req)
226c694b233SGeorge Cherian {
227e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, false);
228c694b233SGeorge Cherian }
229c694b233SGeorge Cherian 
230b8fc3397SColin Ian King static int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
231c694b233SGeorge Cherian 		   u32 keylen)
232c694b233SGeorge Cherian {
233c694b233SGeorge Cherian 	struct crypto_tfm *tfm = crypto_ablkcipher_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 
287e2eb769eSGeorge Cherian static int cvm_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
288e2eb769eSGeorge Cherian 		      u32 keylen, u8 cipher_type)
289c694b233SGeorge Cherian {
290c694b233SGeorge Cherian 	struct crypto_tfm *tfm = crypto_ablkcipher_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 {
298e2eb769eSGeorge Cherian 		crypto_ablkcipher_set_flags(cipher,
299e2eb769eSGeorge Cherian 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
300c694b233SGeorge Cherian 		return -EINVAL;
301c694b233SGeorge Cherian 	}
302e2eb769eSGeorge Cherian }
303e2eb769eSGeorge Cherian 
304e2eb769eSGeorge Cherian static int cvm_cbc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
305e2eb769eSGeorge Cherian 			      u32 keylen)
306e2eb769eSGeorge Cherian {
307e2eb769eSGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CBC);
308e2eb769eSGeorge Cherian }
309e2eb769eSGeorge Cherian 
31010d82222SGeorge Cherian static int cvm_ecb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
31110d82222SGeorge Cherian 			      u32 keylen)
31210d82222SGeorge Cherian {
31310d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_ECB);
31410d82222SGeorge Cherian }
31510d82222SGeorge Cherian 
31610d82222SGeorge Cherian static int cvm_cfb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
31710d82222SGeorge Cherian 			      u32 keylen)
31810d82222SGeorge Cherian {
31910d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CFB);
32010d82222SGeorge Cherian }
32110d82222SGeorge Cherian 
322e2eb769eSGeorge Cherian static int cvm_cbc_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
323e2eb769eSGeorge Cherian 			       u32 keylen)
324e2eb769eSGeorge Cherian {
325*0e1cbe97SArd Biesheuvel 	return verify_ablkcipher_des3_key(cipher, key) ?:
326*0e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_CBC);
327e2eb769eSGeorge Cherian }
328c694b233SGeorge Cherian 
32910d82222SGeorge Cherian static int cvm_ecb_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
33010d82222SGeorge Cherian 			       u32 keylen)
33110d82222SGeorge Cherian {
332*0e1cbe97SArd Biesheuvel 	return verify_ablkcipher_des3_key(cipher, key) ?:
333*0e1cbe97SArd Biesheuvel 	       cvm_setkey(cipher, key, keylen, DES3_ECB);
33410d82222SGeorge Cherian }
33510d82222SGeorge Cherian 
336b8fc3397SColin Ian King static int cvm_enc_dec_init(struct crypto_tfm *tfm)
337c694b233SGeorge Cherian {
3380edf8593SEric Biggers 	tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx);
339c694b233SGeorge Cherian 	return 0;
340c694b233SGeorge Cherian }
341c694b233SGeorge Cherian 
3422a2b9461SColin Ian King static struct crypto_alg algs[] = { {
343c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
344c694b233SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
345c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
346c694b233SGeorge Cherian 	.cra_alignmask = 7,
347c694b233SGeorge Cherian 	.cra_priority = 4001,
348c694b233SGeorge Cherian 	.cra_name = "xts(aes)",
349c694b233SGeorge Cherian 	.cra_driver_name = "cavium-xts-aes",
350c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
351c694b233SGeorge Cherian 	.cra_u = {
352c694b233SGeorge Cherian 		.ablkcipher = {
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,
359c694b233SGeorge Cherian 		},
360c694b233SGeorge Cherian 	},
361c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
362c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
363c694b233SGeorge Cherian }, {
364c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
365c694b233SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
366c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
367c694b233SGeorge Cherian 	.cra_alignmask = 7,
368c694b233SGeorge Cherian 	.cra_priority = 4001,
369c694b233SGeorge Cherian 	.cra_name = "cbc(aes)",
370c694b233SGeorge Cherian 	.cra_driver_name = "cavium-cbc-aes",
371c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
372c694b233SGeorge Cherian 	.cra_u = {
373c694b233SGeorge Cherian 		.ablkcipher = {
374c694b233SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
375c694b233SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
376c694b233SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
377e2eb769eSGeorge Cherian 			.setkey = cvm_cbc_aes_setkey,
378e2eb769eSGeorge Cherian 			.encrypt = cvm_encrypt,
379e2eb769eSGeorge Cherian 			.decrypt = cvm_decrypt,
380c694b233SGeorge Cherian 		},
381c694b233SGeorge Cherian 	},
382c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
383c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
384c694b233SGeorge Cherian }, {
385c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
38610d82222SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
38710d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
38810d82222SGeorge Cherian 	.cra_alignmask = 7,
38910d82222SGeorge Cherian 	.cra_priority = 4001,
39010d82222SGeorge Cherian 	.cra_name = "ecb(aes)",
39110d82222SGeorge Cherian 	.cra_driver_name = "cavium-ecb-aes",
39210d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
39310d82222SGeorge Cherian 	.cra_u = {
39410d82222SGeorge Cherian 		.ablkcipher = {
39510d82222SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
39610d82222SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
39710d82222SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
39810d82222SGeorge Cherian 			.setkey = cvm_ecb_aes_setkey,
39910d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
40010d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
40110d82222SGeorge Cherian 		},
40210d82222SGeorge Cherian 	},
40310d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
40410d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
40510d82222SGeorge Cherian }, {
40610d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
40710d82222SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
40810d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
40910d82222SGeorge Cherian 	.cra_alignmask = 7,
41010d82222SGeorge Cherian 	.cra_priority = 4001,
41110d82222SGeorge Cherian 	.cra_name = "cfb(aes)",
41210d82222SGeorge Cherian 	.cra_driver_name = "cavium-cfb-aes",
41310d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
41410d82222SGeorge Cherian 	.cra_u = {
41510d82222SGeorge Cherian 		.ablkcipher = {
41610d82222SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
41710d82222SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
41810d82222SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
41910d82222SGeorge Cherian 			.setkey = cvm_cfb_aes_setkey,
42010d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
42110d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
42210d82222SGeorge Cherian 		},
42310d82222SGeorge Cherian 	},
42410d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
42510d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
42610d82222SGeorge Cherian }, {
42710d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
428c694b233SGeorge Cherian 	.cra_blocksize = DES3_EDE_BLOCK_SIZE,
429c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_des3_ctx),
430c694b233SGeorge Cherian 	.cra_alignmask = 7,
431c694b233SGeorge Cherian 	.cra_priority = 4001,
432c694b233SGeorge Cherian 	.cra_name = "cbc(des3_ede)",
433c694b233SGeorge Cherian 	.cra_driver_name = "cavium-cbc-des3_ede",
434c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
435c694b233SGeorge Cherian 	.cra_u = {
436c694b233SGeorge Cherian 		.ablkcipher = {
437c694b233SGeorge Cherian 			.min_keysize = DES3_EDE_KEY_SIZE,
438c694b233SGeorge Cherian 			.max_keysize = DES3_EDE_KEY_SIZE,
439c694b233SGeorge Cherian 			.ivsize = DES_BLOCK_SIZE,
440e2eb769eSGeorge Cherian 			.setkey = cvm_cbc_des3_setkey,
441e2eb769eSGeorge Cherian 			.encrypt = cvm_encrypt,
442e2eb769eSGeorge Cherian 			.decrypt = cvm_decrypt,
443c694b233SGeorge Cherian 		},
444c694b233SGeorge Cherian 	},
445c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
446c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
44710d82222SGeorge Cherian }, {
44810d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
44910d82222SGeorge Cherian 	.cra_blocksize = DES3_EDE_BLOCK_SIZE,
45010d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_des3_ctx),
45110d82222SGeorge Cherian 	.cra_alignmask = 7,
45210d82222SGeorge Cherian 	.cra_priority = 4001,
45310d82222SGeorge Cherian 	.cra_name = "ecb(des3_ede)",
45410d82222SGeorge Cherian 	.cra_driver_name = "cavium-ecb-des3_ede",
45510d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
45610d82222SGeorge Cherian 	.cra_u = {
45710d82222SGeorge Cherian 		.ablkcipher = {
45810d82222SGeorge Cherian 			.min_keysize = DES3_EDE_KEY_SIZE,
45910d82222SGeorge Cherian 			.max_keysize = DES3_EDE_KEY_SIZE,
46010d82222SGeorge Cherian 			.ivsize = DES_BLOCK_SIZE,
46110d82222SGeorge Cherian 			.setkey = cvm_ecb_des3_setkey,
46210d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
46310d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
46410d82222SGeorge Cherian 		},
46510d82222SGeorge Cherian 	},
46610d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
46710d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
468c694b233SGeorge Cherian } };
469c694b233SGeorge Cherian 
470c694b233SGeorge Cherian static inline int cav_register_algs(void)
471c694b233SGeorge Cherian {
472c694b233SGeorge Cherian 	int err = 0;
473c694b233SGeorge Cherian 
474c694b233SGeorge Cherian 	err = crypto_register_algs(algs, ARRAY_SIZE(algs));
475c694b233SGeorge Cherian 	if (err)
476c694b233SGeorge Cherian 		return err;
477c694b233SGeorge Cherian 
478c694b233SGeorge Cherian 	return 0;
479c694b233SGeorge Cherian }
480c694b233SGeorge Cherian 
481c694b233SGeorge Cherian static inline void cav_unregister_algs(void)
482c694b233SGeorge Cherian {
483c694b233SGeorge Cherian 	crypto_unregister_algs(algs, ARRAY_SIZE(algs));
484c694b233SGeorge Cherian }
485c694b233SGeorge Cherian 
486c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf)
487c694b233SGeorge Cherian {
488c694b233SGeorge Cherian 	struct pci_dev *pdev = cptvf->pdev;
489c694b233SGeorge Cherian 	u32 dev_count;
490c694b233SGeorge Cherian 
491c694b233SGeorge Cherian 	dev_count = dev_handle.dev_count;
492c694b233SGeorge Cherian 	dev_handle.cdev[dev_count] = cptvf;
493c694b233SGeorge Cherian 	dev_handle.dev_count++;
494c694b233SGeorge Cherian 
495c694b233SGeorge Cherian 	if (dev_count == 3) {
496c694b233SGeorge Cherian 		if (cav_register_algs()) {
497c694b233SGeorge Cherian 			dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
498c694b233SGeorge Cherian 			return -EINVAL;
499c694b233SGeorge Cherian 		}
500c694b233SGeorge Cherian 	}
501c694b233SGeorge Cherian 
502c694b233SGeorge Cherian 	return 0;
503c694b233SGeorge Cherian }
504c694b233SGeorge Cherian 
505c694b233SGeorge Cherian void cvm_crypto_exit(void)
506c694b233SGeorge Cherian {
507c694b233SGeorge Cherian 	u32 dev_count;
508c694b233SGeorge Cherian 
509c694b233SGeorge Cherian 	dev_count = --dev_handle.dev_count;
510c694b233SGeorge Cherian 	if (!dev_count)
511c694b233SGeorge Cherian 		cav_unregister_algs();
512c694b233SGeorge Cherian }
513