xref: /openbmc/linux/drivers/crypto/cavium/cpt/cptvf_algs.c (revision 10d82222d9411dcc0ebcb11ca110597246696af4)
1c694b233SGeorge Cherian 
2c694b233SGeorge Cherian /*
3c694b233SGeorge Cherian  * Copyright (C) 2016 Cavium, Inc.
4c694b233SGeorge Cherian  *
5c694b233SGeorge Cherian  * This program is free software; you can redistribute it and/or modify it
6c694b233SGeorge Cherian  * under the terms of version 2 of the GNU General Public License
7c694b233SGeorge Cherian  * as published by the Free Software Foundation.
8c694b233SGeorge Cherian  */
9c694b233SGeorge Cherian 
10c694b233SGeorge Cherian #include <crypto/aes.h>
11c694b233SGeorge Cherian #include <crypto/algapi.h>
12c694b233SGeorge Cherian #include <crypto/authenc.h>
13c694b233SGeorge Cherian #include <crypto/cryptd.h>
14c694b233SGeorge Cherian #include <crypto/crypto_wq.h>
15c694b233SGeorge Cherian #include <crypto/des.h>
16c694b233SGeorge Cherian #include <crypto/xts.h>
17c694b233SGeorge Cherian #include <linux/crypto.h>
18c694b233SGeorge Cherian #include <linux/err.h>
19c694b233SGeorge Cherian #include <linux/list.h>
20c694b233SGeorge Cherian #include <linux/scatterlist.h>
21c694b233SGeorge Cherian 
22c694b233SGeorge Cherian #include "cptvf.h"
23c694b233SGeorge Cherian #include "cptvf_algs.h"
24c694b233SGeorge Cherian 
25c694b233SGeorge Cherian struct cpt_device_handle {
26c694b233SGeorge Cherian 	void *cdev[MAX_DEVICES];
27c694b233SGeorge Cherian 	u32 dev_count;
28c694b233SGeorge Cherian };
29c694b233SGeorge Cherian 
30c694b233SGeorge Cherian static struct cpt_device_handle dev_handle;
31c694b233SGeorge Cherian 
32c694b233SGeorge Cherian static void cvm_callback(u32 status, void *arg)
33c694b233SGeorge Cherian {
34c694b233SGeorge Cherian 	struct crypto_async_request *req = (struct crypto_async_request *)arg;
35c694b233SGeorge Cherian 
36c694b233SGeorge Cherian 	req->complete(req, !status);
37c694b233SGeorge Cherian }
38c694b233SGeorge Cherian 
39c694b233SGeorge Cherian static inline void update_input_iv(struct cpt_request_info *req_info,
40c694b233SGeorge Cherian 				   u8 *iv, u32 enc_iv_len,
41c694b233SGeorge Cherian 				   u32 *argcnt)
42c694b233SGeorge Cherian {
43c694b233SGeorge Cherian 	/* Setting the iv information */
44c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (void *)iv;
45c694b233SGeorge Cherian 	req_info->in[*argcnt].size = enc_iv_len;
46c694b233SGeorge Cherian 	req_info->req.dlen += enc_iv_len;
47c694b233SGeorge Cherian 
48c694b233SGeorge Cherian 	++(*argcnt);
49c694b233SGeorge Cherian }
50c694b233SGeorge Cherian 
51c694b233SGeorge Cherian static inline void update_output_iv(struct cpt_request_info *req_info,
52c694b233SGeorge Cherian 				    u8 *iv, u32 enc_iv_len,
53c694b233SGeorge Cherian 				    u32 *argcnt)
54c694b233SGeorge Cherian {
55c694b233SGeorge Cherian 	/* Setting the iv information */
56c694b233SGeorge Cherian 	req_info->out[*argcnt].vptr = (void *)iv;
57c694b233SGeorge Cherian 	req_info->out[*argcnt].size = enc_iv_len;
58c694b233SGeorge Cherian 	req_info->rlen += enc_iv_len;
59c694b233SGeorge Cherian 
60c694b233SGeorge Cherian 	++(*argcnt);
61c694b233SGeorge Cherian }
62c694b233SGeorge Cherian 
63c694b233SGeorge Cherian static inline void update_input_data(struct cpt_request_info *req_info,
64c694b233SGeorge Cherian 				     struct scatterlist *inp_sg,
65c694b233SGeorge Cherian 				     u32 nbytes, u32 *argcnt)
66c694b233SGeorge Cherian {
67c694b233SGeorge Cherian 	req_info->req.dlen += nbytes;
68c694b233SGeorge Cherian 
69c694b233SGeorge Cherian 	while (nbytes) {
70c694b233SGeorge Cherian 		u32 len = min(nbytes, inp_sg->length);
71c694b233SGeorge Cherian 		u8 *ptr = sg_virt(inp_sg);
72c694b233SGeorge Cherian 
73c694b233SGeorge Cherian 		req_info->in[*argcnt].vptr = (void *)ptr;
74c694b233SGeorge Cherian 		req_info->in[*argcnt].size = len;
75c694b233SGeorge Cherian 		nbytes -= len;
76c694b233SGeorge Cherian 
77c694b233SGeorge Cherian 		++(*argcnt);
78c694b233SGeorge Cherian 		++inp_sg;
79c694b233SGeorge Cherian 	}
80c694b233SGeorge Cherian }
81c694b233SGeorge Cherian 
82c694b233SGeorge Cherian static inline void update_output_data(struct cpt_request_info *req_info,
83c694b233SGeorge Cherian 				      struct scatterlist *outp_sg,
84c694b233SGeorge Cherian 				      u32 nbytes, u32 *argcnt)
85c694b233SGeorge Cherian {
86c694b233SGeorge Cherian 	req_info->rlen += nbytes;
87c694b233SGeorge Cherian 
88c694b233SGeorge Cherian 	while (nbytes) {
89c694b233SGeorge Cherian 		u32 len = min(nbytes, outp_sg->length);
90c694b233SGeorge Cherian 		u8 *ptr = sg_virt(outp_sg);
91c694b233SGeorge Cherian 
92c694b233SGeorge Cherian 		req_info->out[*argcnt].vptr = (void *)ptr;
93c694b233SGeorge Cherian 		req_info->out[*argcnt].size = len;
94c694b233SGeorge Cherian 		nbytes -= len;
95c694b233SGeorge Cherian 		++(*argcnt);
96c694b233SGeorge Cherian 		++outp_sg;
97c694b233SGeorge Cherian 	}
98c694b233SGeorge Cherian }
99c694b233SGeorge Cherian 
100c694b233SGeorge Cherian static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc,
101c694b233SGeorge Cherian 				 u32 *argcnt)
102c694b233SGeorge Cherian {
103c694b233SGeorge Cherian 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
104c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm);
105c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
106c694b233SGeorge Cherian 	struct fc_context *fctx = &rctx->fctx;
107c694b233SGeorge Cherian 	u64 *offset_control = &rctx->control_word;
108c694b233SGeorge Cherian 	u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
109c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
110c694b233SGeorge Cherian 	u64 *ctrl_flags = NULL;
111c694b233SGeorge Cherian 
112c694b233SGeorge Cherian 	req_info->ctrl.s.grp = 0;
113c694b233SGeorge Cherian 	req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER;
114c694b233SGeorge Cherian 	req_info->ctrl.s.se_req = SE_CORE_REQ;
115c694b233SGeorge Cherian 
116c694b233SGeorge Cherian 	req_info->req.opcode.s.major = MAJOR_OP_FC |
117c694b233SGeorge Cherian 					DMA_MODE_FLAG(DMA_GATHER_SCATTER);
118c694b233SGeorge Cherian 	if (enc)
119c694b233SGeorge Cherian 		req_info->req.opcode.s.minor = 2;
120c694b233SGeorge Cherian 	else
121c694b233SGeorge Cherian 		req_info->req.opcode.s.minor = 3;
122c694b233SGeorge Cherian 
123c694b233SGeorge Cherian 	req_info->req.param1 = req->nbytes; /* Encryption Data length */
124c694b233SGeorge Cherian 	req_info->req.param2 = 0; /*Auth data length */
125c694b233SGeorge Cherian 
126e2eb769eSGeorge Cherian 	fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;
127e2eb769eSGeorge Cherian 	fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;
128c694b233SGeorge Cherian 	fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR;
129c694b233SGeorge Cherian 
130e2eb769eSGeorge Cherian 	if (ctx->cipher_type == AES_XTS)
131c694b233SGeorge Cherian 		memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);
132c694b233SGeorge Cherian 	else
133c694b233SGeorge Cherian 		memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);
134c694b233SGeorge Cherian 	ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags;
135c694b233SGeorge Cherian 	*ctrl_flags = cpu_to_be64(*ctrl_flags);
136c694b233SGeorge Cherian 
137c694b233SGeorge Cherian 	*offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16));
138c694b233SGeorge Cherian 	/* Storing  Packet Data Information in offset
139c694b233SGeorge Cherian 	 * Control Word First 8 bytes
140c694b233SGeorge Cherian 	 */
141c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (u8 *)offset_control;
142c694b233SGeorge Cherian 	req_info->in[*argcnt].size = CONTROL_WORD_LEN;
143c694b233SGeorge Cherian 	req_info->req.dlen += CONTROL_WORD_LEN;
144c694b233SGeorge Cherian 	++(*argcnt);
145c694b233SGeorge Cherian 
146c694b233SGeorge Cherian 	req_info->in[*argcnt].vptr = (u8 *)fctx;
147c694b233SGeorge Cherian 	req_info->in[*argcnt].size = sizeof(struct fc_context);
148c694b233SGeorge Cherian 	req_info->req.dlen += sizeof(struct fc_context);
149c694b233SGeorge Cherian 
150c694b233SGeorge Cherian 	++(*argcnt);
151c694b233SGeorge Cherian 
152c694b233SGeorge Cherian 	return 0;
153c694b233SGeorge Cherian }
154c694b233SGeorge Cherian 
155c694b233SGeorge Cherian static inline u32 create_input_list(struct ablkcipher_request  *req, u32 enc,
156c694b233SGeorge Cherian 				    u32 enc_iv_len)
157c694b233SGeorge Cherian {
158c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
159c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
160c694b233SGeorge Cherian 	u32 argcnt =  0;
161c694b233SGeorge Cherian 
162e2eb769eSGeorge Cherian 	create_ctx_hdr(req, enc, &argcnt);
163c694b233SGeorge Cherian 	update_input_iv(req_info, req->info, enc_iv_len, &argcnt);
164c694b233SGeorge Cherian 	update_input_data(req_info, req->src, req->nbytes, &argcnt);
165c694b233SGeorge Cherian 	req_info->incnt = argcnt;
166c694b233SGeorge Cherian 
167c694b233SGeorge Cherian 	return 0;
168c694b233SGeorge Cherian }
169c694b233SGeorge Cherian 
170c694b233SGeorge Cherian static inline void store_cb_info(struct ablkcipher_request *req,
171c694b233SGeorge Cherian 				 struct cpt_request_info *req_info)
172c694b233SGeorge Cherian {
173c694b233SGeorge Cherian 	req_info->callback = (void *)cvm_callback;
174c694b233SGeorge Cherian 	req_info->callback_arg = (void *)&req->base;
175c694b233SGeorge Cherian }
176c694b233SGeorge Cherian 
177c694b233SGeorge Cherian static inline void create_output_list(struct ablkcipher_request *req,
178c694b233SGeorge Cherian 				      u32 enc_iv_len)
179c694b233SGeorge Cherian {
180c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
181c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
182c694b233SGeorge Cherian 	u32 argcnt = 0;
183c694b233SGeorge Cherian 
184c694b233SGeorge Cherian 	/* OUTPUT Buffer Processing
185c694b233SGeorge Cherian 	 * AES encryption/decryption output would be
186c694b233SGeorge Cherian 	 * received in the following format
187c694b233SGeorge Cherian 	 *
188c694b233SGeorge Cherian 	 * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
189c694b233SGeorge Cherian 	 * [ 16 Bytes/     [   Request Enc/Dec/ DATA Len AES CBC ]
190c694b233SGeorge Cherian 	 */
191c694b233SGeorge Cherian 	/* Reading IV information */
192c694b233SGeorge Cherian 	update_output_iv(req_info, req->info, enc_iv_len, &argcnt);
193c694b233SGeorge Cherian 	update_output_data(req_info, req->dst, req->nbytes, &argcnt);
194c694b233SGeorge Cherian 	req_info->outcnt = argcnt;
195c694b233SGeorge Cherian }
196c694b233SGeorge Cherian 
197e2eb769eSGeorge Cherian static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc)
198c694b233SGeorge Cherian {
199c694b233SGeorge Cherian 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
200c694b233SGeorge Cherian 	struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
201c694b233SGeorge Cherian 	u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
202c694b233SGeorge Cherian 	struct fc_context *fctx = &rctx->fctx;
203c694b233SGeorge Cherian 	struct cpt_request_info *req_info = &rctx->cpt_req;
204c694b233SGeorge Cherian 	void *cdev = NULL;
205c694b233SGeorge Cherian 	int status;
206c694b233SGeorge Cherian 
207c694b233SGeorge Cherian 	memset(req_info, 0, sizeof(struct cpt_request_info));
208c694b233SGeorge Cherian 	memset(fctx, 0, sizeof(struct fc_context));
209e2eb769eSGeorge Cherian 	create_input_list(req, enc, enc_iv_len);
210e2eb769eSGeorge Cherian 	create_output_list(req, enc_iv_len);
211c694b233SGeorge Cherian 	store_cb_info(req, req_info);
212c694b233SGeorge Cherian 	cdev = dev_handle.cdev[smp_processor_id()];
213c694b233SGeorge Cherian 	status = cptvf_do_request(cdev, req_info);
214c694b233SGeorge Cherian 	/* We perform an asynchronous send and once
215c694b233SGeorge Cherian 	 * the request is completed the driver would
216c694b233SGeorge Cherian 	 * intimate through  registered call back functions
217c694b233SGeorge Cherian 	 */
218c694b233SGeorge Cherian 
219c694b233SGeorge Cherian 	if (status)
220c694b233SGeorge Cherian 		return status;
221c694b233SGeorge Cherian 	else
222c694b233SGeorge Cherian 		return -EINPROGRESS;
223c694b233SGeorge Cherian }
224c694b233SGeorge Cherian 
225e2eb769eSGeorge Cherian int cvm_encrypt(struct ablkcipher_request *req)
226c694b233SGeorge Cherian {
227e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, true);
228c694b233SGeorge Cherian }
229c694b233SGeorge Cherian 
230e2eb769eSGeorge Cherian int cvm_decrypt(struct ablkcipher_request *req)
231c694b233SGeorge Cherian {
232e2eb769eSGeorge Cherian 	return cvm_enc_dec(req, false);
233c694b233SGeorge Cherian }
234c694b233SGeorge Cherian 
235c694b233SGeorge Cherian int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
236c694b233SGeorge Cherian 		   u32 keylen)
237c694b233SGeorge Cherian {
238c694b233SGeorge Cherian 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
239c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
240c694b233SGeorge Cherian 	int err;
241c694b233SGeorge Cherian 	const u8 *key1 = key;
242c694b233SGeorge Cherian 	const u8 *key2 = key + (keylen / 2);
243c694b233SGeorge Cherian 
244c694b233SGeorge Cherian 	err = xts_check_key(tfm, key, keylen);
245c694b233SGeorge Cherian 	if (err)
246c694b233SGeorge Cherian 		return err;
247c694b233SGeorge Cherian 	ctx->key_len = keylen;
248c694b233SGeorge Cherian 	memcpy(ctx->enc_key, key1, keylen / 2);
249c694b233SGeorge Cherian 	memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
250e2eb769eSGeorge Cherian 	ctx->cipher_type = AES_XTS;
251e2eb769eSGeorge Cherian 	switch (ctx->key_len) {
252e2eb769eSGeorge Cherian 	case 32:
253e2eb769eSGeorge Cherian 		ctx->key_type = AES_128_BIT;
254e2eb769eSGeorge Cherian 		break;
255e2eb769eSGeorge Cherian 	case 64:
256e2eb769eSGeorge Cherian 		ctx->key_type = AES_256_BIT;
257e2eb769eSGeorge Cherian 		break;
258e2eb769eSGeorge Cherian 	default:
259e2eb769eSGeorge Cherian 		return -EINVAL;
260e2eb769eSGeorge Cherian 	}
261c694b233SGeorge Cherian 
262c694b233SGeorge Cherian 	return 0;
263c694b233SGeorge Cherian }
264c694b233SGeorge Cherian 
265e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen)
266e2eb769eSGeorge Cherian {
267e2eb769eSGeorge Cherian 	if ((keylen == 16) || (keylen == 24) || (keylen == 32)) {
268e2eb769eSGeorge Cherian 		ctx->key_len = keylen;
269e2eb769eSGeorge Cherian 		switch (ctx->key_len) {
270e2eb769eSGeorge Cherian 		case 16:
271e2eb769eSGeorge Cherian 			ctx->key_type = AES_128_BIT;
272e2eb769eSGeorge Cherian 			break;
273e2eb769eSGeorge Cherian 		case 24:
274e2eb769eSGeorge Cherian 			ctx->key_type = AES_192_BIT;
275e2eb769eSGeorge Cherian 			break;
276e2eb769eSGeorge Cherian 		case 32:
277e2eb769eSGeorge Cherian 			ctx->key_type = AES_256_BIT;
278e2eb769eSGeorge Cherian 			break;
279e2eb769eSGeorge Cherian 		default:
280e2eb769eSGeorge Cherian 			return -EINVAL;
281e2eb769eSGeorge Cherian 		}
282e2eb769eSGeorge Cherian 
283e2eb769eSGeorge Cherian 		if (ctx->cipher_type == DES3_CBC)
284e2eb769eSGeorge Cherian 			ctx->key_type = 0;
285e2eb769eSGeorge Cherian 
286e2eb769eSGeorge Cherian 		return 0;
287e2eb769eSGeorge Cherian 	}
288e2eb769eSGeorge Cherian 
289e2eb769eSGeorge Cherian 	return -EINVAL;
290e2eb769eSGeorge Cherian }
291e2eb769eSGeorge Cherian 
292e2eb769eSGeorge Cherian static int cvm_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
293e2eb769eSGeorge Cherian 		      u32 keylen, u8 cipher_type)
294c694b233SGeorge Cherian {
295c694b233SGeorge Cherian 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
296c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
297c694b233SGeorge Cherian 
298e2eb769eSGeorge Cherian 	ctx->cipher_type = cipher_type;
299e2eb769eSGeorge Cherian 	if (!cvm_validate_keylen(ctx, keylen)) {
300c694b233SGeorge Cherian 		memcpy(ctx->enc_key, key, keylen);
301c694b233SGeorge Cherian 		return 0;
302e2eb769eSGeorge Cherian 	} else {
303e2eb769eSGeorge Cherian 		crypto_ablkcipher_set_flags(cipher,
304e2eb769eSGeorge Cherian 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
305c694b233SGeorge Cherian 		return -EINVAL;
306c694b233SGeorge Cherian 	}
307e2eb769eSGeorge Cherian }
308e2eb769eSGeorge Cherian 
309e2eb769eSGeorge Cherian static int cvm_cbc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
310e2eb769eSGeorge Cherian 			      u32 keylen)
311e2eb769eSGeorge Cherian {
312e2eb769eSGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CBC);
313e2eb769eSGeorge Cherian }
314e2eb769eSGeorge Cherian 
315*10d82222SGeorge Cherian static int cvm_ecb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
316*10d82222SGeorge Cherian 			      u32 keylen)
317*10d82222SGeorge Cherian {
318*10d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_ECB);
319*10d82222SGeorge Cherian }
320*10d82222SGeorge Cherian 
321*10d82222SGeorge Cherian static int cvm_cfb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
322*10d82222SGeorge Cherian 			      u32 keylen)
323*10d82222SGeorge Cherian {
324*10d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, AES_CFB);
325*10d82222SGeorge Cherian }
326*10d82222SGeorge Cherian 
327e2eb769eSGeorge Cherian static int cvm_cbc_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
328e2eb769eSGeorge Cherian 			       u32 keylen)
329e2eb769eSGeorge Cherian {
330e2eb769eSGeorge Cherian 	return cvm_setkey(cipher, key, keylen, DES3_CBC);
331e2eb769eSGeorge Cherian }
332c694b233SGeorge Cherian 
333*10d82222SGeorge Cherian static int cvm_ecb_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
334*10d82222SGeorge Cherian 			       u32 keylen)
335*10d82222SGeorge Cherian {
336*10d82222SGeorge Cherian 	return cvm_setkey(cipher, key, keylen, DES3_ECB);
337*10d82222SGeorge Cherian }
338*10d82222SGeorge Cherian 
339c694b233SGeorge Cherian int cvm_enc_dec_init(struct crypto_tfm *tfm)
340c694b233SGeorge Cherian {
341c694b233SGeorge Cherian 	struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
342c694b233SGeorge Cherian 
343c694b233SGeorge Cherian 	memset(ctx, 0, sizeof(*ctx));
344c694b233SGeorge Cherian 	tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx) +
345c694b233SGeorge Cherian 					sizeof(struct ablkcipher_request);
346c694b233SGeorge Cherian 	/* Additional memory for ablkcipher_request is
347c694b233SGeorge Cherian 	 * allocated since the cryptd daemon uses
348c694b233SGeorge Cherian 	 * this memory for request_ctx information
349c694b233SGeorge Cherian 	 */
350c694b233SGeorge Cherian 
351c694b233SGeorge Cherian 	return 0;
352c694b233SGeorge Cherian }
353c694b233SGeorge Cherian 
354c694b233SGeorge Cherian struct crypto_alg algs[] = { {
355c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
356c694b233SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
357c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
358c694b233SGeorge Cherian 	.cra_alignmask = 7,
359c694b233SGeorge Cherian 	.cra_priority = 4001,
360c694b233SGeorge Cherian 	.cra_name = "xts(aes)",
361c694b233SGeorge Cherian 	.cra_driver_name = "cavium-xts-aes",
362c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
363c694b233SGeorge Cherian 	.cra_u = {
364c694b233SGeorge Cherian 		.ablkcipher = {
365c694b233SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
366c694b233SGeorge Cherian 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
367c694b233SGeorge Cherian 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
368c694b233SGeorge Cherian 			.setkey = cvm_xts_setkey,
369e2eb769eSGeorge Cherian 			.encrypt = cvm_encrypt,
370e2eb769eSGeorge Cherian 			.decrypt = cvm_decrypt,
371c694b233SGeorge Cherian 		},
372c694b233SGeorge Cherian 	},
373c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
374c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
375c694b233SGeorge Cherian }, {
376c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
377c694b233SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
378c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
379c694b233SGeorge Cherian 	.cra_alignmask = 7,
380c694b233SGeorge Cherian 	.cra_priority = 4001,
381c694b233SGeorge Cherian 	.cra_name = "cbc(aes)",
382c694b233SGeorge Cherian 	.cra_driver_name = "cavium-cbc-aes",
383c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
384c694b233SGeorge Cherian 	.cra_u = {
385c694b233SGeorge Cherian 		.ablkcipher = {
386c694b233SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
387c694b233SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
388c694b233SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
389e2eb769eSGeorge Cherian 			.setkey = cvm_cbc_aes_setkey,
390e2eb769eSGeorge Cherian 			.encrypt = cvm_encrypt,
391e2eb769eSGeorge Cherian 			.decrypt = cvm_decrypt,
392c694b233SGeorge Cherian 		},
393c694b233SGeorge Cherian 	},
394c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
395c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
396c694b233SGeorge Cherian }, {
397c694b233SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
398*10d82222SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
399*10d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
400*10d82222SGeorge Cherian 	.cra_alignmask = 7,
401*10d82222SGeorge Cherian 	.cra_priority = 4001,
402*10d82222SGeorge Cherian 	.cra_name = "ecb(aes)",
403*10d82222SGeorge Cherian 	.cra_driver_name = "cavium-ecb-aes",
404*10d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
405*10d82222SGeorge Cherian 	.cra_u = {
406*10d82222SGeorge Cherian 		.ablkcipher = {
407*10d82222SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
408*10d82222SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
409*10d82222SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
410*10d82222SGeorge Cherian 			.setkey = cvm_ecb_aes_setkey,
411*10d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
412*10d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
413*10d82222SGeorge Cherian 		},
414*10d82222SGeorge Cherian 	},
415*10d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
416*10d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
417*10d82222SGeorge Cherian }, {
418*10d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
419*10d82222SGeorge Cherian 	.cra_blocksize = AES_BLOCK_SIZE,
420*10d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_enc_ctx),
421*10d82222SGeorge Cherian 	.cra_alignmask = 7,
422*10d82222SGeorge Cherian 	.cra_priority = 4001,
423*10d82222SGeorge Cherian 	.cra_name = "cfb(aes)",
424*10d82222SGeorge Cherian 	.cra_driver_name = "cavium-cfb-aes",
425*10d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
426*10d82222SGeorge Cherian 	.cra_u = {
427*10d82222SGeorge Cherian 		.ablkcipher = {
428*10d82222SGeorge Cherian 			.ivsize = AES_BLOCK_SIZE,
429*10d82222SGeorge Cherian 			.min_keysize = AES_MIN_KEY_SIZE,
430*10d82222SGeorge Cherian 			.max_keysize = AES_MAX_KEY_SIZE,
431*10d82222SGeorge Cherian 			.setkey = cvm_cfb_aes_setkey,
432*10d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
433*10d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
434*10d82222SGeorge Cherian 		},
435*10d82222SGeorge Cherian 	},
436*10d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
437*10d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
438*10d82222SGeorge Cherian }, {
439*10d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
440c694b233SGeorge Cherian 	.cra_blocksize = DES3_EDE_BLOCK_SIZE,
441c694b233SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_des3_ctx),
442c694b233SGeorge Cherian 	.cra_alignmask = 7,
443c694b233SGeorge Cherian 	.cra_priority = 4001,
444c694b233SGeorge Cherian 	.cra_name = "cbc(des3_ede)",
445c694b233SGeorge Cherian 	.cra_driver_name = "cavium-cbc-des3_ede",
446c694b233SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
447c694b233SGeorge Cherian 	.cra_u = {
448c694b233SGeorge Cherian 		.ablkcipher = {
449c694b233SGeorge Cherian 			.min_keysize = DES3_EDE_KEY_SIZE,
450c694b233SGeorge Cherian 			.max_keysize = DES3_EDE_KEY_SIZE,
451c694b233SGeorge Cherian 			.ivsize = DES_BLOCK_SIZE,
452e2eb769eSGeorge Cherian 			.setkey = cvm_cbc_des3_setkey,
453e2eb769eSGeorge Cherian 			.encrypt = cvm_encrypt,
454e2eb769eSGeorge Cherian 			.decrypt = cvm_decrypt,
455c694b233SGeorge Cherian 		},
456c694b233SGeorge Cherian 	},
457c694b233SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
458c694b233SGeorge Cherian 	.cra_module = THIS_MODULE,
459*10d82222SGeorge Cherian }, {
460*10d82222SGeorge Cherian 	.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
461*10d82222SGeorge Cherian 	.cra_blocksize = DES3_EDE_BLOCK_SIZE,
462*10d82222SGeorge Cherian 	.cra_ctxsize = sizeof(struct cvm_des3_ctx),
463*10d82222SGeorge Cherian 	.cra_alignmask = 7,
464*10d82222SGeorge Cherian 	.cra_priority = 4001,
465*10d82222SGeorge Cherian 	.cra_name = "ecb(des3_ede)",
466*10d82222SGeorge Cherian 	.cra_driver_name = "cavium-ecb-des3_ede",
467*10d82222SGeorge Cherian 	.cra_type = &crypto_ablkcipher_type,
468*10d82222SGeorge Cherian 	.cra_u = {
469*10d82222SGeorge Cherian 		.ablkcipher = {
470*10d82222SGeorge Cherian 			.min_keysize = DES3_EDE_KEY_SIZE,
471*10d82222SGeorge Cherian 			.max_keysize = DES3_EDE_KEY_SIZE,
472*10d82222SGeorge Cherian 			.ivsize = DES_BLOCK_SIZE,
473*10d82222SGeorge Cherian 			.setkey = cvm_ecb_des3_setkey,
474*10d82222SGeorge Cherian 			.encrypt = cvm_encrypt,
475*10d82222SGeorge Cherian 			.decrypt = cvm_decrypt,
476*10d82222SGeorge Cherian 		},
477*10d82222SGeorge Cherian 	},
478*10d82222SGeorge Cherian 	.cra_init = cvm_enc_dec_init,
479*10d82222SGeorge Cherian 	.cra_module = THIS_MODULE,
480c694b233SGeorge Cherian } };
481c694b233SGeorge Cherian 
482c694b233SGeorge Cherian static inline int cav_register_algs(void)
483c694b233SGeorge Cherian {
484c694b233SGeorge Cherian 	int err = 0;
485c694b233SGeorge Cherian 
486c694b233SGeorge Cherian 	err = crypto_register_algs(algs, ARRAY_SIZE(algs));
487c694b233SGeorge Cherian 	if (err)
488c694b233SGeorge Cherian 		return err;
489c694b233SGeorge Cherian 
490c694b233SGeorge Cherian 	return 0;
491c694b233SGeorge Cherian }
492c694b233SGeorge Cherian 
493c694b233SGeorge Cherian static inline void cav_unregister_algs(void)
494c694b233SGeorge Cherian {
495c694b233SGeorge Cherian 	crypto_unregister_algs(algs, ARRAY_SIZE(algs));
496c694b233SGeorge Cherian }
497c694b233SGeorge Cherian 
498c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf)
499c694b233SGeorge Cherian {
500c694b233SGeorge Cherian 	struct pci_dev *pdev = cptvf->pdev;
501c694b233SGeorge Cherian 	u32 dev_count;
502c694b233SGeorge Cherian 
503c694b233SGeorge Cherian 	dev_count = dev_handle.dev_count;
504c694b233SGeorge Cherian 	dev_handle.cdev[dev_count] = cptvf;
505c694b233SGeorge Cherian 	dev_handle.dev_count++;
506c694b233SGeorge Cherian 
507c694b233SGeorge Cherian 	if (dev_count == 3) {
508c694b233SGeorge Cherian 		if (cav_register_algs()) {
509c694b233SGeorge Cherian 			dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
510c694b233SGeorge Cherian 			return -EINVAL;
511c694b233SGeorge Cherian 		}
512c694b233SGeorge Cherian 	}
513c694b233SGeorge Cherian 
514c694b233SGeorge Cherian 	return 0;
515c694b233SGeorge Cherian }
516c694b233SGeorge Cherian 
517c694b233SGeorge Cherian void cvm_crypto_exit(void)
518c694b233SGeorge Cherian {
519c694b233SGeorge Cherian 	u32 dev_count;
520c694b233SGeorge Cherian 
521c694b233SGeorge Cherian 	dev_count = --dev_handle.dev_count;
522c694b233SGeorge Cherian 	if (!dev_count)
523c694b233SGeorge Cherian 		cav_unregister_algs();
524c694b233SGeorge Cherian }
525