16f03f0e8SSrujana Challa // SPDX-License-Identifier: GPL-2.0-only
26f03f0e8SSrujana Challa /* Copyright (C) 2020 Marvell. */
36f03f0e8SSrujana Challa
46f03f0e8SSrujana Challa #include <crypto/aes.h>
56f03f0e8SSrujana Challa #include <crypto/authenc.h>
66f03f0e8SSrujana Challa #include <crypto/cryptd.h>
76f03f0e8SSrujana Challa #include <crypto/des.h>
86f03f0e8SSrujana Challa #include <crypto/internal/aead.h>
96f03f0e8SSrujana Challa #include <crypto/sha1.h>
106f03f0e8SSrujana Challa #include <crypto/sha2.h>
116f03f0e8SSrujana Challa #include <crypto/xts.h>
126f03f0e8SSrujana Challa #include <crypto/gcm.h>
136f03f0e8SSrujana Challa #include <crypto/scatterwalk.h>
146f03f0e8SSrujana Challa #include <linux/sort.h>
156f03f0e8SSrujana Challa #include <linux/module.h>
166f03f0e8SSrujana Challa #include "otx2_cptvf.h"
176f03f0e8SSrujana Challa #include "otx2_cptvf_algs.h"
186f03f0e8SSrujana Challa #include "otx2_cpt_reqmgr.h"
196f03f0e8SSrujana Challa
206f03f0e8SSrujana Challa /* Size of salt in AES GCM mode */
216f03f0e8SSrujana Challa #define AES_GCM_SALT_SIZE 4
226f03f0e8SSrujana Challa /* Size of IV in AES GCM mode */
236f03f0e8SSrujana Challa #define AES_GCM_IV_SIZE 8
246f03f0e8SSrujana Challa /* Size of ICV (Integrity Check Value) in AES GCM mode */
256f03f0e8SSrujana Challa #define AES_GCM_ICV_SIZE 16
266f03f0e8SSrujana Challa /* Offset of IV in AES GCM mode */
276f03f0e8SSrujana Challa #define AES_GCM_IV_OFFSET 8
286f03f0e8SSrujana Challa #define CONTROL_WORD_LEN 8
296f03f0e8SSrujana Challa #define KEY2_OFFSET 48
306f03f0e8SSrujana Challa #define DMA_MODE_FLAG(dma_mode) \
316f03f0e8SSrujana Challa (((dma_mode) == OTX2_CPT_DMA_MODE_SG) ? (1 << 7) : 0)
326f03f0e8SSrujana Challa
336f03f0e8SSrujana Challa /* Truncated SHA digest size */
346f03f0e8SSrujana Challa #define SHA1_TRUNC_DIGEST_SIZE 12
356f03f0e8SSrujana Challa #define SHA256_TRUNC_DIGEST_SIZE 16
366f03f0e8SSrujana Challa #define SHA384_TRUNC_DIGEST_SIZE 24
376f03f0e8SSrujana Challa #define SHA512_TRUNC_DIGEST_SIZE 32
386f03f0e8SSrujana Challa
396f03f0e8SSrujana Challa static DEFINE_MUTEX(mutex);
406f03f0e8SSrujana Challa static int is_crypto_registered;
416f03f0e8SSrujana Challa
426f03f0e8SSrujana Challa struct cpt_device_desc {
436f03f0e8SSrujana Challa struct pci_dev *dev;
446f03f0e8SSrujana Challa int num_queues;
456f03f0e8SSrujana Challa };
466f03f0e8SSrujana Challa
476f03f0e8SSrujana Challa struct cpt_device_table {
486f03f0e8SSrujana Challa atomic_t count;
496f03f0e8SSrujana Challa struct cpt_device_desc desc[OTX2_CPT_MAX_LFS_NUM];
506f03f0e8SSrujana Challa };
516f03f0e8SSrujana Challa
526f03f0e8SSrujana Challa static struct cpt_device_table se_devices = {
536f03f0e8SSrujana Challa .count = ATOMIC_INIT(0)
546f03f0e8SSrujana Challa };
556f03f0e8SSrujana Challa
56*21ba7132SHerbert Xu static struct otx2_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg);
57*21ba7132SHerbert Xu
get_se_device(struct pci_dev ** pdev,int * cpu_num)586f03f0e8SSrujana Challa static inline int get_se_device(struct pci_dev **pdev, int *cpu_num)
596f03f0e8SSrujana Challa {
606f03f0e8SSrujana Challa int count;
616f03f0e8SSrujana Challa
626f03f0e8SSrujana Challa count = atomic_read(&se_devices.count);
636f03f0e8SSrujana Challa if (count < 1)
646f03f0e8SSrujana Challa return -ENODEV;
656f03f0e8SSrujana Challa
666f03f0e8SSrujana Challa *cpu_num = get_cpu();
676f03f0e8SSrujana Challa /*
686f03f0e8SSrujana Challa * On OcteonTX2 platform CPT instruction queue is bound to each
696f03f0e8SSrujana Challa * local function LF, in turn LFs can be attached to PF
706f03f0e8SSrujana Challa * or VF therefore we always use first device. We get maximum
716f03f0e8SSrujana Challa * performance if one CPT queue is available for each cpu
726f03f0e8SSrujana Challa * otherwise CPT queues need to be shared between cpus.
736f03f0e8SSrujana Challa */
746f03f0e8SSrujana Challa if (*cpu_num >= se_devices.desc[0].num_queues)
756f03f0e8SSrujana Challa *cpu_num %= se_devices.desc[0].num_queues;
766f03f0e8SSrujana Challa *pdev = se_devices.desc[0].dev;
776f03f0e8SSrujana Challa
786f03f0e8SSrujana Challa put_cpu();
796f03f0e8SSrujana Challa
806f03f0e8SSrujana Challa return 0;
816f03f0e8SSrujana Challa }
826f03f0e8SSrujana Challa
validate_hmac_cipher_null(struct otx2_cpt_req_info * cpt_req)836f03f0e8SSrujana Challa static inline int validate_hmac_cipher_null(struct otx2_cpt_req_info *cpt_req)
846f03f0e8SSrujana Challa {
856f03f0e8SSrujana Challa struct otx2_cpt_req_ctx *rctx;
866f03f0e8SSrujana Challa struct aead_request *req;
876f03f0e8SSrujana Challa struct crypto_aead *tfm;
886f03f0e8SSrujana Challa
896f03f0e8SSrujana Challa req = container_of(cpt_req->areq, struct aead_request, base);
906f03f0e8SSrujana Challa tfm = crypto_aead_reqtfm(req);
91d887dec1SHerbert Xu rctx = aead_request_ctx_dma(req);
926f03f0e8SSrujana Challa if (memcmp(rctx->fctx.hmac.s.hmac_calc,
936f03f0e8SSrujana Challa rctx->fctx.hmac.s.hmac_recv,
946f03f0e8SSrujana Challa crypto_aead_authsize(tfm)) != 0)
956f03f0e8SSrujana Challa return -EBADMSG;
966f03f0e8SSrujana Challa
976f03f0e8SSrujana Challa return 0;
986f03f0e8SSrujana Challa }
996f03f0e8SSrujana Challa
otx2_cpt_aead_callback(int status,void * arg1,void * arg2)1006f03f0e8SSrujana Challa static void otx2_cpt_aead_callback(int status, void *arg1, void *arg2)
1016f03f0e8SSrujana Challa {
1026f03f0e8SSrujana Challa struct otx2_cpt_inst_info *inst_info = arg2;
1036f03f0e8SSrujana Challa struct crypto_async_request *areq = arg1;
1046f03f0e8SSrujana Challa struct otx2_cpt_req_info *cpt_req;
1056f03f0e8SSrujana Challa struct pci_dev *pdev;
1066f03f0e8SSrujana Challa
1076f03f0e8SSrujana Challa if (inst_info) {
1086f03f0e8SSrujana Challa cpt_req = inst_info->req;
1096f03f0e8SSrujana Challa if (!status) {
1106f03f0e8SSrujana Challa /*
1116f03f0e8SSrujana Challa * When selected cipher is NULL we need to manually
1126f03f0e8SSrujana Challa * verify whether calculated hmac value matches
1136f03f0e8SSrujana Challa * received hmac value
1146f03f0e8SSrujana Challa */
1156f03f0e8SSrujana Challa if (cpt_req->req_type ==
1166f03f0e8SSrujana Challa OTX2_CPT_AEAD_ENC_DEC_NULL_REQ &&
1176f03f0e8SSrujana Challa !cpt_req->is_enc)
1186f03f0e8SSrujana Challa status = validate_hmac_cipher_null(cpt_req);
1196f03f0e8SSrujana Challa }
1206f03f0e8SSrujana Challa pdev = inst_info->pdev;
1216f03f0e8SSrujana Challa otx2_cpt_info_destroy(pdev, inst_info);
1226f03f0e8SSrujana Challa }
1236f03f0e8SSrujana Challa if (areq)
12425085ba5SHerbert Xu crypto_request_complete(areq, status);
1256f03f0e8SSrujana Challa }
1266f03f0e8SSrujana Challa
output_iv_copyback(struct crypto_async_request * areq)1276f03f0e8SSrujana Challa static void output_iv_copyback(struct crypto_async_request *areq)
1286f03f0e8SSrujana Challa {
1296f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info;
1306f03f0e8SSrujana Challa struct otx2_cpt_req_ctx *rctx;
1316f03f0e8SSrujana Challa struct skcipher_request *sreq;
1326f03f0e8SSrujana Challa struct crypto_skcipher *stfm;
1336f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx;
1346f03f0e8SSrujana Challa u32 start, ivsize;
1356f03f0e8SSrujana Challa
1366f03f0e8SSrujana Challa sreq = container_of(areq, struct skcipher_request, base);
1376f03f0e8SSrujana Challa stfm = crypto_skcipher_reqtfm(sreq);
1386f03f0e8SSrujana Challa ctx = crypto_skcipher_ctx(stfm);
1396f03f0e8SSrujana Challa if (ctx->cipher_type == OTX2_CPT_AES_CBC ||
1406f03f0e8SSrujana Challa ctx->cipher_type == OTX2_CPT_DES3_CBC) {
141d887dec1SHerbert Xu rctx = skcipher_request_ctx_dma(sreq);
1426f03f0e8SSrujana Challa req_info = &rctx->cpt_req;
1436f03f0e8SSrujana Challa ivsize = crypto_skcipher_ivsize(stfm);
1446f03f0e8SSrujana Challa start = sreq->cryptlen - ivsize;
1456f03f0e8SSrujana Challa
1466f03f0e8SSrujana Challa if (req_info->is_enc) {
1476f03f0e8SSrujana Challa scatterwalk_map_and_copy(sreq->iv, sreq->dst, start,
1486f03f0e8SSrujana Challa ivsize, 0);
1496f03f0e8SSrujana Challa } else {
1506f03f0e8SSrujana Challa if (sreq->src != sreq->dst) {
1516f03f0e8SSrujana Challa scatterwalk_map_and_copy(sreq->iv, sreq->src,
1526f03f0e8SSrujana Challa start, ivsize, 0);
1536f03f0e8SSrujana Challa } else {
1546f03f0e8SSrujana Challa memcpy(sreq->iv, req_info->iv_out, ivsize);
1556f03f0e8SSrujana Challa kfree(req_info->iv_out);
1566f03f0e8SSrujana Challa }
1576f03f0e8SSrujana Challa }
1586f03f0e8SSrujana Challa }
1596f03f0e8SSrujana Challa }
1606f03f0e8SSrujana Challa
otx2_cpt_skcipher_callback(int status,void * arg1,void * arg2)1616f03f0e8SSrujana Challa static void otx2_cpt_skcipher_callback(int status, void *arg1, void *arg2)
1626f03f0e8SSrujana Challa {
1636f03f0e8SSrujana Challa struct otx2_cpt_inst_info *inst_info = arg2;
1646f03f0e8SSrujana Challa struct crypto_async_request *areq = arg1;
1656f03f0e8SSrujana Challa struct pci_dev *pdev;
1666f03f0e8SSrujana Challa
1676f03f0e8SSrujana Challa if (areq) {
1686f03f0e8SSrujana Challa if (!status)
1696f03f0e8SSrujana Challa output_iv_copyback(areq);
1706f03f0e8SSrujana Challa if (inst_info) {
1716f03f0e8SSrujana Challa pdev = inst_info->pdev;
1726f03f0e8SSrujana Challa otx2_cpt_info_destroy(pdev, inst_info);
1736f03f0e8SSrujana Challa }
17425085ba5SHerbert Xu crypto_request_complete(areq, status);
1756f03f0e8SSrujana Challa }
1766f03f0e8SSrujana Challa }
1776f03f0e8SSrujana Challa
update_input_data(struct otx2_cpt_req_info * req_info,struct scatterlist * inp_sg,u32 nbytes,u32 * argcnt)1786f03f0e8SSrujana Challa static inline void update_input_data(struct otx2_cpt_req_info *req_info,
1796f03f0e8SSrujana Challa struct scatterlist *inp_sg,
1806f03f0e8SSrujana Challa u32 nbytes, u32 *argcnt)
1816f03f0e8SSrujana Challa {
1826f03f0e8SSrujana Challa req_info->req.dlen += nbytes;
1836f03f0e8SSrujana Challa
1846f03f0e8SSrujana Challa while (nbytes) {
1856f03f0e8SSrujana Challa u32 len = (nbytes < inp_sg->length) ? nbytes : inp_sg->length;
1866f03f0e8SSrujana Challa u8 *ptr = sg_virt(inp_sg);
1876f03f0e8SSrujana Challa
1886f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = (void *)ptr;
1896f03f0e8SSrujana Challa req_info->in[*argcnt].size = len;
1906f03f0e8SSrujana Challa nbytes -= len;
1916f03f0e8SSrujana Challa ++(*argcnt);
1926f03f0e8SSrujana Challa inp_sg = sg_next(inp_sg);
1936f03f0e8SSrujana Challa }
1946f03f0e8SSrujana Challa }
1956f03f0e8SSrujana Challa
update_output_data(struct otx2_cpt_req_info * req_info,struct scatterlist * outp_sg,u32 offset,u32 nbytes,u32 * argcnt)1966f03f0e8SSrujana Challa static inline void update_output_data(struct otx2_cpt_req_info *req_info,
1976f03f0e8SSrujana Challa struct scatterlist *outp_sg,
1986f03f0e8SSrujana Challa u32 offset, u32 nbytes, u32 *argcnt)
1996f03f0e8SSrujana Challa {
2006f03f0e8SSrujana Challa u32 len, sg_len;
2016f03f0e8SSrujana Challa u8 *ptr;
2026f03f0e8SSrujana Challa
2036f03f0e8SSrujana Challa req_info->rlen += nbytes;
2046f03f0e8SSrujana Challa
2056f03f0e8SSrujana Challa while (nbytes) {
2066f03f0e8SSrujana Challa sg_len = outp_sg->length - offset;
2076f03f0e8SSrujana Challa len = (nbytes < sg_len) ? nbytes : sg_len;
2086f03f0e8SSrujana Challa ptr = sg_virt(outp_sg);
2096f03f0e8SSrujana Challa
2106f03f0e8SSrujana Challa req_info->out[*argcnt].vptr = (void *) (ptr + offset);
2116f03f0e8SSrujana Challa req_info->out[*argcnt].size = len;
2126f03f0e8SSrujana Challa nbytes -= len;
2136f03f0e8SSrujana Challa ++(*argcnt);
2146f03f0e8SSrujana Challa offset = 0;
2156f03f0e8SSrujana Challa outp_sg = sg_next(outp_sg);
2166f03f0e8SSrujana Challa }
2176f03f0e8SSrujana Challa }
2186f03f0e8SSrujana Challa
create_ctx_hdr(struct skcipher_request * req,u32 enc,u32 * argcnt)2196f03f0e8SSrujana Challa static inline int create_ctx_hdr(struct skcipher_request *req, u32 enc,
2206f03f0e8SSrujana Challa u32 *argcnt)
2216f03f0e8SSrujana Challa {
2226f03f0e8SSrujana Challa struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req);
223d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);
2246f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(stfm);
2256f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
2266f03f0e8SSrujana Challa struct otx2_cpt_fc_ctx *fctx = &rctx->fctx;
2276f03f0e8SSrujana Challa int ivsize = crypto_skcipher_ivsize(stfm);
2286f03f0e8SSrujana Challa u32 start = req->cryptlen - ivsize;
2296f03f0e8SSrujana Challa gfp_t flags;
2306f03f0e8SSrujana Challa
2316f03f0e8SSrujana Challa flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
2326f03f0e8SSrujana Challa GFP_KERNEL : GFP_ATOMIC;
2336f03f0e8SSrujana Challa req_info->ctrl.s.dma_mode = OTX2_CPT_DMA_MODE_SG;
2346f03f0e8SSrujana Challa req_info->ctrl.s.se_req = 1;
2356f03f0e8SSrujana Challa
2366f03f0e8SSrujana Challa req_info->req.opcode.s.major = OTX2_CPT_MAJOR_OP_FC |
2376f03f0e8SSrujana Challa DMA_MODE_FLAG(OTX2_CPT_DMA_MODE_SG);
2386f03f0e8SSrujana Challa if (enc) {
2396f03f0e8SSrujana Challa req_info->req.opcode.s.minor = 2;
2406f03f0e8SSrujana Challa } else {
2416f03f0e8SSrujana Challa req_info->req.opcode.s.minor = 3;
2426f03f0e8SSrujana Challa if ((ctx->cipher_type == OTX2_CPT_AES_CBC ||
2436f03f0e8SSrujana Challa ctx->cipher_type == OTX2_CPT_DES3_CBC) &&
2446f03f0e8SSrujana Challa req->src == req->dst) {
2456f03f0e8SSrujana Challa req_info->iv_out = kmalloc(ivsize, flags);
2466f03f0e8SSrujana Challa if (!req_info->iv_out)
2476f03f0e8SSrujana Challa return -ENOMEM;
2486f03f0e8SSrujana Challa
2496f03f0e8SSrujana Challa scatterwalk_map_and_copy(req_info->iv_out, req->src,
2506f03f0e8SSrujana Challa start, ivsize, 0);
2516f03f0e8SSrujana Challa }
2526f03f0e8SSrujana Challa }
2536f03f0e8SSrujana Challa /* Encryption data length */
2546f03f0e8SSrujana Challa req_info->req.param1 = req->cryptlen;
2556f03f0e8SSrujana Challa /* Authentication data length */
2566f03f0e8SSrujana Challa req_info->req.param2 = 0;
2576f03f0e8SSrujana Challa
2586f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;
2596f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;
2606f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.iv_source = OTX2_CPT_FROM_CPTR;
2616f03f0e8SSrujana Challa
2626f03f0e8SSrujana Challa if (ctx->cipher_type == OTX2_CPT_AES_XTS)
2636f03f0e8SSrujana Challa memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);
2646f03f0e8SSrujana Challa else
2656f03f0e8SSrujana Challa memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);
2666f03f0e8SSrujana Challa
2676f03f0e8SSrujana Challa memcpy(fctx->enc.encr_iv, req->iv, crypto_skcipher_ivsize(stfm));
2686f03f0e8SSrujana Challa
2696f03f0e8SSrujana Challa cpu_to_be64s(&fctx->enc.enc_ctrl.u);
2706f03f0e8SSrujana Challa
2716f03f0e8SSrujana Challa /*
2726f03f0e8SSrujana Challa * Storing Packet Data Information in offset
2736f03f0e8SSrujana Challa * Control Word First 8 bytes
2746f03f0e8SSrujana Challa */
2756f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word;
2766f03f0e8SSrujana Challa req_info->in[*argcnt].size = CONTROL_WORD_LEN;
2776f03f0e8SSrujana Challa req_info->req.dlen += CONTROL_WORD_LEN;
2786f03f0e8SSrujana Challa ++(*argcnt);
2796f03f0e8SSrujana Challa
2806f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = (u8 *)fctx;
2816f03f0e8SSrujana Challa req_info->in[*argcnt].size = sizeof(struct otx2_cpt_fc_ctx);
2826f03f0e8SSrujana Challa req_info->req.dlen += sizeof(struct otx2_cpt_fc_ctx);
2836f03f0e8SSrujana Challa
2846f03f0e8SSrujana Challa ++(*argcnt);
2856f03f0e8SSrujana Challa
2866f03f0e8SSrujana Challa return 0;
2876f03f0e8SSrujana Challa }
2886f03f0e8SSrujana Challa
create_input_list(struct skcipher_request * req,u32 enc,u32 enc_iv_len)2896f03f0e8SSrujana Challa static inline int create_input_list(struct skcipher_request *req, u32 enc,
2906f03f0e8SSrujana Challa u32 enc_iv_len)
2916f03f0e8SSrujana Challa {
292d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);
2936f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
2946f03f0e8SSrujana Challa u32 argcnt = 0;
2956f03f0e8SSrujana Challa int ret;
2966f03f0e8SSrujana Challa
2976f03f0e8SSrujana Challa ret = create_ctx_hdr(req, enc, &argcnt);
2986f03f0e8SSrujana Challa if (ret)
2996f03f0e8SSrujana Challa return ret;
3006f03f0e8SSrujana Challa
3016f03f0e8SSrujana Challa update_input_data(req_info, req->src, req->cryptlen, &argcnt);
3026f03f0e8SSrujana Challa req_info->in_cnt = argcnt;
3036f03f0e8SSrujana Challa
3046f03f0e8SSrujana Challa return 0;
3056f03f0e8SSrujana Challa }
3066f03f0e8SSrujana Challa
create_output_list(struct skcipher_request * req,u32 enc_iv_len)3076f03f0e8SSrujana Challa static inline void create_output_list(struct skcipher_request *req,
3086f03f0e8SSrujana Challa u32 enc_iv_len)
3096f03f0e8SSrujana Challa {
310d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);
3116f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
3126f03f0e8SSrujana Challa u32 argcnt = 0;
3136f03f0e8SSrujana Challa
3146f03f0e8SSrujana Challa /*
3156f03f0e8SSrujana Challa * OUTPUT Buffer Processing
3166f03f0e8SSrujana Challa * AES encryption/decryption output would be
3176f03f0e8SSrujana Challa * received in the following format
3186f03f0e8SSrujana Challa *
3196f03f0e8SSrujana Challa * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
3206f03f0e8SSrujana Challa * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]
3216f03f0e8SSrujana Challa */
3226f03f0e8SSrujana Challa update_output_data(req_info, req->dst, 0, req->cryptlen, &argcnt);
3236f03f0e8SSrujana Challa req_info->out_cnt = argcnt;
3246f03f0e8SSrujana Challa }
3256f03f0e8SSrujana Challa
skcipher_do_fallback(struct skcipher_request * req,bool is_enc)3266f03f0e8SSrujana Challa static int skcipher_do_fallback(struct skcipher_request *req, bool is_enc)
3276f03f0e8SSrujana Challa {
3286f03f0e8SSrujana Challa struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req);
329d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);
3306f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(stfm);
3316f03f0e8SSrujana Challa int ret;
3326f03f0e8SSrujana Challa
3336f03f0e8SSrujana Challa if (ctx->fbk_cipher) {
3346f03f0e8SSrujana Challa skcipher_request_set_tfm(&rctx->sk_fbk_req, ctx->fbk_cipher);
3356f03f0e8SSrujana Challa skcipher_request_set_callback(&rctx->sk_fbk_req,
3366f03f0e8SSrujana Challa req->base.flags,
3376f03f0e8SSrujana Challa req->base.complete,
3386f03f0e8SSrujana Challa req->base.data);
3396f03f0e8SSrujana Challa skcipher_request_set_crypt(&rctx->sk_fbk_req, req->src,
3406f03f0e8SSrujana Challa req->dst, req->cryptlen, req->iv);
3416f03f0e8SSrujana Challa ret = is_enc ? crypto_skcipher_encrypt(&rctx->sk_fbk_req) :
3426f03f0e8SSrujana Challa crypto_skcipher_decrypt(&rctx->sk_fbk_req);
3436f03f0e8SSrujana Challa } else {
3446f03f0e8SSrujana Challa ret = -EINVAL;
3456f03f0e8SSrujana Challa }
3466f03f0e8SSrujana Challa return ret;
3476f03f0e8SSrujana Challa }
3486f03f0e8SSrujana Challa
cpt_enc_dec(struct skcipher_request * req,u32 enc)3496f03f0e8SSrujana Challa static inline int cpt_enc_dec(struct skcipher_request *req, u32 enc)
3506f03f0e8SSrujana Challa {
3516f03f0e8SSrujana Challa struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req);
352d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);
3536f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(stfm);
3546f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
3556f03f0e8SSrujana Challa u32 enc_iv_len = crypto_skcipher_ivsize(stfm);
3566f03f0e8SSrujana Challa struct pci_dev *pdev;
3576f03f0e8SSrujana Challa int status, cpu_num;
3586f03f0e8SSrujana Challa
3596f03f0e8SSrujana Challa if (req->cryptlen == 0)
3606f03f0e8SSrujana Challa return 0;
3616f03f0e8SSrujana Challa
3626f03f0e8SSrujana Challa if (!IS_ALIGNED(req->cryptlen, ctx->enc_align_len))
3636f03f0e8SSrujana Challa return -EINVAL;
3646f03f0e8SSrujana Challa
3656f03f0e8SSrujana Challa if (req->cryptlen > OTX2_CPT_MAX_REQ_SIZE)
3666f03f0e8SSrujana Challa return skcipher_do_fallback(req, enc);
3676f03f0e8SSrujana Challa
3686f03f0e8SSrujana Challa /* Clear control words */
3696f03f0e8SSrujana Challa rctx->ctrl_word.flags = 0;
3706f03f0e8SSrujana Challa rctx->fctx.enc.enc_ctrl.u = 0;
3716f03f0e8SSrujana Challa
3726f03f0e8SSrujana Challa status = create_input_list(req, enc, enc_iv_len);
3736f03f0e8SSrujana Challa if (status)
3746f03f0e8SSrujana Challa return status;
3756f03f0e8SSrujana Challa create_output_list(req, enc_iv_len);
3766f03f0e8SSrujana Challa
3776f03f0e8SSrujana Challa status = get_se_device(&pdev, &cpu_num);
3786f03f0e8SSrujana Challa if (status)
3796f03f0e8SSrujana Challa return status;
3806f03f0e8SSrujana Challa
3816f03f0e8SSrujana Challa req_info->callback = otx2_cpt_skcipher_callback;
3826f03f0e8SSrujana Challa req_info->areq = &req->base;
3836f03f0e8SSrujana Challa req_info->req_type = OTX2_CPT_ENC_DEC_REQ;
3846f03f0e8SSrujana Challa req_info->is_enc = enc;
3856f03f0e8SSrujana Challa req_info->is_trunc_hmac = false;
3866f03f0e8SSrujana Challa req_info->ctrl.s.grp = otx2_cpt_get_kcrypto_eng_grp_num(pdev);
3876f03f0e8SSrujana Challa
3886f03f0e8SSrujana Challa /*
3896f03f0e8SSrujana Challa * We perform an asynchronous send and once
3906f03f0e8SSrujana Challa * the request is completed the driver would
3916f03f0e8SSrujana Challa * intimate through registered call back functions
3926f03f0e8SSrujana Challa */
3936f03f0e8SSrujana Challa status = otx2_cpt_do_request(pdev, req_info, cpu_num);
3946f03f0e8SSrujana Challa
3956f03f0e8SSrujana Challa return status;
3966f03f0e8SSrujana Challa }
3976f03f0e8SSrujana Challa
otx2_cpt_skcipher_encrypt(struct skcipher_request * req)3986f03f0e8SSrujana Challa static int otx2_cpt_skcipher_encrypt(struct skcipher_request *req)
3996f03f0e8SSrujana Challa {
4006f03f0e8SSrujana Challa return cpt_enc_dec(req, true);
4016f03f0e8SSrujana Challa }
4026f03f0e8SSrujana Challa
otx2_cpt_skcipher_decrypt(struct skcipher_request * req)4036f03f0e8SSrujana Challa static int otx2_cpt_skcipher_decrypt(struct skcipher_request *req)
4046f03f0e8SSrujana Challa {
4056f03f0e8SSrujana Challa return cpt_enc_dec(req, false);
4066f03f0e8SSrujana Challa }
4076f03f0e8SSrujana Challa
otx2_cpt_skcipher_xts_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen)4086f03f0e8SSrujana Challa static int otx2_cpt_skcipher_xts_setkey(struct crypto_skcipher *tfm,
4096f03f0e8SSrujana Challa const u8 *key, u32 keylen)
4106f03f0e8SSrujana Challa {
4116f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
4126f03f0e8SSrujana Challa const u8 *key2 = key + (keylen / 2);
4136f03f0e8SSrujana Challa const u8 *key1 = key;
4146f03f0e8SSrujana Challa int ret;
4156f03f0e8SSrujana Challa
4160ee43367SVladis Dronov ret = xts_verify_key(tfm, key, keylen);
4176f03f0e8SSrujana Challa if (ret)
4186f03f0e8SSrujana Challa return ret;
4196f03f0e8SSrujana Challa ctx->key_len = keylen;
4206f03f0e8SSrujana Challa ctx->enc_align_len = 1;
4216f03f0e8SSrujana Challa memcpy(ctx->enc_key, key1, keylen / 2);
4226f03f0e8SSrujana Challa memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
4236f03f0e8SSrujana Challa ctx->cipher_type = OTX2_CPT_AES_XTS;
4246f03f0e8SSrujana Challa switch (ctx->key_len) {
4256f03f0e8SSrujana Challa case 2 * AES_KEYSIZE_128:
4266f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_128_BIT;
4276f03f0e8SSrujana Challa break;
4286f03f0e8SSrujana Challa case 2 * AES_KEYSIZE_192:
4296f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_192_BIT;
4306f03f0e8SSrujana Challa break;
4316f03f0e8SSrujana Challa case 2 * AES_KEYSIZE_256:
4326f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_256_BIT;
4336f03f0e8SSrujana Challa break;
4346f03f0e8SSrujana Challa default:
4356f03f0e8SSrujana Challa return -EINVAL;
4366f03f0e8SSrujana Challa }
4376f03f0e8SSrujana Challa return crypto_skcipher_setkey(ctx->fbk_cipher, key, keylen);
4386f03f0e8SSrujana Challa }
4396f03f0e8SSrujana Challa
cpt_des_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen,u8 cipher_type)4406f03f0e8SSrujana Challa static int cpt_des_setkey(struct crypto_skcipher *tfm, const u8 *key,
4416f03f0e8SSrujana Challa u32 keylen, u8 cipher_type)
4426f03f0e8SSrujana Challa {
4436f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
4446f03f0e8SSrujana Challa
4456f03f0e8SSrujana Challa if (keylen != DES3_EDE_KEY_SIZE)
4466f03f0e8SSrujana Challa return -EINVAL;
4476f03f0e8SSrujana Challa
4486f03f0e8SSrujana Challa ctx->key_len = keylen;
4496f03f0e8SSrujana Challa ctx->cipher_type = cipher_type;
4506f03f0e8SSrujana Challa ctx->enc_align_len = 8;
4516f03f0e8SSrujana Challa
4526f03f0e8SSrujana Challa memcpy(ctx->enc_key, key, keylen);
4536f03f0e8SSrujana Challa
4546f03f0e8SSrujana Challa return crypto_skcipher_setkey(ctx->fbk_cipher, key, keylen);
4556f03f0e8SSrujana Challa }
4566f03f0e8SSrujana Challa
cpt_aes_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen,u8 cipher_type)4576f03f0e8SSrujana Challa static int cpt_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
4586f03f0e8SSrujana Challa u32 keylen, u8 cipher_type)
4596f03f0e8SSrujana Challa {
4606f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
4616f03f0e8SSrujana Challa
4626f03f0e8SSrujana Challa switch (keylen) {
4636f03f0e8SSrujana Challa case AES_KEYSIZE_128:
4646f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_128_BIT;
4656f03f0e8SSrujana Challa break;
4666f03f0e8SSrujana Challa case AES_KEYSIZE_192:
4676f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_192_BIT;
4686f03f0e8SSrujana Challa break;
4696f03f0e8SSrujana Challa case AES_KEYSIZE_256:
4706f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_256_BIT;
4716f03f0e8SSrujana Challa break;
4726f03f0e8SSrujana Challa default:
4736f03f0e8SSrujana Challa return -EINVAL;
4746f03f0e8SSrujana Challa }
4756f03f0e8SSrujana Challa if (cipher_type == OTX2_CPT_AES_CBC || cipher_type == OTX2_CPT_AES_ECB)
4766f03f0e8SSrujana Challa ctx->enc_align_len = 16;
4776f03f0e8SSrujana Challa else
4786f03f0e8SSrujana Challa ctx->enc_align_len = 1;
4796f03f0e8SSrujana Challa
4806f03f0e8SSrujana Challa ctx->key_len = keylen;
4816f03f0e8SSrujana Challa ctx->cipher_type = cipher_type;
4826f03f0e8SSrujana Challa
4836f03f0e8SSrujana Challa memcpy(ctx->enc_key, key, keylen);
4846f03f0e8SSrujana Challa
4856f03f0e8SSrujana Challa return crypto_skcipher_setkey(ctx->fbk_cipher, key, keylen);
4866f03f0e8SSrujana Challa }
4876f03f0e8SSrujana Challa
otx2_cpt_skcipher_cbc_aes_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen)4886f03f0e8SSrujana Challa static int otx2_cpt_skcipher_cbc_aes_setkey(struct crypto_skcipher *tfm,
4896f03f0e8SSrujana Challa const u8 *key, u32 keylen)
4906f03f0e8SSrujana Challa {
4916f03f0e8SSrujana Challa return cpt_aes_setkey(tfm, key, keylen, OTX2_CPT_AES_CBC);
4926f03f0e8SSrujana Challa }
4936f03f0e8SSrujana Challa
otx2_cpt_skcipher_ecb_aes_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen)4946f03f0e8SSrujana Challa static int otx2_cpt_skcipher_ecb_aes_setkey(struct crypto_skcipher *tfm,
4956f03f0e8SSrujana Challa const u8 *key, u32 keylen)
4966f03f0e8SSrujana Challa {
4976f03f0e8SSrujana Challa return cpt_aes_setkey(tfm, key, keylen, OTX2_CPT_AES_ECB);
4986f03f0e8SSrujana Challa }
4996f03f0e8SSrujana Challa
otx2_cpt_skcipher_cbc_des3_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen)5006f03f0e8SSrujana Challa static int otx2_cpt_skcipher_cbc_des3_setkey(struct crypto_skcipher *tfm,
5016f03f0e8SSrujana Challa const u8 *key, u32 keylen)
5026f03f0e8SSrujana Challa {
5036f03f0e8SSrujana Challa return cpt_des_setkey(tfm, key, keylen, OTX2_CPT_DES3_CBC);
5046f03f0e8SSrujana Challa }
5056f03f0e8SSrujana Challa
otx2_cpt_skcipher_ecb_des3_setkey(struct crypto_skcipher * tfm,const u8 * key,u32 keylen)5066f03f0e8SSrujana Challa static int otx2_cpt_skcipher_ecb_des3_setkey(struct crypto_skcipher *tfm,
5076f03f0e8SSrujana Challa const u8 *key, u32 keylen)
5086f03f0e8SSrujana Challa {
5096f03f0e8SSrujana Challa return cpt_des_setkey(tfm, key, keylen, OTX2_CPT_DES3_ECB);
5106f03f0e8SSrujana Challa }
5116f03f0e8SSrujana Challa
cpt_skcipher_fallback_init(struct otx2_cpt_enc_ctx * ctx,struct crypto_alg * alg)5126f03f0e8SSrujana Challa static int cpt_skcipher_fallback_init(struct otx2_cpt_enc_ctx *ctx,
5136f03f0e8SSrujana Challa struct crypto_alg *alg)
5146f03f0e8SSrujana Challa {
5156f03f0e8SSrujana Challa if (alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) {
5166f03f0e8SSrujana Challa ctx->fbk_cipher =
5176f03f0e8SSrujana Challa crypto_alloc_skcipher(alg->cra_name, 0,
5186f03f0e8SSrujana Challa CRYPTO_ALG_ASYNC |
5196f03f0e8SSrujana Challa CRYPTO_ALG_NEED_FALLBACK);
5206f03f0e8SSrujana Challa if (IS_ERR(ctx->fbk_cipher)) {
5216f03f0e8SSrujana Challa pr_err("%s() failed to allocate fallback for %s\n",
5226f03f0e8SSrujana Challa __func__, alg->cra_name);
5236f03f0e8SSrujana Challa return PTR_ERR(ctx->fbk_cipher);
5246f03f0e8SSrujana Challa }
5256f03f0e8SSrujana Challa }
5266f03f0e8SSrujana Challa return 0;
5276f03f0e8SSrujana Challa }
5286f03f0e8SSrujana Challa
otx2_cpt_enc_dec_init(struct crypto_skcipher * stfm)5296f03f0e8SSrujana Challa static int otx2_cpt_enc_dec_init(struct crypto_skcipher *stfm)
5306f03f0e8SSrujana Challa {
5316f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(stfm);
5326f03f0e8SSrujana Challa struct crypto_tfm *tfm = crypto_skcipher_tfm(stfm);
5336f03f0e8SSrujana Challa struct crypto_alg *alg = tfm->__crt_alg;
5346f03f0e8SSrujana Challa
5356f03f0e8SSrujana Challa memset(ctx, 0, sizeof(*ctx));
5366f03f0e8SSrujana Challa /*
5376f03f0e8SSrujana Challa * Additional memory for skcipher_request is
5386f03f0e8SSrujana Challa * allocated since the cryptd daemon uses
5396f03f0e8SSrujana Challa * this memory for request_ctx information
5406f03f0e8SSrujana Challa */
541d887dec1SHerbert Xu crypto_skcipher_set_reqsize_dma(
542d887dec1SHerbert Xu stfm, sizeof(struct otx2_cpt_req_ctx) +
5436f03f0e8SSrujana Challa sizeof(struct skcipher_request));
5446f03f0e8SSrujana Challa
5456f03f0e8SSrujana Challa return cpt_skcipher_fallback_init(ctx, alg);
5466f03f0e8SSrujana Challa }
5476f03f0e8SSrujana Challa
otx2_cpt_skcipher_exit(struct crypto_skcipher * tfm)5486f03f0e8SSrujana Challa static void otx2_cpt_skcipher_exit(struct crypto_skcipher *tfm)
5496f03f0e8SSrujana Challa {
5506f03f0e8SSrujana Challa struct otx2_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);
5516f03f0e8SSrujana Challa
5526f03f0e8SSrujana Challa if (ctx->fbk_cipher) {
5536f03f0e8SSrujana Challa crypto_free_skcipher(ctx->fbk_cipher);
5546f03f0e8SSrujana Challa ctx->fbk_cipher = NULL;
5556f03f0e8SSrujana Challa }
5566f03f0e8SSrujana Challa }
5576f03f0e8SSrujana Challa
cpt_aead_fallback_init(struct otx2_cpt_aead_ctx * ctx,struct crypto_alg * alg)5586f03f0e8SSrujana Challa static int cpt_aead_fallback_init(struct otx2_cpt_aead_ctx *ctx,
5596f03f0e8SSrujana Challa struct crypto_alg *alg)
5606f03f0e8SSrujana Challa {
5616f03f0e8SSrujana Challa if (alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) {
5626f03f0e8SSrujana Challa ctx->fbk_cipher =
5636f03f0e8SSrujana Challa crypto_alloc_aead(alg->cra_name, 0,
5646f03f0e8SSrujana Challa CRYPTO_ALG_ASYNC |
5656f03f0e8SSrujana Challa CRYPTO_ALG_NEED_FALLBACK);
5666f03f0e8SSrujana Challa if (IS_ERR(ctx->fbk_cipher)) {
5676f03f0e8SSrujana Challa pr_err("%s() failed to allocate fallback for %s\n",
5686f03f0e8SSrujana Challa __func__, alg->cra_name);
5696f03f0e8SSrujana Challa return PTR_ERR(ctx->fbk_cipher);
5706f03f0e8SSrujana Challa }
5716f03f0e8SSrujana Challa }
5726f03f0e8SSrujana Challa return 0;
5736f03f0e8SSrujana Challa }
5746f03f0e8SSrujana Challa
cpt_aead_init(struct crypto_aead * atfm,u8 cipher_type,u8 mac_type)5756f03f0e8SSrujana Challa static int cpt_aead_init(struct crypto_aead *atfm, u8 cipher_type, u8 mac_type)
5766f03f0e8SSrujana Challa {
577d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(atfm);
5786f03f0e8SSrujana Challa struct crypto_tfm *tfm = crypto_aead_tfm(atfm);
5796f03f0e8SSrujana Challa struct crypto_alg *alg = tfm->__crt_alg;
5806f03f0e8SSrujana Challa
5816f03f0e8SSrujana Challa ctx->cipher_type = cipher_type;
5826f03f0e8SSrujana Challa ctx->mac_type = mac_type;
5836f03f0e8SSrujana Challa
584*21ba7132SHerbert Xu switch (ctx->mac_type) {
585*21ba7132SHerbert Xu case OTX2_CPT_SHA1:
586*21ba7132SHerbert Xu ctx->hashalg = crypto_alloc_shash("sha1", 0, 0);
587*21ba7132SHerbert Xu break;
588*21ba7132SHerbert Xu
589*21ba7132SHerbert Xu case OTX2_CPT_SHA256:
590*21ba7132SHerbert Xu ctx->hashalg = crypto_alloc_shash("sha256", 0, 0);
591*21ba7132SHerbert Xu break;
592*21ba7132SHerbert Xu
593*21ba7132SHerbert Xu case OTX2_CPT_SHA384:
594*21ba7132SHerbert Xu ctx->hashalg = crypto_alloc_shash("sha384", 0, 0);
595*21ba7132SHerbert Xu break;
596*21ba7132SHerbert Xu
597*21ba7132SHerbert Xu case OTX2_CPT_SHA512:
598*21ba7132SHerbert Xu ctx->hashalg = crypto_alloc_shash("sha512", 0, 0);
599*21ba7132SHerbert Xu break;
600*21ba7132SHerbert Xu }
601*21ba7132SHerbert Xu
602*21ba7132SHerbert Xu if (IS_ERR(ctx->hashalg))
603*21ba7132SHerbert Xu return PTR_ERR(ctx->hashalg);
604*21ba7132SHerbert Xu
605*21ba7132SHerbert Xu if (ctx->hashalg) {
606*21ba7132SHerbert Xu ctx->sdesc = alloc_sdesc(ctx->hashalg);
607*21ba7132SHerbert Xu if (!ctx->sdesc) {
608*21ba7132SHerbert Xu crypto_free_shash(ctx->hashalg);
609*21ba7132SHerbert Xu return -ENOMEM;
610*21ba7132SHerbert Xu }
611*21ba7132SHerbert Xu }
612*21ba7132SHerbert Xu
6136f03f0e8SSrujana Challa /*
6146f03f0e8SSrujana Challa * When selected cipher is NULL we use HMAC opcode instead of
6156f03f0e8SSrujana Challa * FLEXICRYPTO opcode therefore we don't need to use HASH algorithms
6166f03f0e8SSrujana Challa * for calculating ipad and opad
6176f03f0e8SSrujana Challa */
618*21ba7132SHerbert Xu if (ctx->cipher_type != OTX2_CPT_CIPHER_NULL && ctx->hashalg) {
619*21ba7132SHerbert Xu int ss = crypto_shash_statesize(ctx->hashalg);
6206f03f0e8SSrujana Challa
621*21ba7132SHerbert Xu ctx->ipad = kzalloc(ss, GFP_KERNEL);
622*21ba7132SHerbert Xu if (!ctx->ipad) {
623*21ba7132SHerbert Xu kfree(ctx->sdesc);
624*21ba7132SHerbert Xu crypto_free_shash(ctx->hashalg);
625*21ba7132SHerbert Xu return -ENOMEM;
626*21ba7132SHerbert Xu }
6276f03f0e8SSrujana Challa
628*21ba7132SHerbert Xu ctx->opad = kzalloc(ss, GFP_KERNEL);
629*21ba7132SHerbert Xu if (!ctx->opad) {
630*21ba7132SHerbert Xu kfree(ctx->ipad);
631*21ba7132SHerbert Xu kfree(ctx->sdesc);
632*21ba7132SHerbert Xu crypto_free_shash(ctx->hashalg);
633*21ba7132SHerbert Xu return -ENOMEM;
6346f03f0e8SSrujana Challa }
6356f03f0e8SSrujana Challa }
6366f03f0e8SSrujana Challa switch (ctx->cipher_type) {
6376f03f0e8SSrujana Challa case OTX2_CPT_AES_CBC:
6386f03f0e8SSrujana Challa case OTX2_CPT_AES_ECB:
6396f03f0e8SSrujana Challa ctx->enc_align_len = 16;
6406f03f0e8SSrujana Challa break;
6416f03f0e8SSrujana Challa case OTX2_CPT_DES3_CBC:
6426f03f0e8SSrujana Challa case OTX2_CPT_DES3_ECB:
6436f03f0e8SSrujana Challa ctx->enc_align_len = 8;
6446f03f0e8SSrujana Challa break;
6456f03f0e8SSrujana Challa case OTX2_CPT_AES_GCM:
6466f03f0e8SSrujana Challa case OTX2_CPT_CIPHER_NULL:
6476f03f0e8SSrujana Challa ctx->enc_align_len = 1;
6486f03f0e8SSrujana Challa break;
6496f03f0e8SSrujana Challa }
650d887dec1SHerbert Xu crypto_aead_set_reqsize_dma(atfm, sizeof(struct otx2_cpt_req_ctx));
6516f03f0e8SSrujana Challa
6526f03f0e8SSrujana Challa return cpt_aead_fallback_init(ctx, alg);
6536f03f0e8SSrujana Challa }
6546f03f0e8SSrujana Challa
otx2_cpt_aead_cbc_aes_sha1_init(struct crypto_aead * tfm)6556f03f0e8SSrujana Challa static int otx2_cpt_aead_cbc_aes_sha1_init(struct crypto_aead *tfm)
6566f03f0e8SSrujana Challa {
6576f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_AES_CBC, OTX2_CPT_SHA1);
6586f03f0e8SSrujana Challa }
6596f03f0e8SSrujana Challa
otx2_cpt_aead_cbc_aes_sha256_init(struct crypto_aead * tfm)6606f03f0e8SSrujana Challa static int otx2_cpt_aead_cbc_aes_sha256_init(struct crypto_aead *tfm)
6616f03f0e8SSrujana Challa {
6626f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_AES_CBC, OTX2_CPT_SHA256);
6636f03f0e8SSrujana Challa }
6646f03f0e8SSrujana Challa
otx2_cpt_aead_cbc_aes_sha384_init(struct crypto_aead * tfm)6656f03f0e8SSrujana Challa static int otx2_cpt_aead_cbc_aes_sha384_init(struct crypto_aead *tfm)
6666f03f0e8SSrujana Challa {
6676f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_AES_CBC, OTX2_CPT_SHA384);
6686f03f0e8SSrujana Challa }
6696f03f0e8SSrujana Challa
otx2_cpt_aead_cbc_aes_sha512_init(struct crypto_aead * tfm)6706f03f0e8SSrujana Challa static int otx2_cpt_aead_cbc_aes_sha512_init(struct crypto_aead *tfm)
6716f03f0e8SSrujana Challa {
6726f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_AES_CBC, OTX2_CPT_SHA512);
6736f03f0e8SSrujana Challa }
6746f03f0e8SSrujana Challa
otx2_cpt_aead_ecb_null_sha1_init(struct crypto_aead * tfm)6756f03f0e8SSrujana Challa static int otx2_cpt_aead_ecb_null_sha1_init(struct crypto_aead *tfm)
6766f03f0e8SSrujana Challa {
6776f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_CIPHER_NULL, OTX2_CPT_SHA1);
6786f03f0e8SSrujana Challa }
6796f03f0e8SSrujana Challa
otx2_cpt_aead_ecb_null_sha256_init(struct crypto_aead * tfm)6806f03f0e8SSrujana Challa static int otx2_cpt_aead_ecb_null_sha256_init(struct crypto_aead *tfm)
6816f03f0e8SSrujana Challa {
6826f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_CIPHER_NULL, OTX2_CPT_SHA256);
6836f03f0e8SSrujana Challa }
6846f03f0e8SSrujana Challa
otx2_cpt_aead_ecb_null_sha384_init(struct crypto_aead * tfm)6856f03f0e8SSrujana Challa static int otx2_cpt_aead_ecb_null_sha384_init(struct crypto_aead *tfm)
6866f03f0e8SSrujana Challa {
6876f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_CIPHER_NULL, OTX2_CPT_SHA384);
6886f03f0e8SSrujana Challa }
6896f03f0e8SSrujana Challa
otx2_cpt_aead_ecb_null_sha512_init(struct crypto_aead * tfm)6906f03f0e8SSrujana Challa static int otx2_cpt_aead_ecb_null_sha512_init(struct crypto_aead *tfm)
6916f03f0e8SSrujana Challa {
6926f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_CIPHER_NULL, OTX2_CPT_SHA512);
6936f03f0e8SSrujana Challa }
6946f03f0e8SSrujana Challa
otx2_cpt_aead_gcm_aes_init(struct crypto_aead * tfm)6956f03f0e8SSrujana Challa static int otx2_cpt_aead_gcm_aes_init(struct crypto_aead *tfm)
6966f03f0e8SSrujana Challa {
6976f03f0e8SSrujana Challa return cpt_aead_init(tfm, OTX2_CPT_AES_GCM, OTX2_CPT_MAC_NULL);
6986f03f0e8SSrujana Challa }
6996f03f0e8SSrujana Challa
otx2_cpt_aead_exit(struct crypto_aead * tfm)7006f03f0e8SSrujana Challa static void otx2_cpt_aead_exit(struct crypto_aead *tfm)
7016f03f0e8SSrujana Challa {
702d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
7036f03f0e8SSrujana Challa
7046f03f0e8SSrujana Challa kfree(ctx->ipad);
7056f03f0e8SSrujana Challa kfree(ctx->opad);
7066f03f0e8SSrujana Challa crypto_free_shash(ctx->hashalg);
7076f03f0e8SSrujana Challa kfree(ctx->sdesc);
7086f03f0e8SSrujana Challa
7096f03f0e8SSrujana Challa if (ctx->fbk_cipher) {
7106f03f0e8SSrujana Challa crypto_free_aead(ctx->fbk_cipher);
7116f03f0e8SSrujana Challa ctx->fbk_cipher = NULL;
7126f03f0e8SSrujana Challa }
7136f03f0e8SSrujana Challa }
7146f03f0e8SSrujana Challa
otx2_cpt_aead_gcm_set_authsize(struct crypto_aead * tfm,unsigned int authsize)7156f03f0e8SSrujana Challa static int otx2_cpt_aead_gcm_set_authsize(struct crypto_aead *tfm,
7166f03f0e8SSrujana Challa unsigned int authsize)
7176f03f0e8SSrujana Challa {
718d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
7196f03f0e8SSrujana Challa
7206f03f0e8SSrujana Challa if (crypto_rfc4106_check_authsize(authsize))
7216f03f0e8SSrujana Challa return -EINVAL;
7226f03f0e8SSrujana Challa
7236f03f0e8SSrujana Challa tfm->authsize = authsize;
7246f03f0e8SSrujana Challa /* Set authsize for fallback case */
7256f03f0e8SSrujana Challa if (ctx->fbk_cipher)
7266f03f0e8SSrujana Challa ctx->fbk_cipher->authsize = authsize;
7276f03f0e8SSrujana Challa
7286f03f0e8SSrujana Challa return 0;
7296f03f0e8SSrujana Challa }
7306f03f0e8SSrujana Challa
otx2_cpt_aead_set_authsize(struct crypto_aead * tfm,unsigned int authsize)7316f03f0e8SSrujana Challa static int otx2_cpt_aead_set_authsize(struct crypto_aead *tfm,
7326f03f0e8SSrujana Challa unsigned int authsize)
7336f03f0e8SSrujana Challa {
7346f03f0e8SSrujana Challa tfm->authsize = authsize;
7356f03f0e8SSrujana Challa
7366f03f0e8SSrujana Challa return 0;
7376f03f0e8SSrujana Challa }
7386f03f0e8SSrujana Challa
otx2_cpt_aead_null_set_authsize(struct crypto_aead * tfm,unsigned int authsize)7396f03f0e8SSrujana Challa static int otx2_cpt_aead_null_set_authsize(struct crypto_aead *tfm,
7406f03f0e8SSrujana Challa unsigned int authsize)
7416f03f0e8SSrujana Challa {
742d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
7436f03f0e8SSrujana Challa
7446f03f0e8SSrujana Challa ctx->is_trunc_hmac = true;
7456f03f0e8SSrujana Challa tfm->authsize = authsize;
7466f03f0e8SSrujana Challa
7476f03f0e8SSrujana Challa return 0;
7486f03f0e8SSrujana Challa }
7496f03f0e8SSrujana Challa
alloc_sdesc(struct crypto_shash * alg)7506f03f0e8SSrujana Challa static struct otx2_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg)
7516f03f0e8SSrujana Challa {
7526f03f0e8SSrujana Challa struct otx2_cpt_sdesc *sdesc;
7536f03f0e8SSrujana Challa int size;
7546f03f0e8SSrujana Challa
7556f03f0e8SSrujana Challa size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
7566f03f0e8SSrujana Challa sdesc = kmalloc(size, GFP_KERNEL);
7576f03f0e8SSrujana Challa if (!sdesc)
7586f03f0e8SSrujana Challa return NULL;
7596f03f0e8SSrujana Challa
7606f03f0e8SSrujana Challa sdesc->shash.tfm = alg;
7616f03f0e8SSrujana Challa
7626f03f0e8SSrujana Challa return sdesc;
7636f03f0e8SSrujana Challa }
7646f03f0e8SSrujana Challa
swap_data32(void * buf,u32 len)7656f03f0e8SSrujana Challa static inline void swap_data32(void *buf, u32 len)
7666f03f0e8SSrujana Challa {
7676f03f0e8SSrujana Challa cpu_to_be32_array(buf, buf, len / 4);
7686f03f0e8SSrujana Challa }
7696f03f0e8SSrujana Challa
swap_data64(void * buf,u32 len)7706f03f0e8SSrujana Challa static inline void swap_data64(void *buf, u32 len)
7716f03f0e8SSrujana Challa {
7726f03f0e8SSrujana Challa u64 *src = buf;
7736f03f0e8SSrujana Challa int i = 0;
7746f03f0e8SSrujana Challa
7756f03f0e8SSrujana Challa for (i = 0 ; i < len / 8; i++, src++)
7766f03f0e8SSrujana Challa cpu_to_be64s(src);
7776f03f0e8SSrujana Challa }
7786f03f0e8SSrujana Challa
swap_pad(u8 mac_type,u8 * pad)779*21ba7132SHerbert Xu static int swap_pad(u8 mac_type, u8 *pad)
7806f03f0e8SSrujana Challa {
7816f03f0e8SSrujana Challa struct sha512_state *sha512;
7826f03f0e8SSrujana Challa struct sha256_state *sha256;
7836f03f0e8SSrujana Challa struct sha1_state *sha1;
7846f03f0e8SSrujana Challa
7856f03f0e8SSrujana Challa switch (mac_type) {
7866f03f0e8SSrujana Challa case OTX2_CPT_SHA1:
787*21ba7132SHerbert Xu sha1 = (struct sha1_state *)pad;
7886f03f0e8SSrujana Challa swap_data32(sha1->state, SHA1_DIGEST_SIZE);
7896f03f0e8SSrujana Challa break;
7906f03f0e8SSrujana Challa
7916f03f0e8SSrujana Challa case OTX2_CPT_SHA256:
792*21ba7132SHerbert Xu sha256 = (struct sha256_state *)pad;
7936f03f0e8SSrujana Challa swap_data32(sha256->state, SHA256_DIGEST_SIZE);
7946f03f0e8SSrujana Challa break;
7956f03f0e8SSrujana Challa
7966f03f0e8SSrujana Challa case OTX2_CPT_SHA384:
7976f03f0e8SSrujana Challa case OTX2_CPT_SHA512:
798*21ba7132SHerbert Xu sha512 = (struct sha512_state *)pad;
7996f03f0e8SSrujana Challa swap_data64(sha512->state, SHA512_DIGEST_SIZE);
8006f03f0e8SSrujana Challa break;
8016f03f0e8SSrujana Challa
8026f03f0e8SSrujana Challa default:
8036f03f0e8SSrujana Challa return -EINVAL;
8046f03f0e8SSrujana Challa }
8056f03f0e8SSrujana Challa
8066f03f0e8SSrujana Challa return 0;
8076f03f0e8SSrujana Challa }
8086f03f0e8SSrujana Challa
aead_hmac_init(struct crypto_aead * cipher,struct crypto_authenc_keys * keys)809*21ba7132SHerbert Xu static int aead_hmac_init(struct crypto_aead *cipher,
810*21ba7132SHerbert Xu struct crypto_authenc_keys *keys)
8116f03f0e8SSrujana Challa {
812d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
8136f03f0e8SSrujana Challa int ds = crypto_shash_digestsize(ctx->hashalg);
8146f03f0e8SSrujana Challa int bs = crypto_shash_blocksize(ctx->hashalg);
815*21ba7132SHerbert Xu int authkeylen = keys->authkeylen;
8166f03f0e8SSrujana Challa u8 *ipad = NULL, *opad = NULL;
817*21ba7132SHerbert Xu int icount = 0;
818*21ba7132SHerbert Xu int ret;
8196f03f0e8SSrujana Challa
8206f03f0e8SSrujana Challa if (authkeylen > bs) {
821*21ba7132SHerbert Xu ret = crypto_shash_digest(&ctx->sdesc->shash, keys->authkey,
822*21ba7132SHerbert Xu authkeylen, ctx->key);
8236f03f0e8SSrujana Challa if (ret)
8246f03f0e8SSrujana Challa goto calc_fail;
8256f03f0e8SSrujana Challa
8266f03f0e8SSrujana Challa authkeylen = ds;
827*21ba7132SHerbert Xu } else
828*21ba7132SHerbert Xu memcpy(ctx->key, keys->authkey, authkeylen);
829*21ba7132SHerbert Xu
830*21ba7132SHerbert Xu ctx->enc_key_len = keys->enckeylen;
831*21ba7132SHerbert Xu ctx->auth_key_len = authkeylen;
832*21ba7132SHerbert Xu
833*21ba7132SHerbert Xu if (ctx->cipher_type == OTX2_CPT_CIPHER_NULL)
834*21ba7132SHerbert Xu return keys->enckeylen ? -EINVAL : 0;
835*21ba7132SHerbert Xu
836*21ba7132SHerbert Xu switch (keys->enckeylen) {
837*21ba7132SHerbert Xu case AES_KEYSIZE_128:
838*21ba7132SHerbert Xu ctx->key_type = OTX2_CPT_AES_128_BIT;
839*21ba7132SHerbert Xu break;
840*21ba7132SHerbert Xu case AES_KEYSIZE_192:
841*21ba7132SHerbert Xu ctx->key_type = OTX2_CPT_AES_192_BIT;
842*21ba7132SHerbert Xu break;
843*21ba7132SHerbert Xu case AES_KEYSIZE_256:
844*21ba7132SHerbert Xu ctx->key_type = OTX2_CPT_AES_256_BIT;
845*21ba7132SHerbert Xu break;
846*21ba7132SHerbert Xu default:
847*21ba7132SHerbert Xu /* Invalid key length */
848*21ba7132SHerbert Xu return -EINVAL;
8496f03f0e8SSrujana Challa }
8506f03f0e8SSrujana Challa
851*21ba7132SHerbert Xu memcpy(ctx->key + authkeylen, keys->enckey, keys->enckeylen);
852*21ba7132SHerbert Xu
853*21ba7132SHerbert Xu ipad = ctx->ipad;
854*21ba7132SHerbert Xu opad = ctx->opad;
855*21ba7132SHerbert Xu
856*21ba7132SHerbert Xu memcpy(ipad, ctx->key, authkeylen);
8576f03f0e8SSrujana Challa memset(ipad + authkeylen, 0, bs - authkeylen);
8586f03f0e8SSrujana Challa memcpy(opad, ipad, bs);
8596f03f0e8SSrujana Challa
8606f03f0e8SSrujana Challa for (icount = 0; icount < bs; icount++) {
8616f03f0e8SSrujana Challa ipad[icount] ^= 0x36;
8626f03f0e8SSrujana Challa opad[icount] ^= 0x5c;
8636f03f0e8SSrujana Challa }
8646f03f0e8SSrujana Challa
8656f03f0e8SSrujana Challa /*
8666f03f0e8SSrujana Challa * Partial Hash calculated from the software
8676f03f0e8SSrujana Challa * algorithm is retrieved for IPAD & OPAD
8686f03f0e8SSrujana Challa */
8696f03f0e8SSrujana Challa
8706f03f0e8SSrujana Challa /* IPAD Calculation */
8716f03f0e8SSrujana Challa crypto_shash_init(&ctx->sdesc->shash);
8726f03f0e8SSrujana Challa crypto_shash_update(&ctx->sdesc->shash, ipad, bs);
8736f03f0e8SSrujana Challa crypto_shash_export(&ctx->sdesc->shash, ipad);
874*21ba7132SHerbert Xu ret = swap_pad(ctx->mac_type, ipad);
8756f03f0e8SSrujana Challa if (ret)
8766f03f0e8SSrujana Challa goto calc_fail;
8776f03f0e8SSrujana Challa
8786f03f0e8SSrujana Challa /* OPAD Calculation */
8796f03f0e8SSrujana Challa crypto_shash_init(&ctx->sdesc->shash);
8806f03f0e8SSrujana Challa crypto_shash_update(&ctx->sdesc->shash, opad, bs);
8816f03f0e8SSrujana Challa crypto_shash_export(&ctx->sdesc->shash, opad);
882*21ba7132SHerbert Xu ret = swap_pad(ctx->mac_type, opad);
8836f03f0e8SSrujana Challa
8846f03f0e8SSrujana Challa calc_fail:
8856f03f0e8SSrujana Challa return ret;
8866f03f0e8SSrujana Challa }
8876f03f0e8SSrujana Challa
otx2_cpt_aead_cbc_aes_sha_setkey(struct crypto_aead * cipher,const unsigned char * key,unsigned int keylen)8886f03f0e8SSrujana Challa static int otx2_cpt_aead_cbc_aes_sha_setkey(struct crypto_aead *cipher,
8896f03f0e8SSrujana Challa const unsigned char *key,
8906f03f0e8SSrujana Challa unsigned int keylen)
8916f03f0e8SSrujana Challa {
892*21ba7132SHerbert Xu struct crypto_authenc_keys authenc_keys;
8936f03f0e8SSrujana Challa
894*21ba7132SHerbert Xu return crypto_authenc_extractkeys(&authenc_keys, key, keylen) ?:
895*21ba7132SHerbert Xu aead_hmac_init(cipher, &authenc_keys);
8966f03f0e8SSrujana Challa }
8976f03f0e8SSrujana Challa
otx2_cpt_aead_ecb_null_sha_setkey(struct crypto_aead * cipher,const unsigned char * key,unsigned int keylen)8986f03f0e8SSrujana Challa static int otx2_cpt_aead_ecb_null_sha_setkey(struct crypto_aead *cipher,
8996f03f0e8SSrujana Challa const unsigned char *key,
9006f03f0e8SSrujana Challa unsigned int keylen)
9016f03f0e8SSrujana Challa {
902*21ba7132SHerbert Xu return otx2_cpt_aead_cbc_aes_sha_setkey(cipher, key, keylen);
9036f03f0e8SSrujana Challa }
9046f03f0e8SSrujana Challa
otx2_cpt_aead_gcm_aes_setkey(struct crypto_aead * cipher,const unsigned char * key,unsigned int keylen)9056f03f0e8SSrujana Challa static int otx2_cpt_aead_gcm_aes_setkey(struct crypto_aead *cipher,
9066f03f0e8SSrujana Challa const unsigned char *key,
9076f03f0e8SSrujana Challa unsigned int keylen)
9086f03f0e8SSrujana Challa {
909d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
9106f03f0e8SSrujana Challa
9116f03f0e8SSrujana Challa /*
9126f03f0e8SSrujana Challa * For aes gcm we expect to get encryption key (16, 24, 32 bytes)
9136f03f0e8SSrujana Challa * and salt (4 bytes)
9146f03f0e8SSrujana Challa */
9156f03f0e8SSrujana Challa switch (keylen) {
9166f03f0e8SSrujana Challa case AES_KEYSIZE_128 + AES_GCM_SALT_SIZE:
9176f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_128_BIT;
9186f03f0e8SSrujana Challa ctx->enc_key_len = AES_KEYSIZE_128;
9196f03f0e8SSrujana Challa break;
9206f03f0e8SSrujana Challa case AES_KEYSIZE_192 + AES_GCM_SALT_SIZE:
9216f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_192_BIT;
9226f03f0e8SSrujana Challa ctx->enc_key_len = AES_KEYSIZE_192;
9236f03f0e8SSrujana Challa break;
9246f03f0e8SSrujana Challa case AES_KEYSIZE_256 + AES_GCM_SALT_SIZE:
9256f03f0e8SSrujana Challa ctx->key_type = OTX2_CPT_AES_256_BIT;
9266f03f0e8SSrujana Challa ctx->enc_key_len = AES_KEYSIZE_256;
9276f03f0e8SSrujana Challa break;
9286f03f0e8SSrujana Challa default:
9296f03f0e8SSrujana Challa /* Invalid key and salt length */
9306f03f0e8SSrujana Challa return -EINVAL;
9316f03f0e8SSrujana Challa }
9326f03f0e8SSrujana Challa
9336f03f0e8SSrujana Challa /* Store encryption key and salt */
9346f03f0e8SSrujana Challa memcpy(ctx->key, key, keylen);
9356f03f0e8SSrujana Challa
9366f03f0e8SSrujana Challa return crypto_aead_setkey(ctx->fbk_cipher, key, keylen);
9376f03f0e8SSrujana Challa }
9386f03f0e8SSrujana Challa
create_aead_ctx_hdr(struct aead_request * req,u32 enc,u32 * argcnt)9396f03f0e8SSrujana Challa static inline int create_aead_ctx_hdr(struct aead_request *req, u32 enc,
9406f03f0e8SSrujana Challa u32 *argcnt)
9416f03f0e8SSrujana Challa {
942d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
9436f03f0e8SSrujana Challa struct crypto_aead *tfm = crypto_aead_reqtfm(req);
944d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
9456f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
9466f03f0e8SSrujana Challa struct otx2_cpt_fc_ctx *fctx = &rctx->fctx;
9476f03f0e8SSrujana Challa int mac_len = crypto_aead_authsize(tfm);
9486f03f0e8SSrujana Challa int ds;
9496f03f0e8SSrujana Challa
9506f03f0e8SSrujana Challa rctx->ctrl_word.e.enc_data_offset = req->assoclen;
9516f03f0e8SSrujana Challa
9526f03f0e8SSrujana Challa switch (ctx->cipher_type) {
9536f03f0e8SSrujana Challa case OTX2_CPT_AES_CBC:
9546f03f0e8SSrujana Challa if (req->assoclen > 248 || !IS_ALIGNED(req->assoclen, 8))
9556f03f0e8SSrujana Challa return -EINVAL;
9566f03f0e8SSrujana Challa
9576f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.iv_source = OTX2_CPT_FROM_CPTR;
9586f03f0e8SSrujana Challa /* Copy encryption key to context */
9596f03f0e8SSrujana Challa memcpy(fctx->enc.encr_key, ctx->key + ctx->auth_key_len,
9606f03f0e8SSrujana Challa ctx->enc_key_len);
9616f03f0e8SSrujana Challa /* Copy IV to context */
9626f03f0e8SSrujana Challa memcpy(fctx->enc.encr_iv, req->iv, crypto_aead_ivsize(tfm));
9636f03f0e8SSrujana Challa
9646f03f0e8SSrujana Challa ds = crypto_shash_digestsize(ctx->hashalg);
9656f03f0e8SSrujana Challa if (ctx->mac_type == OTX2_CPT_SHA384)
9666f03f0e8SSrujana Challa ds = SHA512_DIGEST_SIZE;
9676f03f0e8SSrujana Challa if (ctx->ipad)
9686f03f0e8SSrujana Challa memcpy(fctx->hmac.e.ipad, ctx->ipad, ds);
9696f03f0e8SSrujana Challa if (ctx->opad)
9706f03f0e8SSrujana Challa memcpy(fctx->hmac.e.opad, ctx->opad, ds);
9716f03f0e8SSrujana Challa break;
9726f03f0e8SSrujana Challa
9736f03f0e8SSrujana Challa case OTX2_CPT_AES_GCM:
9746f03f0e8SSrujana Challa if (crypto_ipsec_check_assoclen(req->assoclen))
9756f03f0e8SSrujana Challa return -EINVAL;
9766f03f0e8SSrujana Challa
9776f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.iv_source = OTX2_CPT_FROM_DPTR;
9786f03f0e8SSrujana Challa /* Copy encryption key to context */
9796f03f0e8SSrujana Challa memcpy(fctx->enc.encr_key, ctx->key, ctx->enc_key_len);
9806f03f0e8SSrujana Challa /* Copy salt to context */
9816f03f0e8SSrujana Challa memcpy(fctx->enc.encr_iv, ctx->key + ctx->enc_key_len,
9826f03f0e8SSrujana Challa AES_GCM_SALT_SIZE);
9836f03f0e8SSrujana Challa
9846f03f0e8SSrujana Challa rctx->ctrl_word.e.iv_offset = req->assoclen - AES_GCM_IV_OFFSET;
9856f03f0e8SSrujana Challa break;
9866f03f0e8SSrujana Challa
9876f03f0e8SSrujana Challa default:
9886f03f0e8SSrujana Challa /* Unknown cipher type */
9896f03f0e8SSrujana Challa return -EINVAL;
9906f03f0e8SSrujana Challa }
9916f03f0e8SSrujana Challa cpu_to_be64s(&rctx->ctrl_word.flags);
9926f03f0e8SSrujana Challa
9936f03f0e8SSrujana Challa req_info->ctrl.s.dma_mode = OTX2_CPT_DMA_MODE_SG;
9946f03f0e8SSrujana Challa req_info->ctrl.s.se_req = 1;
9956f03f0e8SSrujana Challa req_info->req.opcode.s.major = OTX2_CPT_MAJOR_OP_FC |
9966f03f0e8SSrujana Challa DMA_MODE_FLAG(OTX2_CPT_DMA_MODE_SG);
9976f03f0e8SSrujana Challa if (enc) {
9986f03f0e8SSrujana Challa req_info->req.opcode.s.minor = 2;
9996f03f0e8SSrujana Challa req_info->req.param1 = req->cryptlen;
10006f03f0e8SSrujana Challa req_info->req.param2 = req->cryptlen + req->assoclen;
10016f03f0e8SSrujana Challa } else {
10026f03f0e8SSrujana Challa req_info->req.opcode.s.minor = 3;
10036f03f0e8SSrujana Challa req_info->req.param1 = req->cryptlen - mac_len;
10046f03f0e8SSrujana Challa req_info->req.param2 = req->cryptlen + req->assoclen - mac_len;
10056f03f0e8SSrujana Challa }
10066f03f0e8SSrujana Challa
10076f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;
10086f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;
10096f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.mac_type = ctx->mac_type;
10106f03f0e8SSrujana Challa fctx->enc.enc_ctrl.e.mac_len = mac_len;
10116f03f0e8SSrujana Challa cpu_to_be64s(&fctx->enc.enc_ctrl.u);
10126f03f0e8SSrujana Challa
10136f03f0e8SSrujana Challa /*
10146f03f0e8SSrujana Challa * Storing Packet Data Information in offset
10156f03f0e8SSrujana Challa * Control Word First 8 bytes
10166f03f0e8SSrujana Challa */
10176f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word;
10186f03f0e8SSrujana Challa req_info->in[*argcnt].size = CONTROL_WORD_LEN;
10196f03f0e8SSrujana Challa req_info->req.dlen += CONTROL_WORD_LEN;
10206f03f0e8SSrujana Challa ++(*argcnt);
10216f03f0e8SSrujana Challa
10226f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = (u8 *)fctx;
10236f03f0e8SSrujana Challa req_info->in[*argcnt].size = sizeof(struct otx2_cpt_fc_ctx);
10246f03f0e8SSrujana Challa req_info->req.dlen += sizeof(struct otx2_cpt_fc_ctx);
10256f03f0e8SSrujana Challa ++(*argcnt);
10266f03f0e8SSrujana Challa
10276f03f0e8SSrujana Challa return 0;
10286f03f0e8SSrujana Challa }
10296f03f0e8SSrujana Challa
create_hmac_ctx_hdr(struct aead_request * req,u32 * argcnt,u32 enc)10306f03f0e8SSrujana Challa static inline void create_hmac_ctx_hdr(struct aead_request *req, u32 *argcnt,
10316f03f0e8SSrujana Challa u32 enc)
10326f03f0e8SSrujana Challa {
1033d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
10346f03f0e8SSrujana Challa struct crypto_aead *tfm = crypto_aead_reqtfm(req);
1035d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
10366f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
10376f03f0e8SSrujana Challa
10386f03f0e8SSrujana Challa req_info->ctrl.s.dma_mode = OTX2_CPT_DMA_MODE_SG;
10396f03f0e8SSrujana Challa req_info->ctrl.s.se_req = 1;
10406f03f0e8SSrujana Challa req_info->req.opcode.s.major = OTX2_CPT_MAJOR_OP_HMAC |
10416f03f0e8SSrujana Challa DMA_MODE_FLAG(OTX2_CPT_DMA_MODE_SG);
10426f03f0e8SSrujana Challa req_info->is_trunc_hmac = ctx->is_trunc_hmac;
10436f03f0e8SSrujana Challa
10446f03f0e8SSrujana Challa req_info->req.opcode.s.minor = 0;
10456f03f0e8SSrujana Challa req_info->req.param1 = ctx->auth_key_len;
10466f03f0e8SSrujana Challa req_info->req.param2 = ctx->mac_type << 8;
10476f03f0e8SSrujana Challa
10486f03f0e8SSrujana Challa /* Add authentication key */
10496f03f0e8SSrujana Challa req_info->in[*argcnt].vptr = ctx->key;
10506f03f0e8SSrujana Challa req_info->in[*argcnt].size = round_up(ctx->auth_key_len, 8);
10516f03f0e8SSrujana Challa req_info->req.dlen += round_up(ctx->auth_key_len, 8);
10526f03f0e8SSrujana Challa ++(*argcnt);
10536f03f0e8SSrujana Challa }
10546f03f0e8SSrujana Challa
create_aead_input_list(struct aead_request * req,u32 enc)10556f03f0e8SSrujana Challa static inline int create_aead_input_list(struct aead_request *req, u32 enc)
10566f03f0e8SSrujana Challa {
1057d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
10586f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
10596f03f0e8SSrujana Challa u32 inputlen = req->cryptlen + req->assoclen;
10606f03f0e8SSrujana Challa u32 status, argcnt = 0;
10616f03f0e8SSrujana Challa
10626f03f0e8SSrujana Challa status = create_aead_ctx_hdr(req, enc, &argcnt);
10636f03f0e8SSrujana Challa if (status)
10646f03f0e8SSrujana Challa return status;
10656f03f0e8SSrujana Challa update_input_data(req_info, req->src, inputlen, &argcnt);
10666f03f0e8SSrujana Challa req_info->in_cnt = argcnt;
10676f03f0e8SSrujana Challa
10686f03f0e8SSrujana Challa return 0;
10696f03f0e8SSrujana Challa }
10706f03f0e8SSrujana Challa
create_aead_output_list(struct aead_request * req,u32 enc,u32 mac_len)10716f03f0e8SSrujana Challa static inline void create_aead_output_list(struct aead_request *req, u32 enc,
10726f03f0e8SSrujana Challa u32 mac_len)
10736f03f0e8SSrujana Challa {
1074d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
10756f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
10766f03f0e8SSrujana Challa u32 argcnt = 0, outputlen = 0;
10776f03f0e8SSrujana Challa
10786f03f0e8SSrujana Challa if (enc)
10796f03f0e8SSrujana Challa outputlen = req->cryptlen + req->assoclen + mac_len;
10806f03f0e8SSrujana Challa else
10816f03f0e8SSrujana Challa outputlen = req->cryptlen + req->assoclen - mac_len;
10826f03f0e8SSrujana Challa
10836f03f0e8SSrujana Challa update_output_data(req_info, req->dst, 0, outputlen, &argcnt);
10846f03f0e8SSrujana Challa req_info->out_cnt = argcnt;
10856f03f0e8SSrujana Challa }
10866f03f0e8SSrujana Challa
create_aead_null_input_list(struct aead_request * req,u32 enc,u32 mac_len)10876f03f0e8SSrujana Challa static inline void create_aead_null_input_list(struct aead_request *req,
10886f03f0e8SSrujana Challa u32 enc, u32 mac_len)
10896f03f0e8SSrujana Challa {
1090d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
10916f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
10926f03f0e8SSrujana Challa u32 inputlen, argcnt = 0;
10936f03f0e8SSrujana Challa
10946f03f0e8SSrujana Challa if (enc)
10956f03f0e8SSrujana Challa inputlen = req->cryptlen + req->assoclen;
10966f03f0e8SSrujana Challa else
10976f03f0e8SSrujana Challa inputlen = req->cryptlen + req->assoclen - mac_len;
10986f03f0e8SSrujana Challa
10996f03f0e8SSrujana Challa create_hmac_ctx_hdr(req, &argcnt, enc);
11006f03f0e8SSrujana Challa update_input_data(req_info, req->src, inputlen, &argcnt);
11016f03f0e8SSrujana Challa req_info->in_cnt = argcnt;
11026f03f0e8SSrujana Challa }
11036f03f0e8SSrujana Challa
create_aead_null_output_list(struct aead_request * req,u32 enc,u32 mac_len)11046f03f0e8SSrujana Challa static inline int create_aead_null_output_list(struct aead_request *req,
11056f03f0e8SSrujana Challa u32 enc, u32 mac_len)
11066f03f0e8SSrujana Challa {
1107d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
11086f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
11096f03f0e8SSrujana Challa struct scatterlist *dst;
11106f03f0e8SSrujana Challa u8 *ptr = NULL;
11116f03f0e8SSrujana Challa int argcnt = 0, status, offset;
11126f03f0e8SSrujana Challa u32 inputlen;
11136f03f0e8SSrujana Challa
11146f03f0e8SSrujana Challa if (enc)
11156f03f0e8SSrujana Challa inputlen = req->cryptlen + req->assoclen;
11166f03f0e8SSrujana Challa else
11176f03f0e8SSrujana Challa inputlen = req->cryptlen + req->assoclen - mac_len;
11186f03f0e8SSrujana Challa
11196f03f0e8SSrujana Challa /*
11206f03f0e8SSrujana Challa * If source and destination are different
11216f03f0e8SSrujana Challa * then copy payload to destination
11226f03f0e8SSrujana Challa */
11236f03f0e8SSrujana Challa if (req->src != req->dst) {
11246f03f0e8SSrujana Challa
11256f03f0e8SSrujana Challa ptr = kmalloc(inputlen, (req_info->areq->flags &
11266f03f0e8SSrujana Challa CRYPTO_TFM_REQ_MAY_SLEEP) ?
11276f03f0e8SSrujana Challa GFP_KERNEL : GFP_ATOMIC);
11286f03f0e8SSrujana Challa if (!ptr)
11296f03f0e8SSrujana Challa return -ENOMEM;
11306f03f0e8SSrujana Challa
11316f03f0e8SSrujana Challa status = sg_copy_to_buffer(req->src, sg_nents(req->src), ptr,
11326f03f0e8SSrujana Challa inputlen);
11336f03f0e8SSrujana Challa if (status != inputlen) {
11346f03f0e8SSrujana Challa status = -EINVAL;
11356f03f0e8SSrujana Challa goto error_free;
11366f03f0e8SSrujana Challa }
11376f03f0e8SSrujana Challa status = sg_copy_from_buffer(req->dst, sg_nents(req->dst), ptr,
11386f03f0e8SSrujana Challa inputlen);
11396f03f0e8SSrujana Challa if (status != inputlen) {
11406f03f0e8SSrujana Challa status = -EINVAL;
11416f03f0e8SSrujana Challa goto error_free;
11426f03f0e8SSrujana Challa }
11436f03f0e8SSrujana Challa kfree(ptr);
11446f03f0e8SSrujana Challa }
11456f03f0e8SSrujana Challa
11466f03f0e8SSrujana Challa if (enc) {
11476f03f0e8SSrujana Challa /*
11486f03f0e8SSrujana Challa * In an encryption scenario hmac needs
11496f03f0e8SSrujana Challa * to be appended after payload
11506f03f0e8SSrujana Challa */
11516f03f0e8SSrujana Challa dst = req->dst;
11526f03f0e8SSrujana Challa offset = inputlen;
11536f03f0e8SSrujana Challa while (offset >= dst->length) {
11546f03f0e8SSrujana Challa offset -= dst->length;
11556f03f0e8SSrujana Challa dst = sg_next(dst);
11566f03f0e8SSrujana Challa if (!dst)
11576f03f0e8SSrujana Challa return -ENOENT;
11586f03f0e8SSrujana Challa }
11596f03f0e8SSrujana Challa
11606f03f0e8SSrujana Challa update_output_data(req_info, dst, offset, mac_len, &argcnt);
11616f03f0e8SSrujana Challa } else {
11626f03f0e8SSrujana Challa /*
11636f03f0e8SSrujana Challa * In a decryption scenario calculated hmac for received
11646f03f0e8SSrujana Challa * payload needs to be compare with hmac received
11656f03f0e8SSrujana Challa */
11666f03f0e8SSrujana Challa status = sg_copy_buffer(req->src, sg_nents(req->src),
11676f03f0e8SSrujana Challa rctx->fctx.hmac.s.hmac_recv, mac_len,
11686f03f0e8SSrujana Challa inputlen, true);
11696f03f0e8SSrujana Challa if (status != mac_len)
11706f03f0e8SSrujana Challa return -EINVAL;
11716f03f0e8SSrujana Challa
11726f03f0e8SSrujana Challa req_info->out[argcnt].vptr = rctx->fctx.hmac.s.hmac_calc;
11736f03f0e8SSrujana Challa req_info->out[argcnt].size = mac_len;
11746f03f0e8SSrujana Challa argcnt++;
11756f03f0e8SSrujana Challa }
11766f03f0e8SSrujana Challa
11776f03f0e8SSrujana Challa req_info->out_cnt = argcnt;
11786f03f0e8SSrujana Challa return 0;
11796f03f0e8SSrujana Challa
11806f03f0e8SSrujana Challa error_free:
11816f03f0e8SSrujana Challa kfree(ptr);
11826f03f0e8SSrujana Challa return status;
11836f03f0e8SSrujana Challa }
11846f03f0e8SSrujana Challa
aead_do_fallback(struct aead_request * req,bool is_enc)11856f03f0e8SSrujana Challa static int aead_do_fallback(struct aead_request *req, bool is_enc)
11866f03f0e8SSrujana Challa {
1187d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
11886f03f0e8SSrujana Challa struct crypto_aead *aead = crypto_aead_reqtfm(req);
1189d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(aead);
11906f03f0e8SSrujana Challa int ret;
11916f03f0e8SSrujana Challa
11926f03f0e8SSrujana Challa if (ctx->fbk_cipher) {
11936f03f0e8SSrujana Challa /* Store the cipher tfm and then use the fallback tfm */
11946f03f0e8SSrujana Challa aead_request_set_tfm(&rctx->fbk_req, ctx->fbk_cipher);
11956f03f0e8SSrujana Challa aead_request_set_callback(&rctx->fbk_req, req->base.flags,
11966f03f0e8SSrujana Challa req->base.complete, req->base.data);
11976f03f0e8SSrujana Challa aead_request_set_crypt(&rctx->fbk_req, req->src,
11986f03f0e8SSrujana Challa req->dst, req->cryptlen, req->iv);
119906f6e365SOvidiu Panait aead_request_set_ad(&rctx->fbk_req, req->assoclen);
12006f03f0e8SSrujana Challa ret = is_enc ? crypto_aead_encrypt(&rctx->fbk_req) :
12016f03f0e8SSrujana Challa crypto_aead_decrypt(&rctx->fbk_req);
12026f03f0e8SSrujana Challa } else {
12036f03f0e8SSrujana Challa ret = -EINVAL;
12046f03f0e8SSrujana Challa }
12056f03f0e8SSrujana Challa
12066f03f0e8SSrujana Challa return ret;
12076f03f0e8SSrujana Challa }
12086f03f0e8SSrujana Challa
cpt_aead_enc_dec(struct aead_request * req,u8 reg_type,u8 enc)12096f03f0e8SSrujana Challa static int cpt_aead_enc_dec(struct aead_request *req, u8 reg_type, u8 enc)
12106f03f0e8SSrujana Challa {
1211d887dec1SHerbert Xu struct otx2_cpt_req_ctx *rctx = aead_request_ctx_dma(req);
12126f03f0e8SSrujana Challa struct otx2_cpt_req_info *req_info = &rctx->cpt_req;
12136f03f0e8SSrujana Challa struct crypto_aead *tfm = crypto_aead_reqtfm(req);
1214d887dec1SHerbert Xu struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);
12156f03f0e8SSrujana Challa struct pci_dev *pdev;
12166f03f0e8SSrujana Challa int status, cpu_num;
12176f03f0e8SSrujana Challa
12186f03f0e8SSrujana Challa /* Clear control words */
12196f03f0e8SSrujana Challa rctx->ctrl_word.flags = 0;
12206f03f0e8SSrujana Challa rctx->fctx.enc.enc_ctrl.u = 0;
12216f03f0e8SSrujana Challa
12226f03f0e8SSrujana Challa req_info->callback = otx2_cpt_aead_callback;
12236f03f0e8SSrujana Challa req_info->areq = &req->base;
12246f03f0e8SSrujana Challa req_info->req_type = reg_type;
12256f03f0e8SSrujana Challa req_info->is_enc = enc;
12266f03f0e8SSrujana Challa req_info->is_trunc_hmac = false;
12276f03f0e8SSrujana Challa
12286f03f0e8SSrujana Challa switch (reg_type) {
12296f03f0e8SSrujana Challa case OTX2_CPT_AEAD_ENC_DEC_REQ:
12306f03f0e8SSrujana Challa status = create_aead_input_list(req, enc);
12316f03f0e8SSrujana Challa if (status)
12326f03f0e8SSrujana Challa return status;
12336f03f0e8SSrujana Challa create_aead_output_list(req, enc, crypto_aead_authsize(tfm));
12346f03f0e8SSrujana Challa break;
12356f03f0e8SSrujana Challa
12366f03f0e8SSrujana Challa case OTX2_CPT_AEAD_ENC_DEC_NULL_REQ:
12376f03f0e8SSrujana Challa create_aead_null_input_list(req, enc,
12386f03f0e8SSrujana Challa crypto_aead_authsize(tfm));
12396f03f0e8SSrujana Challa status = create_aead_null_output_list(req, enc,
12406f03f0e8SSrujana Challa crypto_aead_authsize(tfm));
12416f03f0e8SSrujana Challa if (status)
12426f03f0e8SSrujana Challa return status;
12436f03f0e8SSrujana Challa break;
12446f03f0e8SSrujana Challa
12456f03f0e8SSrujana Challa default:
12466f03f0e8SSrujana Challa return -EINVAL;
12476f03f0e8SSrujana Challa }
12486f03f0e8SSrujana Challa if (!IS_ALIGNED(req_info->req.param1, ctx->enc_align_len))
12496f03f0e8SSrujana Challa return -EINVAL;
12506f03f0e8SSrujana Challa
12516f03f0e8SSrujana Challa if (!req_info->req.param2 ||
12526f03f0e8SSrujana Challa (req_info->req.param1 > OTX2_CPT_MAX_REQ_SIZE) ||
12536f03f0e8SSrujana Challa (req_info->req.param2 > OTX2_CPT_MAX_REQ_SIZE))
12546f03f0e8SSrujana Challa return aead_do_fallback(req, enc);
12556f03f0e8SSrujana Challa
12566f03f0e8SSrujana Challa status = get_se_device(&pdev, &cpu_num);
12576f03f0e8SSrujana Challa if (status)
12586f03f0e8SSrujana Challa return status;
12596f03f0e8SSrujana Challa
12606f03f0e8SSrujana Challa req_info->ctrl.s.grp = otx2_cpt_get_kcrypto_eng_grp_num(pdev);
12616f03f0e8SSrujana Challa
12626f03f0e8SSrujana Challa /*
12636f03f0e8SSrujana Challa * We perform an asynchronous send and once
12646f03f0e8SSrujana Challa * the request is completed the driver would
12656f03f0e8SSrujana Challa * intimate through registered call back functions
12666f03f0e8SSrujana Challa */
12676f03f0e8SSrujana Challa return otx2_cpt_do_request(pdev, req_info, cpu_num);
12686f03f0e8SSrujana Challa }
12696f03f0e8SSrujana Challa
otx2_cpt_aead_encrypt(struct aead_request * req)12706f03f0e8SSrujana Challa static int otx2_cpt_aead_encrypt(struct aead_request *req)
12716f03f0e8SSrujana Challa {
12726f03f0e8SSrujana Challa return cpt_aead_enc_dec(req, OTX2_CPT_AEAD_ENC_DEC_REQ, true);
12736f03f0e8SSrujana Challa }
12746f03f0e8SSrujana Challa
otx2_cpt_aead_decrypt(struct aead_request * req)12756f03f0e8SSrujana Challa static int otx2_cpt_aead_decrypt(struct aead_request *req)
12766f03f0e8SSrujana Challa {
12776f03f0e8SSrujana Challa return cpt_aead_enc_dec(req, OTX2_CPT_AEAD_ENC_DEC_REQ, false);
12786f03f0e8SSrujana Challa }
12796f03f0e8SSrujana Challa
otx2_cpt_aead_null_encrypt(struct aead_request * req)12806f03f0e8SSrujana Challa static int otx2_cpt_aead_null_encrypt(struct aead_request *req)
12816f03f0e8SSrujana Challa {
12826f03f0e8SSrujana Challa return cpt_aead_enc_dec(req, OTX2_CPT_AEAD_ENC_DEC_NULL_REQ, true);
12836f03f0e8SSrujana Challa }
12846f03f0e8SSrujana Challa
otx2_cpt_aead_null_decrypt(struct aead_request * req)12856f03f0e8SSrujana Challa static int otx2_cpt_aead_null_decrypt(struct aead_request *req)
12866f03f0e8SSrujana Challa {
12876f03f0e8SSrujana Challa return cpt_aead_enc_dec(req, OTX2_CPT_AEAD_ENC_DEC_NULL_REQ, false);
12886f03f0e8SSrujana Challa }
12896f03f0e8SSrujana Challa
12906f03f0e8SSrujana Challa static struct skcipher_alg otx2_cpt_skciphers[] = { {
12916f03f0e8SSrujana Challa .base.cra_name = "xts(aes)",
12926f03f0e8SSrujana Challa .base.cra_driver_name = "cpt_xts_aes",
12936f03f0e8SSrujana Challa .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
12946f03f0e8SSrujana Challa .base.cra_blocksize = AES_BLOCK_SIZE,
12956f03f0e8SSrujana Challa .base.cra_ctxsize = sizeof(struct otx2_cpt_enc_ctx),
12966f03f0e8SSrujana Challa .base.cra_alignmask = 7,
12976f03f0e8SSrujana Challa .base.cra_priority = 4001,
12986f03f0e8SSrujana Challa .base.cra_module = THIS_MODULE,
12996f03f0e8SSrujana Challa
13006f03f0e8SSrujana Challa .init = otx2_cpt_enc_dec_init,
13016f03f0e8SSrujana Challa .exit = otx2_cpt_skcipher_exit,
13026f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
13036f03f0e8SSrujana Challa .min_keysize = 2 * AES_MIN_KEY_SIZE,
13046f03f0e8SSrujana Challa .max_keysize = 2 * AES_MAX_KEY_SIZE,
13056f03f0e8SSrujana Challa .setkey = otx2_cpt_skcipher_xts_setkey,
13066f03f0e8SSrujana Challa .encrypt = otx2_cpt_skcipher_encrypt,
13076f03f0e8SSrujana Challa .decrypt = otx2_cpt_skcipher_decrypt,
13086f03f0e8SSrujana Challa }, {
13096f03f0e8SSrujana Challa .base.cra_name = "cbc(aes)",
13106f03f0e8SSrujana Challa .base.cra_driver_name = "cpt_cbc_aes",
13116f03f0e8SSrujana Challa .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
13126f03f0e8SSrujana Challa .base.cra_blocksize = AES_BLOCK_SIZE,
13136f03f0e8SSrujana Challa .base.cra_ctxsize = sizeof(struct otx2_cpt_enc_ctx),
13146f03f0e8SSrujana Challa .base.cra_alignmask = 7,
13156f03f0e8SSrujana Challa .base.cra_priority = 4001,
13166f03f0e8SSrujana Challa .base.cra_module = THIS_MODULE,
13176f03f0e8SSrujana Challa
13186f03f0e8SSrujana Challa .init = otx2_cpt_enc_dec_init,
13196f03f0e8SSrujana Challa .exit = otx2_cpt_skcipher_exit,
13206f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
13216f03f0e8SSrujana Challa .min_keysize = AES_MIN_KEY_SIZE,
13226f03f0e8SSrujana Challa .max_keysize = AES_MAX_KEY_SIZE,
13236f03f0e8SSrujana Challa .setkey = otx2_cpt_skcipher_cbc_aes_setkey,
13246f03f0e8SSrujana Challa .encrypt = otx2_cpt_skcipher_encrypt,
13256f03f0e8SSrujana Challa .decrypt = otx2_cpt_skcipher_decrypt,
13266f03f0e8SSrujana Challa }, {
13276f03f0e8SSrujana Challa .base.cra_name = "ecb(aes)",
13286f03f0e8SSrujana Challa .base.cra_driver_name = "cpt_ecb_aes",
13296f03f0e8SSrujana Challa .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
13306f03f0e8SSrujana Challa .base.cra_blocksize = AES_BLOCK_SIZE,
13316f03f0e8SSrujana Challa .base.cra_ctxsize = sizeof(struct otx2_cpt_enc_ctx),
13326f03f0e8SSrujana Challa .base.cra_alignmask = 7,
13336f03f0e8SSrujana Challa .base.cra_priority = 4001,
13346f03f0e8SSrujana Challa .base.cra_module = THIS_MODULE,
13356f03f0e8SSrujana Challa
13366f03f0e8SSrujana Challa .init = otx2_cpt_enc_dec_init,
13376f03f0e8SSrujana Challa .exit = otx2_cpt_skcipher_exit,
13386f03f0e8SSrujana Challa .ivsize = 0,
13396f03f0e8SSrujana Challa .min_keysize = AES_MIN_KEY_SIZE,
13406f03f0e8SSrujana Challa .max_keysize = AES_MAX_KEY_SIZE,
13416f03f0e8SSrujana Challa .setkey = otx2_cpt_skcipher_ecb_aes_setkey,
13426f03f0e8SSrujana Challa .encrypt = otx2_cpt_skcipher_encrypt,
13436f03f0e8SSrujana Challa .decrypt = otx2_cpt_skcipher_decrypt,
13446f03f0e8SSrujana Challa }, {
13456f03f0e8SSrujana Challa .base.cra_name = "cbc(des3_ede)",
13466f03f0e8SSrujana Challa .base.cra_driver_name = "cpt_cbc_des3_ede",
13476f03f0e8SSrujana Challa .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
13486f03f0e8SSrujana Challa .base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
13496f03f0e8SSrujana Challa .base.cra_ctxsize = sizeof(struct otx2_cpt_enc_ctx),
13506f03f0e8SSrujana Challa .base.cra_alignmask = 7,
13516f03f0e8SSrujana Challa .base.cra_priority = 4001,
13526f03f0e8SSrujana Challa .base.cra_module = THIS_MODULE,
13536f03f0e8SSrujana Challa
13546f03f0e8SSrujana Challa .init = otx2_cpt_enc_dec_init,
13556f03f0e8SSrujana Challa .exit = otx2_cpt_skcipher_exit,
13566f03f0e8SSrujana Challa .min_keysize = DES3_EDE_KEY_SIZE,
13576f03f0e8SSrujana Challa .max_keysize = DES3_EDE_KEY_SIZE,
13586f03f0e8SSrujana Challa .ivsize = DES_BLOCK_SIZE,
13596f03f0e8SSrujana Challa .setkey = otx2_cpt_skcipher_cbc_des3_setkey,
13606f03f0e8SSrujana Challa .encrypt = otx2_cpt_skcipher_encrypt,
13616f03f0e8SSrujana Challa .decrypt = otx2_cpt_skcipher_decrypt,
13626f03f0e8SSrujana Challa }, {
13636f03f0e8SSrujana Challa .base.cra_name = "ecb(des3_ede)",
13646f03f0e8SSrujana Challa .base.cra_driver_name = "cpt_ecb_des3_ede",
13656f03f0e8SSrujana Challa .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
13666f03f0e8SSrujana Challa .base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
13676f03f0e8SSrujana Challa .base.cra_ctxsize = sizeof(struct otx2_cpt_enc_ctx),
13686f03f0e8SSrujana Challa .base.cra_alignmask = 7,
13696f03f0e8SSrujana Challa .base.cra_priority = 4001,
13706f03f0e8SSrujana Challa .base.cra_module = THIS_MODULE,
13716f03f0e8SSrujana Challa
13726f03f0e8SSrujana Challa .init = otx2_cpt_enc_dec_init,
13736f03f0e8SSrujana Challa .exit = otx2_cpt_skcipher_exit,
13746f03f0e8SSrujana Challa .min_keysize = DES3_EDE_KEY_SIZE,
13756f03f0e8SSrujana Challa .max_keysize = DES3_EDE_KEY_SIZE,
13766f03f0e8SSrujana Challa .ivsize = 0,
13776f03f0e8SSrujana Challa .setkey = otx2_cpt_skcipher_ecb_des3_setkey,
13786f03f0e8SSrujana Challa .encrypt = otx2_cpt_skcipher_encrypt,
13796f03f0e8SSrujana Challa .decrypt = otx2_cpt_skcipher_decrypt,
13806f03f0e8SSrujana Challa } };
13816f03f0e8SSrujana Challa
13826f03f0e8SSrujana Challa static struct aead_alg otx2_cpt_aeads[] = { {
13836f03f0e8SSrujana Challa .base = {
13846f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha1),cbc(aes))",
13856f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha1_cbc_aes",
13866f03f0e8SSrujana Challa .cra_blocksize = AES_BLOCK_SIZE,
13876f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1388d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
13896f03f0e8SSrujana Challa .cra_priority = 4001,
13906f03f0e8SSrujana Challa .cra_alignmask = 0,
13916f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
13926f03f0e8SSrujana Challa },
13936f03f0e8SSrujana Challa .init = otx2_cpt_aead_cbc_aes_sha1_init,
13946f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
13956f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_cbc_aes_sha_setkey,
13966f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_set_authsize,
13976f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_encrypt,
13986f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_decrypt,
13996f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
14006f03f0e8SSrujana Challa .maxauthsize = SHA1_DIGEST_SIZE,
14016f03f0e8SSrujana Challa }, {
14026f03f0e8SSrujana Challa .base = {
14036f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha256),cbc(aes))",
14046f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha256_cbc_aes",
14056f03f0e8SSrujana Challa .cra_blocksize = AES_BLOCK_SIZE,
14066f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1407d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
14086f03f0e8SSrujana Challa .cra_priority = 4001,
14096f03f0e8SSrujana Challa .cra_alignmask = 0,
14106f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
14116f03f0e8SSrujana Challa },
14126f03f0e8SSrujana Challa .init = otx2_cpt_aead_cbc_aes_sha256_init,
14136f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
14146f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_cbc_aes_sha_setkey,
14156f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_set_authsize,
14166f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_encrypt,
14176f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_decrypt,
14186f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
14196f03f0e8SSrujana Challa .maxauthsize = SHA256_DIGEST_SIZE,
14206f03f0e8SSrujana Challa }, {
14216f03f0e8SSrujana Challa .base = {
14226f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha384),cbc(aes))",
14236f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha384_cbc_aes",
14246f03f0e8SSrujana Challa .cra_blocksize = AES_BLOCK_SIZE,
14256f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1426d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
14276f03f0e8SSrujana Challa .cra_priority = 4001,
14286f03f0e8SSrujana Challa .cra_alignmask = 0,
14296f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
14306f03f0e8SSrujana Challa },
14316f03f0e8SSrujana Challa .init = otx2_cpt_aead_cbc_aes_sha384_init,
14326f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
14336f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_cbc_aes_sha_setkey,
14346f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_set_authsize,
14356f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_encrypt,
14366f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_decrypt,
14376f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
14386f03f0e8SSrujana Challa .maxauthsize = SHA384_DIGEST_SIZE,
14396f03f0e8SSrujana Challa }, {
14406f03f0e8SSrujana Challa .base = {
14416f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha512),cbc(aes))",
14426f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha512_cbc_aes",
14436f03f0e8SSrujana Challa .cra_blocksize = AES_BLOCK_SIZE,
14446f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1445d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
14466f03f0e8SSrujana Challa .cra_priority = 4001,
14476f03f0e8SSrujana Challa .cra_alignmask = 0,
14486f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
14496f03f0e8SSrujana Challa },
14506f03f0e8SSrujana Challa .init = otx2_cpt_aead_cbc_aes_sha512_init,
14516f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
14526f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_cbc_aes_sha_setkey,
14536f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_set_authsize,
14546f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_encrypt,
14556f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_decrypt,
14566f03f0e8SSrujana Challa .ivsize = AES_BLOCK_SIZE,
14576f03f0e8SSrujana Challa .maxauthsize = SHA512_DIGEST_SIZE,
14586f03f0e8SSrujana Challa }, {
14596f03f0e8SSrujana Challa .base = {
14606f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha1),ecb(cipher_null))",
14616f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha1_ecb_null",
14626f03f0e8SSrujana Challa .cra_blocksize = 1,
14636f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC,
1464d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
14656f03f0e8SSrujana Challa .cra_priority = 4001,
14666f03f0e8SSrujana Challa .cra_alignmask = 0,
14676f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
14686f03f0e8SSrujana Challa },
14696f03f0e8SSrujana Challa .init = otx2_cpt_aead_ecb_null_sha1_init,
14706f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
14716f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_ecb_null_sha_setkey,
14726f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_null_set_authsize,
14736f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_null_encrypt,
14746f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_null_decrypt,
14756f03f0e8SSrujana Challa .ivsize = 0,
14766f03f0e8SSrujana Challa .maxauthsize = SHA1_DIGEST_SIZE,
14776f03f0e8SSrujana Challa }, {
14786f03f0e8SSrujana Challa .base = {
14796f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha256),ecb(cipher_null))",
14806f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha256_ecb_null",
14816f03f0e8SSrujana Challa .cra_blocksize = 1,
14826f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC,
1483d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
14846f03f0e8SSrujana Challa .cra_priority = 4001,
14856f03f0e8SSrujana Challa .cra_alignmask = 0,
14866f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
14876f03f0e8SSrujana Challa },
14886f03f0e8SSrujana Challa .init = otx2_cpt_aead_ecb_null_sha256_init,
14896f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
14906f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_ecb_null_sha_setkey,
14916f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_null_set_authsize,
14926f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_null_encrypt,
14936f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_null_decrypt,
14946f03f0e8SSrujana Challa .ivsize = 0,
14956f03f0e8SSrujana Challa .maxauthsize = SHA256_DIGEST_SIZE,
14966f03f0e8SSrujana Challa }, {
14976f03f0e8SSrujana Challa .base = {
14986f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha384),ecb(cipher_null))",
14996f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha384_ecb_null",
15006f03f0e8SSrujana Challa .cra_blocksize = 1,
15016f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC,
1502d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
15036f03f0e8SSrujana Challa .cra_priority = 4001,
15046f03f0e8SSrujana Challa .cra_alignmask = 0,
15056f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
15066f03f0e8SSrujana Challa },
15076f03f0e8SSrujana Challa .init = otx2_cpt_aead_ecb_null_sha384_init,
15086f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
15096f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_ecb_null_sha_setkey,
15106f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_null_set_authsize,
15116f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_null_encrypt,
15126f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_null_decrypt,
15136f03f0e8SSrujana Challa .ivsize = 0,
15146f03f0e8SSrujana Challa .maxauthsize = SHA384_DIGEST_SIZE,
15156f03f0e8SSrujana Challa }, {
15166f03f0e8SSrujana Challa .base = {
15176f03f0e8SSrujana Challa .cra_name = "authenc(hmac(sha512),ecb(cipher_null))",
15186f03f0e8SSrujana Challa .cra_driver_name = "cpt_hmac_sha512_ecb_null",
15196f03f0e8SSrujana Challa .cra_blocksize = 1,
15206f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC,
1521d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
15226f03f0e8SSrujana Challa .cra_priority = 4001,
15236f03f0e8SSrujana Challa .cra_alignmask = 0,
15246f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
15256f03f0e8SSrujana Challa },
15266f03f0e8SSrujana Challa .init = otx2_cpt_aead_ecb_null_sha512_init,
15276f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
15286f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_ecb_null_sha_setkey,
15296f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_null_set_authsize,
15306f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_null_encrypt,
15316f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_null_decrypt,
15326f03f0e8SSrujana Challa .ivsize = 0,
15336f03f0e8SSrujana Challa .maxauthsize = SHA512_DIGEST_SIZE,
15346f03f0e8SSrujana Challa }, {
15356f03f0e8SSrujana Challa .base = {
15366f03f0e8SSrujana Challa .cra_name = "rfc4106(gcm(aes))",
15376f03f0e8SSrujana Challa .cra_driver_name = "cpt_rfc4106_gcm_aes",
15386f03f0e8SSrujana Challa .cra_blocksize = 1,
15396f03f0e8SSrujana Challa .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1540d887dec1SHerbert Xu .cra_ctxsize = sizeof(struct otx2_cpt_aead_ctx) + CRYPTO_DMA_PADDING,
15416f03f0e8SSrujana Challa .cra_priority = 4001,
15426f03f0e8SSrujana Challa .cra_alignmask = 0,
15436f03f0e8SSrujana Challa .cra_module = THIS_MODULE,
15446f03f0e8SSrujana Challa },
15456f03f0e8SSrujana Challa .init = otx2_cpt_aead_gcm_aes_init,
15466f03f0e8SSrujana Challa .exit = otx2_cpt_aead_exit,
15476f03f0e8SSrujana Challa .setkey = otx2_cpt_aead_gcm_aes_setkey,
15486f03f0e8SSrujana Challa .setauthsize = otx2_cpt_aead_gcm_set_authsize,
15496f03f0e8SSrujana Challa .encrypt = otx2_cpt_aead_encrypt,
15506f03f0e8SSrujana Challa .decrypt = otx2_cpt_aead_decrypt,
15516f03f0e8SSrujana Challa .ivsize = AES_GCM_IV_SIZE,
15526f03f0e8SSrujana Challa .maxauthsize = AES_GCM_ICV_SIZE,
15536f03f0e8SSrujana Challa } };
15546f03f0e8SSrujana Challa
cpt_register_algs(void)15556f03f0e8SSrujana Challa static inline int cpt_register_algs(void)
15566f03f0e8SSrujana Challa {
15576f03f0e8SSrujana Challa int i, err = 0;
15586f03f0e8SSrujana Challa
15596f03f0e8SSrujana Challa for (i = 0; i < ARRAY_SIZE(otx2_cpt_skciphers); i++)
15602d841af2SShijith Thotton otx2_cpt_skciphers[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;
15616f03f0e8SSrujana Challa
15626f03f0e8SSrujana Challa err = crypto_register_skciphers(otx2_cpt_skciphers,
15636f03f0e8SSrujana Challa ARRAY_SIZE(otx2_cpt_skciphers));
15646f03f0e8SSrujana Challa if (err)
15656f03f0e8SSrujana Challa return err;
15666f03f0e8SSrujana Challa
15676f03f0e8SSrujana Challa for (i = 0; i < ARRAY_SIZE(otx2_cpt_aeads); i++)
15686f03f0e8SSrujana Challa otx2_cpt_aeads[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;
15696f03f0e8SSrujana Challa
15706f03f0e8SSrujana Challa err = crypto_register_aeads(otx2_cpt_aeads,
15716f03f0e8SSrujana Challa ARRAY_SIZE(otx2_cpt_aeads));
15726f03f0e8SSrujana Challa if (err) {
15736f03f0e8SSrujana Challa crypto_unregister_skciphers(otx2_cpt_skciphers,
15746f03f0e8SSrujana Challa ARRAY_SIZE(otx2_cpt_skciphers));
15756f03f0e8SSrujana Challa return err;
15766f03f0e8SSrujana Challa }
15776f03f0e8SSrujana Challa
15786f03f0e8SSrujana Challa return 0;
15796f03f0e8SSrujana Challa }
15806f03f0e8SSrujana Challa
cpt_unregister_algs(void)15816f03f0e8SSrujana Challa static inline void cpt_unregister_algs(void)
15826f03f0e8SSrujana Challa {
15836f03f0e8SSrujana Challa crypto_unregister_skciphers(otx2_cpt_skciphers,
15846f03f0e8SSrujana Challa ARRAY_SIZE(otx2_cpt_skciphers));
15856f03f0e8SSrujana Challa crypto_unregister_aeads(otx2_cpt_aeads, ARRAY_SIZE(otx2_cpt_aeads));
15866f03f0e8SSrujana Challa }
15876f03f0e8SSrujana Challa
compare_func(const void * lptr,const void * rptr)15886f03f0e8SSrujana Challa static int compare_func(const void *lptr, const void *rptr)
15896f03f0e8SSrujana Challa {
15906f03f0e8SSrujana Challa const struct cpt_device_desc *ldesc = (struct cpt_device_desc *) lptr;
15916f03f0e8SSrujana Challa const struct cpt_device_desc *rdesc = (struct cpt_device_desc *) rptr;
15926f03f0e8SSrujana Challa
15936f03f0e8SSrujana Challa if (ldesc->dev->devfn < rdesc->dev->devfn)
15946f03f0e8SSrujana Challa return -1;
15956f03f0e8SSrujana Challa if (ldesc->dev->devfn > rdesc->dev->devfn)
15966f03f0e8SSrujana Challa return 1;
15976f03f0e8SSrujana Challa return 0;
15986f03f0e8SSrujana Challa }
15996f03f0e8SSrujana Challa
swap_func(void * lptr,void * rptr,int size)16006f03f0e8SSrujana Challa static void swap_func(void *lptr, void *rptr, int size)
16016f03f0e8SSrujana Challa {
16026f03f0e8SSrujana Challa struct cpt_device_desc *ldesc = lptr;
16036f03f0e8SSrujana Challa struct cpt_device_desc *rdesc = rptr;
16046f03f0e8SSrujana Challa
16053121d5d1Schiminghao swap(*ldesc, *rdesc);
16066f03f0e8SSrujana Challa }
16076f03f0e8SSrujana Challa
otx2_cpt_crypto_init(struct pci_dev * pdev,struct module * mod,int num_queues,int num_devices)16086f03f0e8SSrujana Challa int otx2_cpt_crypto_init(struct pci_dev *pdev, struct module *mod,
16096f03f0e8SSrujana Challa int num_queues, int num_devices)
16106f03f0e8SSrujana Challa {
16116f03f0e8SSrujana Challa int ret = 0;
16126f03f0e8SSrujana Challa int count;
16136f03f0e8SSrujana Challa
16146f03f0e8SSrujana Challa mutex_lock(&mutex);
16156f03f0e8SSrujana Challa count = atomic_read(&se_devices.count);
16166f03f0e8SSrujana Challa if (count >= OTX2_CPT_MAX_LFS_NUM) {
16176f03f0e8SSrujana Challa dev_err(&pdev->dev, "No space to add a new device\n");
16186f03f0e8SSrujana Challa ret = -ENOSPC;
16196f03f0e8SSrujana Challa goto unlock;
16206f03f0e8SSrujana Challa }
16216f03f0e8SSrujana Challa se_devices.desc[count].num_queues = num_queues;
16226f03f0e8SSrujana Challa se_devices.desc[count++].dev = pdev;
16236f03f0e8SSrujana Challa atomic_inc(&se_devices.count);
16246f03f0e8SSrujana Challa
16256f03f0e8SSrujana Challa if (atomic_read(&se_devices.count) == num_devices &&
16266f03f0e8SSrujana Challa is_crypto_registered == false) {
16276f03f0e8SSrujana Challa if (cpt_register_algs()) {
16286f03f0e8SSrujana Challa dev_err(&pdev->dev,
16296f03f0e8SSrujana Challa "Error in registering crypto algorithms\n");
16306f03f0e8SSrujana Challa ret = -EINVAL;
16316f03f0e8SSrujana Challa goto unlock;
16326f03f0e8SSrujana Challa }
16336f03f0e8SSrujana Challa try_module_get(mod);
16346f03f0e8SSrujana Challa is_crypto_registered = true;
16356f03f0e8SSrujana Challa }
16366f03f0e8SSrujana Challa sort(se_devices.desc, count, sizeof(struct cpt_device_desc),
16376f03f0e8SSrujana Challa compare_func, swap_func);
16386f03f0e8SSrujana Challa
16396f03f0e8SSrujana Challa unlock:
16406f03f0e8SSrujana Challa mutex_unlock(&mutex);
16416f03f0e8SSrujana Challa return ret;
16426f03f0e8SSrujana Challa }
16436f03f0e8SSrujana Challa
otx2_cpt_crypto_exit(struct pci_dev * pdev,struct module * mod)16446f03f0e8SSrujana Challa void otx2_cpt_crypto_exit(struct pci_dev *pdev, struct module *mod)
16456f03f0e8SSrujana Challa {
16466f03f0e8SSrujana Challa struct cpt_device_table *dev_tbl;
16476f03f0e8SSrujana Challa bool dev_found = false;
16486f03f0e8SSrujana Challa int i, j, count;
16496f03f0e8SSrujana Challa
16506f03f0e8SSrujana Challa mutex_lock(&mutex);
16516f03f0e8SSrujana Challa
16526f03f0e8SSrujana Challa dev_tbl = &se_devices;
16536f03f0e8SSrujana Challa count = atomic_read(&dev_tbl->count);
16546f03f0e8SSrujana Challa for (i = 0; i < count; i++) {
16556f03f0e8SSrujana Challa if (pdev == dev_tbl->desc[i].dev) {
16566f03f0e8SSrujana Challa for (j = i; j < count-1; j++)
16576f03f0e8SSrujana Challa dev_tbl->desc[j] = dev_tbl->desc[j+1];
16586f03f0e8SSrujana Challa dev_found = true;
16596f03f0e8SSrujana Challa break;
16606f03f0e8SSrujana Challa }
16616f03f0e8SSrujana Challa }
16626f03f0e8SSrujana Challa
16636f03f0e8SSrujana Challa if (!dev_found) {
16646f03f0e8SSrujana Challa dev_err(&pdev->dev, "%s device not found\n", __func__);
16656f03f0e8SSrujana Challa goto unlock;
16666f03f0e8SSrujana Challa }
16676f03f0e8SSrujana Challa if (atomic_dec_and_test(&se_devices.count)) {
16686f03f0e8SSrujana Challa cpt_unregister_algs();
16696f03f0e8SSrujana Challa module_put(mod);
16706f03f0e8SSrujana Challa is_crypto_registered = false;
16716f03f0e8SSrujana Challa }
16726f03f0e8SSrujana Challa
16736f03f0e8SSrujana Challa unlock:
16746f03f0e8SSrujana Challa mutex_unlock(&mutex);
16756f03f0e8SSrujana Challa }
1676