Path: blob/master/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
26295 views
// SPDX-License-Identifier: GPL-2.01/* Marvell OcteonTX CPT driver2*3* Copyright (C) 2019 Marvell International Ltd.4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*/910#include <crypto/aes.h>11#include <crypto/authenc.h>12#include <crypto/cryptd.h>13#include <crypto/des.h>14#include <crypto/internal/aead.h>15#include <crypto/sha1.h>16#include <crypto/sha2.h>17#include <crypto/xts.h>18#include <crypto/scatterwalk.h>19#include <linux/sort.h>20#include <linux/module.h>21#include "otx_cptvf.h"22#include "otx_cptvf_algs.h"23#include "otx_cptvf_reqmgr.h"2425#define CPT_MAX_VF_NUM 6426/* Size of salt in AES GCM mode */27#define AES_GCM_SALT_SIZE 428/* Size of IV in AES GCM mode */29#define AES_GCM_IV_SIZE 830/* Size of ICV (Integrity Check Value) in AES GCM mode */31#define AES_GCM_ICV_SIZE 1632/* Offset of IV in AES GCM mode */33#define AES_GCM_IV_OFFSET 834#define CONTROL_WORD_LEN 835#define KEY2_OFFSET 4836#define DMA_MODE_FLAG(dma_mode) \37(((dma_mode) == OTX_CPT_DMA_GATHER_SCATTER) ? (1 << 7) : 0)3839/* Truncated SHA digest size */40#define SHA1_TRUNC_DIGEST_SIZE 1241#define SHA256_TRUNC_DIGEST_SIZE 1642#define SHA384_TRUNC_DIGEST_SIZE 2443#define SHA512_TRUNC_DIGEST_SIZE 324445static DEFINE_MUTEX(mutex);46static int is_crypto_registered;4748struct cpt_device_desc {49enum otx_cptpf_type pf_type;50struct pci_dev *dev;51int num_queues;52};5354struct cpt_device_table {55atomic_t count;56struct cpt_device_desc desc[CPT_MAX_VF_NUM];57};5859static struct cpt_device_table se_devices = {60.count = ATOMIC_INIT(0)61};6263static struct cpt_device_table ae_devices = {64.count = ATOMIC_INIT(0)65};6667static struct otx_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg);6869static inline int get_se_device(struct pci_dev **pdev, int *cpu_num)70{71int count, ret = 0;7273count = atomic_read(&se_devices.count);74if (count < 1)75return -ENODEV;7677*cpu_num = get_cpu();7879if (se_devices.desc[0].pf_type == OTX_CPT_SE) {80/*81* On OcteonTX platform there is one CPT instruction queue bound82* to each VF. We get maximum performance if one CPT queue83* is available for each cpu otherwise CPT queues need to be84* shared between cpus.85*/86if (*cpu_num >= count)87*cpu_num %= count;88*pdev = se_devices.desc[*cpu_num].dev;89} else {90pr_err("Unknown PF type %d\n", se_devices.desc[0].pf_type);91ret = -EINVAL;92}93put_cpu();9495return ret;96}9798static inline int validate_hmac_cipher_null(struct otx_cpt_req_info *cpt_req)99{100struct otx_cpt_req_ctx *rctx;101struct aead_request *req;102struct crypto_aead *tfm;103104req = container_of(cpt_req->areq, struct aead_request, base);105tfm = crypto_aead_reqtfm(req);106rctx = aead_request_ctx_dma(req);107if (memcmp(rctx->fctx.hmac.s.hmac_calc,108rctx->fctx.hmac.s.hmac_recv,109crypto_aead_authsize(tfm)) != 0)110return -EBADMSG;111112return 0;113}114115static void otx_cpt_aead_callback(int status, void *arg1, void *arg2)116{117struct otx_cpt_info_buffer *cpt_info = arg2;118struct crypto_async_request *areq = arg1;119struct otx_cpt_req_info *cpt_req;120struct pci_dev *pdev;121122if (!cpt_info)123goto complete;124125cpt_req = cpt_info->req;126if (!status) {127/*128* When selected cipher is NULL we need to manually129* verify whether calculated hmac value matches130* received hmac value131*/132if (cpt_req->req_type == OTX_CPT_AEAD_ENC_DEC_NULL_REQ &&133!cpt_req->is_enc)134status = validate_hmac_cipher_null(cpt_req);135}136pdev = cpt_info->pdev;137do_request_cleanup(pdev, cpt_info);138139complete:140if (areq)141crypto_request_complete(areq, status);142}143144static void output_iv_copyback(struct crypto_async_request *areq)145{146struct otx_cpt_req_info *req_info;147struct skcipher_request *sreq;148struct crypto_skcipher *stfm;149struct otx_cpt_req_ctx *rctx;150struct otx_cpt_enc_ctx *ctx;151u32 start, ivsize;152153sreq = container_of(areq, struct skcipher_request, base);154stfm = crypto_skcipher_reqtfm(sreq);155ctx = crypto_skcipher_ctx(stfm);156if (ctx->cipher_type == OTX_CPT_AES_CBC ||157ctx->cipher_type == OTX_CPT_DES3_CBC) {158rctx = skcipher_request_ctx_dma(sreq);159req_info = &rctx->cpt_req;160ivsize = crypto_skcipher_ivsize(stfm);161start = sreq->cryptlen - ivsize;162163if (req_info->is_enc) {164scatterwalk_map_and_copy(sreq->iv, sreq->dst, start,165ivsize, 0);166} else {167if (sreq->src != sreq->dst) {168scatterwalk_map_and_copy(sreq->iv, sreq->src,169start, ivsize, 0);170} else {171memcpy(sreq->iv, req_info->iv_out, ivsize);172kfree(req_info->iv_out);173}174}175}176}177178static void otx_cpt_skcipher_callback(int status, void *arg1, void *arg2)179{180struct otx_cpt_info_buffer *cpt_info = arg2;181struct crypto_async_request *areq = arg1;182struct pci_dev *pdev;183184if (areq) {185if (!status)186output_iv_copyback(areq);187if (cpt_info) {188pdev = cpt_info->pdev;189do_request_cleanup(pdev, cpt_info);190}191crypto_request_complete(areq, status);192}193}194195static inline void update_input_data(struct otx_cpt_req_info *req_info,196struct scatterlist *inp_sg,197u32 nbytes, u32 *argcnt)198{199req_info->req.dlen += nbytes;200201while (nbytes) {202u32 len = min(nbytes, inp_sg->length);203u8 *ptr = sg_virt(inp_sg);204205req_info->in[*argcnt].vptr = (void *)ptr;206req_info->in[*argcnt].size = len;207nbytes -= len;208++(*argcnt);209inp_sg = sg_next(inp_sg);210}211}212213static inline void update_output_data(struct otx_cpt_req_info *req_info,214struct scatterlist *outp_sg,215u32 offset, u32 nbytes, u32 *argcnt)216{217req_info->rlen += nbytes;218219while (nbytes) {220u32 len = min(nbytes, outp_sg->length - offset);221u8 *ptr = sg_virt(outp_sg);222223req_info->out[*argcnt].vptr = (void *) (ptr + offset);224req_info->out[*argcnt].size = len;225nbytes -= len;226++(*argcnt);227offset = 0;228outp_sg = sg_next(outp_sg);229}230}231232static inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc,233u32 *argcnt)234{235struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req);236struct otx_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);237struct otx_cpt_req_info *req_info = &rctx->cpt_req;238struct crypto_tfm *tfm = crypto_skcipher_tfm(stfm);239struct otx_cpt_enc_ctx *ctx = crypto_tfm_ctx(tfm);240struct otx_cpt_fc_ctx *fctx = &rctx->fctx;241int ivsize = crypto_skcipher_ivsize(stfm);242u32 start = req->cryptlen - ivsize;243gfp_t flags;244245flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?246GFP_KERNEL : GFP_ATOMIC;247req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER;248req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ;249250req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_FC |251DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER);252if (enc) {253req_info->req.opcode.s.minor = 2;254} else {255req_info->req.opcode.s.minor = 3;256if ((ctx->cipher_type == OTX_CPT_AES_CBC ||257ctx->cipher_type == OTX_CPT_DES3_CBC) &&258req->src == req->dst) {259req_info->iv_out = kmalloc(ivsize, flags);260if (!req_info->iv_out)261return -ENOMEM;262263scatterwalk_map_and_copy(req_info->iv_out, req->src,264start, ivsize, 0);265}266}267/* Encryption data length */268req_info->req.param1 = req->cryptlen;269/* Authentication data length */270req_info->req.param2 = 0;271272fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;273fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;274fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_CPTR;275276if (ctx->cipher_type == OTX_CPT_AES_XTS)277memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);278else279memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);280281memcpy(fctx->enc.encr_iv, req->iv, crypto_skcipher_ivsize(stfm));282283fctx->enc.enc_ctrl.flags = cpu_to_be64(fctx->enc.enc_ctrl.cflags);284285/*286* Storing Packet Data Information in offset287* Control Word First 8 bytes288*/289req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word;290req_info->in[*argcnt].size = CONTROL_WORD_LEN;291req_info->req.dlen += CONTROL_WORD_LEN;292++(*argcnt);293294req_info->in[*argcnt].vptr = (u8 *)fctx;295req_info->in[*argcnt].size = sizeof(struct otx_cpt_fc_ctx);296req_info->req.dlen += sizeof(struct otx_cpt_fc_ctx);297298++(*argcnt);299300return 0;301}302303static inline u32 create_input_list(struct skcipher_request *req, u32 enc,304u32 enc_iv_len)305{306struct otx_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);307struct otx_cpt_req_info *req_info = &rctx->cpt_req;308u32 argcnt = 0;309int ret;310311ret = create_ctx_hdr(req, enc, &argcnt);312if (ret)313return ret;314315update_input_data(req_info, req->src, req->cryptlen, &argcnt);316req_info->incnt = argcnt;317318return 0;319}320321static inline void create_output_list(struct skcipher_request *req,322u32 enc_iv_len)323{324struct otx_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);325struct otx_cpt_req_info *req_info = &rctx->cpt_req;326u32 argcnt = 0;327328/*329* OUTPUT Buffer Processing330* AES encryption/decryption output would be331* received in the following format332*333* ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|334* [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]335*/336update_output_data(req_info, req->dst, 0, req->cryptlen, &argcnt);337req_info->outcnt = argcnt;338}339340static inline int cpt_enc_dec(struct skcipher_request *req, u32 enc)341{342struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req);343struct otx_cpt_req_ctx *rctx = skcipher_request_ctx_dma(req);344struct otx_cpt_req_info *req_info = &rctx->cpt_req;345u32 enc_iv_len = crypto_skcipher_ivsize(stfm);346struct pci_dev *pdev;347int status, cpu_num;348349/* Validate that request doesn't exceed maximum CPT supported size */350if (req->cryptlen > OTX_CPT_MAX_REQ_SIZE)351return -E2BIG;352353/* Clear control words */354rctx->ctrl_word.flags = 0;355rctx->fctx.enc.enc_ctrl.flags = 0;356357status = create_input_list(req, enc, enc_iv_len);358if (status)359return status;360create_output_list(req, enc_iv_len);361362status = get_se_device(&pdev, &cpu_num);363if (status)364return status;365366req_info->callback = (void *)otx_cpt_skcipher_callback;367req_info->areq = &req->base;368req_info->req_type = OTX_CPT_ENC_DEC_REQ;369req_info->is_enc = enc;370req_info->is_trunc_hmac = false;371req_info->ctrl.s.grp = 0;372373/*374* We perform an asynchronous send and once375* the request is completed the driver would376* intimate through registered call back functions377*/378status = otx_cpt_do_request(pdev, req_info, cpu_num);379380return status;381}382383static int otx_cpt_skcipher_encrypt(struct skcipher_request *req)384{385return cpt_enc_dec(req, true);386}387388static int otx_cpt_skcipher_decrypt(struct skcipher_request *req)389{390return cpt_enc_dec(req, false);391}392393static int otx_cpt_skcipher_xts_setkey(struct crypto_skcipher *tfm,394const u8 *key, u32 keylen)395{396struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);397const u8 *key2 = key + (keylen / 2);398const u8 *key1 = key;399int ret;400401ret = xts_verify_key(tfm, key, keylen);402if (ret)403return ret;404ctx->key_len = keylen;405memcpy(ctx->enc_key, key1, keylen / 2);406memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);407ctx->cipher_type = OTX_CPT_AES_XTS;408switch (ctx->key_len) {409case 2 * AES_KEYSIZE_128:410ctx->key_type = OTX_CPT_AES_128_BIT;411break;412case 2 * AES_KEYSIZE_256:413ctx->key_type = OTX_CPT_AES_256_BIT;414break;415default:416return -EINVAL;417}418419return 0;420}421422static int cpt_des_setkey(struct crypto_skcipher *tfm, const u8 *key,423u32 keylen, u8 cipher_type)424{425struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);426427if (keylen != DES3_EDE_KEY_SIZE)428return -EINVAL;429430ctx->key_len = keylen;431ctx->cipher_type = cipher_type;432433memcpy(ctx->enc_key, key, keylen);434435return 0;436}437438static int cpt_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,439u32 keylen, u8 cipher_type)440{441struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);442443switch (keylen) {444case AES_KEYSIZE_128:445ctx->key_type = OTX_CPT_AES_128_BIT;446break;447case AES_KEYSIZE_192:448ctx->key_type = OTX_CPT_AES_192_BIT;449break;450case AES_KEYSIZE_256:451ctx->key_type = OTX_CPT_AES_256_BIT;452break;453default:454return -EINVAL;455}456ctx->key_len = keylen;457ctx->cipher_type = cipher_type;458459memcpy(ctx->enc_key, key, keylen);460461return 0;462}463464static int otx_cpt_skcipher_cbc_aes_setkey(struct crypto_skcipher *tfm,465const u8 *key, u32 keylen)466{467return cpt_aes_setkey(tfm, key, keylen, OTX_CPT_AES_CBC);468}469470static int otx_cpt_skcipher_ecb_aes_setkey(struct crypto_skcipher *tfm,471const u8 *key, u32 keylen)472{473return cpt_aes_setkey(tfm, key, keylen, OTX_CPT_AES_ECB);474}475476static int otx_cpt_skcipher_cbc_des3_setkey(struct crypto_skcipher *tfm,477const u8 *key, u32 keylen)478{479return cpt_des_setkey(tfm, key, keylen, OTX_CPT_DES3_CBC);480}481482static int otx_cpt_skcipher_ecb_des3_setkey(struct crypto_skcipher *tfm,483const u8 *key, u32 keylen)484{485return cpt_des_setkey(tfm, key, keylen, OTX_CPT_DES3_ECB);486}487488static int otx_cpt_enc_dec_init(struct crypto_skcipher *tfm)489{490struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm);491492memset(ctx, 0, sizeof(*ctx));493/*494* Additional memory for skcipher_request is495* allocated since the cryptd daemon uses496* this memory for request_ctx information497*/498crypto_skcipher_set_reqsize_dma(499tfm, sizeof(struct otx_cpt_req_ctx) +500sizeof(struct skcipher_request));501502return 0;503}504505static int cpt_aead_init(struct crypto_aead *tfm, u8 cipher_type, u8 mac_type)506{507struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);508509ctx->cipher_type = cipher_type;510ctx->mac_type = mac_type;511512switch (ctx->mac_type) {513case OTX_CPT_SHA1:514ctx->hashalg = crypto_alloc_shash("sha1", 0, 0);515break;516517case OTX_CPT_SHA256:518ctx->hashalg = crypto_alloc_shash("sha256", 0, 0);519break;520521case OTX_CPT_SHA384:522ctx->hashalg = crypto_alloc_shash("sha384", 0, 0);523break;524525case OTX_CPT_SHA512:526ctx->hashalg = crypto_alloc_shash("sha512", 0, 0);527break;528}529530if (IS_ERR(ctx->hashalg))531return PTR_ERR(ctx->hashalg);532533crypto_aead_set_reqsize_dma(tfm, sizeof(struct otx_cpt_req_ctx));534535if (!ctx->hashalg)536return 0;537538/*539* When selected cipher is NULL we use HMAC opcode instead of540* FLEXICRYPTO opcode therefore we don't need to use HASH algorithms541* for calculating ipad and opad542*/543if (ctx->cipher_type != OTX_CPT_CIPHER_NULL) {544int ss = crypto_shash_statesize(ctx->hashalg);545546ctx->ipad = kzalloc(ss, GFP_KERNEL);547if (!ctx->ipad) {548crypto_free_shash(ctx->hashalg);549return -ENOMEM;550}551552ctx->opad = kzalloc(ss, GFP_KERNEL);553if (!ctx->opad) {554kfree(ctx->ipad);555crypto_free_shash(ctx->hashalg);556return -ENOMEM;557}558}559560ctx->sdesc = alloc_sdesc(ctx->hashalg);561if (!ctx->sdesc) {562kfree(ctx->opad);563kfree(ctx->ipad);564crypto_free_shash(ctx->hashalg);565return -ENOMEM;566}567568return 0;569}570571static int otx_cpt_aead_cbc_aes_sha1_init(struct crypto_aead *tfm)572{573return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA1);574}575576static int otx_cpt_aead_cbc_aes_sha256_init(struct crypto_aead *tfm)577{578return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA256);579}580581static int otx_cpt_aead_cbc_aes_sha384_init(struct crypto_aead *tfm)582{583return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA384);584}585586static int otx_cpt_aead_cbc_aes_sha512_init(struct crypto_aead *tfm)587{588return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA512);589}590591static int otx_cpt_aead_ecb_null_sha1_init(struct crypto_aead *tfm)592{593return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA1);594}595596static int otx_cpt_aead_ecb_null_sha256_init(struct crypto_aead *tfm)597{598return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA256);599}600601static int otx_cpt_aead_ecb_null_sha384_init(struct crypto_aead *tfm)602{603return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA384);604}605606static int otx_cpt_aead_ecb_null_sha512_init(struct crypto_aead *tfm)607{608return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA512);609}610611static int otx_cpt_aead_gcm_aes_init(struct crypto_aead *tfm)612{613return cpt_aead_init(tfm, OTX_CPT_AES_GCM, OTX_CPT_MAC_NULL);614}615616static void otx_cpt_aead_exit(struct crypto_aead *tfm)617{618struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);619620kfree(ctx->ipad);621kfree(ctx->opad);622crypto_free_shash(ctx->hashalg);623kfree(ctx->sdesc);624}625626/*627* This is the Integrity Check Value validation (aka the authentication tag628* length)629*/630static int otx_cpt_aead_set_authsize(struct crypto_aead *tfm,631unsigned int authsize)632{633struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);634635switch (ctx->mac_type) {636case OTX_CPT_SHA1:637if (authsize != SHA1_DIGEST_SIZE &&638authsize != SHA1_TRUNC_DIGEST_SIZE)639return -EINVAL;640641if (authsize == SHA1_TRUNC_DIGEST_SIZE)642ctx->is_trunc_hmac = true;643break;644645case OTX_CPT_SHA256:646if (authsize != SHA256_DIGEST_SIZE &&647authsize != SHA256_TRUNC_DIGEST_SIZE)648return -EINVAL;649650if (authsize == SHA256_TRUNC_DIGEST_SIZE)651ctx->is_trunc_hmac = true;652break;653654case OTX_CPT_SHA384:655if (authsize != SHA384_DIGEST_SIZE &&656authsize != SHA384_TRUNC_DIGEST_SIZE)657return -EINVAL;658659if (authsize == SHA384_TRUNC_DIGEST_SIZE)660ctx->is_trunc_hmac = true;661break;662663case OTX_CPT_SHA512:664if (authsize != SHA512_DIGEST_SIZE &&665authsize != SHA512_TRUNC_DIGEST_SIZE)666return -EINVAL;667668if (authsize == SHA512_TRUNC_DIGEST_SIZE)669ctx->is_trunc_hmac = true;670break;671672case OTX_CPT_MAC_NULL:673if (ctx->cipher_type == OTX_CPT_AES_GCM) {674if (authsize != AES_GCM_ICV_SIZE)675return -EINVAL;676} else677return -EINVAL;678break;679680default:681return -EINVAL;682}683684tfm->authsize = authsize;685return 0;686}687688static struct otx_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg)689{690struct otx_cpt_sdesc *sdesc;691int size;692693size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);694sdesc = kmalloc(size, GFP_KERNEL);695if (!sdesc)696return NULL;697698sdesc->shash.tfm = alg;699700return sdesc;701}702703static inline void swap_data32(void *buf, u32 len)704{705cpu_to_be32_array(buf, buf, len / 4);706}707708static inline void swap_data64(void *buf, u32 len)709{710__be64 *dst = buf;711u64 *src = buf;712int i = 0;713714for (i = 0 ; i < len / 8; i++, src++, dst++)715*dst = cpu_to_be64p(src);716}717718static int swap_pad(u8 mac_type, u8 *pad)719{720struct sha512_state *sha512;721struct sha256_state *sha256;722struct sha1_state *sha1;723724switch (mac_type) {725case OTX_CPT_SHA1:726sha1 = (struct sha1_state *)pad;727swap_data32(sha1->state, SHA1_DIGEST_SIZE);728break;729730case OTX_CPT_SHA256:731sha256 = (struct sha256_state *)pad;732swap_data32(sha256->state, SHA256_DIGEST_SIZE);733break;734735case OTX_CPT_SHA384:736case OTX_CPT_SHA512:737sha512 = (struct sha512_state *)pad;738swap_data64(sha512->state, SHA512_DIGEST_SIZE);739break;740741default:742return -EINVAL;743}744745return 0;746}747748static int aead_hmac_init(struct crypto_aead *cipher,749struct crypto_authenc_keys *keys)750{751struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);752int ds = crypto_shash_digestsize(ctx->hashalg);753int bs = crypto_shash_blocksize(ctx->hashalg);754int authkeylen = keys->authkeylen;755u8 *ipad = NULL, *opad = NULL;756int icount = 0;757int ret;758759if (authkeylen > bs) {760ret = crypto_shash_digest(&ctx->sdesc->shash, keys->authkey,761authkeylen, ctx->key);762if (ret)763return ret;764authkeylen = ds;765} else766memcpy(ctx->key, keys->authkey, authkeylen);767768ctx->enc_key_len = keys->enckeylen;769ctx->auth_key_len = authkeylen;770771if (ctx->cipher_type == OTX_CPT_CIPHER_NULL)772return keys->enckeylen ? -EINVAL : 0;773774switch (keys->enckeylen) {775case AES_KEYSIZE_128:776ctx->key_type = OTX_CPT_AES_128_BIT;777break;778case AES_KEYSIZE_192:779ctx->key_type = OTX_CPT_AES_192_BIT;780break;781case AES_KEYSIZE_256:782ctx->key_type = OTX_CPT_AES_256_BIT;783break;784default:785/* Invalid key length */786return -EINVAL;787}788789memcpy(ctx->key + authkeylen, keys->enckey, keys->enckeylen);790791ipad = ctx->ipad;792opad = ctx->opad;793794memcpy(ipad, ctx->key, authkeylen);795memset(ipad + authkeylen, 0, bs - authkeylen);796memcpy(opad, ipad, bs);797798for (icount = 0; icount < bs; icount++) {799ipad[icount] ^= 0x36;800opad[icount] ^= 0x5c;801}802803/*804* Partial Hash calculated from the software805* algorithm is retrieved for IPAD & OPAD806*/807808/* IPAD Calculation */809crypto_shash_init(&ctx->sdesc->shash);810crypto_shash_update(&ctx->sdesc->shash, ipad, bs);811crypto_shash_export(&ctx->sdesc->shash, ipad);812ret = swap_pad(ctx->mac_type, ipad);813if (ret)814goto calc_fail;815816/* OPAD Calculation */817crypto_shash_init(&ctx->sdesc->shash);818crypto_shash_update(&ctx->sdesc->shash, opad, bs);819crypto_shash_export(&ctx->sdesc->shash, opad);820ret = swap_pad(ctx->mac_type, opad);821822calc_fail:823return ret;824}825826static int otx_cpt_aead_cbc_aes_sha_setkey(struct crypto_aead *cipher,827const unsigned char *key,828unsigned int keylen)829{830struct crypto_authenc_keys authenc_keys;831int status;832833status = crypto_authenc_extractkeys(&authenc_keys, key, keylen);834if (status)835goto badkey;836837status = aead_hmac_init(cipher, &authenc_keys);838839badkey:840return status;841}842843static int otx_cpt_aead_ecb_null_sha_setkey(struct crypto_aead *cipher,844const unsigned char *key,845unsigned int keylen)846{847return otx_cpt_aead_cbc_aes_sha_setkey(cipher, key, keylen);848}849850static int otx_cpt_aead_gcm_aes_setkey(struct crypto_aead *cipher,851const unsigned char *key,852unsigned int keylen)853{854struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);855856/*857* For aes gcm we expect to get encryption key (16, 24, 32 bytes)858* and salt (4 bytes)859*/860switch (keylen) {861case AES_KEYSIZE_128 + AES_GCM_SALT_SIZE:862ctx->key_type = OTX_CPT_AES_128_BIT;863ctx->enc_key_len = AES_KEYSIZE_128;864break;865case AES_KEYSIZE_192 + AES_GCM_SALT_SIZE:866ctx->key_type = OTX_CPT_AES_192_BIT;867ctx->enc_key_len = AES_KEYSIZE_192;868break;869case AES_KEYSIZE_256 + AES_GCM_SALT_SIZE:870ctx->key_type = OTX_CPT_AES_256_BIT;871ctx->enc_key_len = AES_KEYSIZE_256;872break;873default:874/* Invalid key and salt length */875return -EINVAL;876}877878/* Store encryption key and salt */879memcpy(ctx->key, key, keylen);880881return 0;882}883884static inline u32 create_aead_ctx_hdr(struct aead_request *req, u32 enc,885u32 *argcnt)886{887struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);888struct crypto_aead *tfm = crypto_aead_reqtfm(req);889struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);890struct otx_cpt_req_info *req_info = &rctx->cpt_req;891struct otx_cpt_fc_ctx *fctx = &rctx->fctx;892int mac_len = crypto_aead_authsize(tfm);893int ds;894895rctx->ctrl_word.e.enc_data_offset = req->assoclen;896897switch (ctx->cipher_type) {898case OTX_CPT_AES_CBC:899fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_CPTR;900/* Copy encryption key to context */901memcpy(fctx->enc.encr_key, ctx->key + ctx->auth_key_len,902ctx->enc_key_len);903/* Copy IV to context */904memcpy(fctx->enc.encr_iv, req->iv, crypto_aead_ivsize(tfm));905906ds = crypto_shash_digestsize(ctx->hashalg);907if (ctx->mac_type == OTX_CPT_SHA384)908ds = SHA512_DIGEST_SIZE;909if (ctx->ipad)910memcpy(fctx->hmac.e.ipad, ctx->ipad, ds);911if (ctx->opad)912memcpy(fctx->hmac.e.opad, ctx->opad, ds);913break;914915case OTX_CPT_AES_GCM:916fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_DPTR;917/* Copy encryption key to context */918memcpy(fctx->enc.encr_key, ctx->key, ctx->enc_key_len);919/* Copy salt to context */920memcpy(fctx->enc.encr_iv, ctx->key + ctx->enc_key_len,921AES_GCM_SALT_SIZE);922923rctx->ctrl_word.e.iv_offset = req->assoclen - AES_GCM_IV_OFFSET;924break;925926default:927/* Unknown cipher type */928return -EINVAL;929}930rctx->ctrl_word.flags = cpu_to_be64(rctx->ctrl_word.cflags);931932req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER;933req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ;934req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_FC |935DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER);936if (enc) {937req_info->req.opcode.s.minor = 2;938req_info->req.param1 = req->cryptlen;939req_info->req.param2 = req->cryptlen + req->assoclen;940} else {941req_info->req.opcode.s.minor = 3;942req_info->req.param1 = req->cryptlen - mac_len;943req_info->req.param2 = req->cryptlen + req->assoclen - mac_len;944}945946fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;947fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;948fctx->enc.enc_ctrl.e.mac_type = ctx->mac_type;949fctx->enc.enc_ctrl.e.mac_len = mac_len;950fctx->enc.enc_ctrl.flags = cpu_to_be64(fctx->enc.enc_ctrl.cflags);951952/*953* Storing Packet Data Information in offset954* Control Word First 8 bytes955*/956req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word;957req_info->in[*argcnt].size = CONTROL_WORD_LEN;958req_info->req.dlen += CONTROL_WORD_LEN;959++(*argcnt);960961req_info->in[*argcnt].vptr = (u8 *)fctx;962req_info->in[*argcnt].size = sizeof(struct otx_cpt_fc_ctx);963req_info->req.dlen += sizeof(struct otx_cpt_fc_ctx);964++(*argcnt);965966return 0;967}968969static inline u32 create_hmac_ctx_hdr(struct aead_request *req, u32 *argcnt,970u32 enc)971{972struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);973struct crypto_aead *tfm = crypto_aead_reqtfm(req);974struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(tfm);975struct otx_cpt_req_info *req_info = &rctx->cpt_req;976977req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER;978req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ;979req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_HMAC |980DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER);981req_info->is_trunc_hmac = ctx->is_trunc_hmac;982983req_info->req.opcode.s.minor = 0;984req_info->req.param1 = ctx->auth_key_len;985req_info->req.param2 = ctx->mac_type << 8;986987/* Add authentication key */988req_info->in[*argcnt].vptr = ctx->key;989req_info->in[*argcnt].size = round_up(ctx->auth_key_len, 8);990req_info->req.dlen += round_up(ctx->auth_key_len, 8);991++(*argcnt);992993return 0;994}995996static inline u32 create_aead_input_list(struct aead_request *req, u32 enc)997{998struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);999struct otx_cpt_req_info *req_info = &rctx->cpt_req;1000u32 inputlen = req->cryptlen + req->assoclen;1001u32 status, argcnt = 0;10021003status = create_aead_ctx_hdr(req, enc, &argcnt);1004if (status)1005return status;1006update_input_data(req_info, req->src, inputlen, &argcnt);1007req_info->incnt = argcnt;10081009return 0;1010}10111012static inline u32 create_aead_output_list(struct aead_request *req, u32 enc,1013u32 mac_len)1014{1015struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);1016struct otx_cpt_req_info *req_info = &rctx->cpt_req;1017u32 argcnt = 0, outputlen = 0;10181019if (enc)1020outputlen = req->cryptlen + req->assoclen + mac_len;1021else1022outputlen = req->cryptlen + req->assoclen - mac_len;10231024update_output_data(req_info, req->dst, 0, outputlen, &argcnt);1025req_info->outcnt = argcnt;10261027return 0;1028}10291030static inline u32 create_aead_null_input_list(struct aead_request *req,1031u32 enc, u32 mac_len)1032{1033struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);1034struct otx_cpt_req_info *req_info = &rctx->cpt_req;1035u32 inputlen, argcnt = 0;10361037if (enc)1038inputlen = req->cryptlen + req->assoclen;1039else1040inputlen = req->cryptlen + req->assoclen - mac_len;10411042create_hmac_ctx_hdr(req, &argcnt, enc);1043update_input_data(req_info, req->src, inputlen, &argcnt);1044req_info->incnt = argcnt;10451046return 0;1047}10481049static inline u32 create_aead_null_output_list(struct aead_request *req,1050u32 enc, u32 mac_len)1051{1052struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);1053struct otx_cpt_req_info *req_info = &rctx->cpt_req;1054struct scatterlist *dst;1055u8 *ptr = NULL;1056int argcnt = 0, status, offset;1057u32 inputlen;10581059if (enc)1060inputlen = req->cryptlen + req->assoclen;1061else1062inputlen = req->cryptlen + req->assoclen - mac_len;10631064/*1065* If source and destination are different1066* then copy payload to destination1067*/1068if (req->src != req->dst) {10691070ptr = kmalloc(inputlen, (req_info->areq->flags &1071CRYPTO_TFM_REQ_MAY_SLEEP) ?1072GFP_KERNEL : GFP_ATOMIC);1073if (!ptr) {1074status = -ENOMEM;1075goto error;1076}10771078status = sg_copy_to_buffer(req->src, sg_nents(req->src), ptr,1079inputlen);1080if (status != inputlen) {1081status = -EINVAL;1082goto error_free;1083}1084status = sg_copy_from_buffer(req->dst, sg_nents(req->dst), ptr,1085inputlen);1086if (status != inputlen) {1087status = -EINVAL;1088goto error_free;1089}1090kfree(ptr);1091}10921093if (enc) {1094/*1095* In an encryption scenario hmac needs1096* to be appended after payload1097*/1098dst = req->dst;1099offset = inputlen;1100while (offset >= dst->length) {1101offset -= dst->length;1102dst = sg_next(dst);1103if (!dst) {1104status = -ENOENT;1105goto error;1106}1107}11081109update_output_data(req_info, dst, offset, mac_len, &argcnt);1110} else {1111/*1112* In a decryption scenario calculated hmac for received1113* payload needs to be compare with hmac received1114*/1115status = sg_copy_buffer(req->src, sg_nents(req->src),1116rctx->fctx.hmac.s.hmac_recv, mac_len,1117inputlen, true);1118if (status != mac_len) {1119status = -EINVAL;1120goto error;1121}11221123req_info->out[argcnt].vptr = rctx->fctx.hmac.s.hmac_calc;1124req_info->out[argcnt].size = mac_len;1125argcnt++;1126}11271128req_info->outcnt = argcnt;1129return 0;11301131error_free:1132kfree(ptr);1133error:1134return status;1135}11361137static u32 cpt_aead_enc_dec(struct aead_request *req, u8 reg_type, u8 enc)1138{1139struct otx_cpt_req_ctx *rctx = aead_request_ctx_dma(req);1140struct otx_cpt_req_info *req_info = &rctx->cpt_req;1141struct crypto_aead *tfm = crypto_aead_reqtfm(req);1142struct pci_dev *pdev;1143u32 status, cpu_num;11441145/* Clear control words */1146rctx->ctrl_word.flags = 0;1147rctx->fctx.enc.enc_ctrl.flags = 0;11481149req_info->callback = otx_cpt_aead_callback;1150req_info->areq = &req->base;1151req_info->req_type = reg_type;1152req_info->is_enc = enc;1153req_info->is_trunc_hmac = false;11541155switch (reg_type) {1156case OTX_CPT_AEAD_ENC_DEC_REQ:1157status = create_aead_input_list(req, enc);1158if (status)1159return status;1160status = create_aead_output_list(req, enc,1161crypto_aead_authsize(tfm));1162if (status)1163return status;1164break;11651166case OTX_CPT_AEAD_ENC_DEC_NULL_REQ:1167status = create_aead_null_input_list(req, enc,1168crypto_aead_authsize(tfm));1169if (status)1170return status;1171status = create_aead_null_output_list(req, enc,1172crypto_aead_authsize(tfm));1173if (status)1174return status;1175break;11761177default:1178return -EINVAL;1179}11801181/* Validate that request doesn't exceed maximum CPT supported size */1182if (req_info->req.param1 > OTX_CPT_MAX_REQ_SIZE ||1183req_info->req.param2 > OTX_CPT_MAX_REQ_SIZE)1184return -E2BIG;11851186status = get_se_device(&pdev, &cpu_num);1187if (status)1188return status;11891190req_info->ctrl.s.grp = 0;11911192status = otx_cpt_do_request(pdev, req_info, cpu_num);1193/*1194* We perform an asynchronous send and once1195* the request is completed the driver would1196* intimate through registered call back functions1197*/1198return status;1199}12001201static int otx_cpt_aead_encrypt(struct aead_request *req)1202{1203return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_REQ, true);1204}12051206static int otx_cpt_aead_decrypt(struct aead_request *req)1207{1208return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_REQ, false);1209}12101211static int otx_cpt_aead_null_encrypt(struct aead_request *req)1212{1213return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_NULL_REQ, true);1214}12151216static int otx_cpt_aead_null_decrypt(struct aead_request *req)1217{1218return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_NULL_REQ, false);1219}12201221static struct skcipher_alg otx_cpt_skciphers[] = { {1222.base.cra_name = "xts(aes)",1223.base.cra_driver_name = "cpt_xts_aes",1224.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1225.base.cra_blocksize = AES_BLOCK_SIZE,1226.base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx),1227.base.cra_alignmask = 7,1228.base.cra_priority = 4001,1229.base.cra_module = THIS_MODULE,12301231.init = otx_cpt_enc_dec_init,1232.ivsize = AES_BLOCK_SIZE,1233.min_keysize = 2 * AES_MIN_KEY_SIZE,1234.max_keysize = 2 * AES_MAX_KEY_SIZE,1235.setkey = otx_cpt_skcipher_xts_setkey,1236.encrypt = otx_cpt_skcipher_encrypt,1237.decrypt = otx_cpt_skcipher_decrypt,1238}, {1239.base.cra_name = "cbc(aes)",1240.base.cra_driver_name = "cpt_cbc_aes",1241.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1242.base.cra_blocksize = AES_BLOCK_SIZE,1243.base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx),1244.base.cra_alignmask = 7,1245.base.cra_priority = 4001,1246.base.cra_module = THIS_MODULE,12471248.init = otx_cpt_enc_dec_init,1249.ivsize = AES_BLOCK_SIZE,1250.min_keysize = AES_MIN_KEY_SIZE,1251.max_keysize = AES_MAX_KEY_SIZE,1252.setkey = otx_cpt_skcipher_cbc_aes_setkey,1253.encrypt = otx_cpt_skcipher_encrypt,1254.decrypt = otx_cpt_skcipher_decrypt,1255}, {1256.base.cra_name = "ecb(aes)",1257.base.cra_driver_name = "cpt_ecb_aes",1258.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1259.base.cra_blocksize = AES_BLOCK_SIZE,1260.base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx),1261.base.cra_alignmask = 7,1262.base.cra_priority = 4001,1263.base.cra_module = THIS_MODULE,12641265.init = otx_cpt_enc_dec_init,1266.ivsize = 0,1267.min_keysize = AES_MIN_KEY_SIZE,1268.max_keysize = AES_MAX_KEY_SIZE,1269.setkey = otx_cpt_skcipher_ecb_aes_setkey,1270.encrypt = otx_cpt_skcipher_encrypt,1271.decrypt = otx_cpt_skcipher_decrypt,1272}, {1273.base.cra_name = "cbc(des3_ede)",1274.base.cra_driver_name = "cpt_cbc_des3_ede",1275.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1276.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,1277.base.cra_ctxsize = sizeof(struct otx_cpt_des3_ctx),1278.base.cra_alignmask = 7,1279.base.cra_priority = 4001,1280.base.cra_module = THIS_MODULE,12811282.init = otx_cpt_enc_dec_init,1283.min_keysize = DES3_EDE_KEY_SIZE,1284.max_keysize = DES3_EDE_KEY_SIZE,1285.ivsize = DES_BLOCK_SIZE,1286.setkey = otx_cpt_skcipher_cbc_des3_setkey,1287.encrypt = otx_cpt_skcipher_encrypt,1288.decrypt = otx_cpt_skcipher_decrypt,1289}, {1290.base.cra_name = "ecb(des3_ede)",1291.base.cra_driver_name = "cpt_ecb_des3_ede",1292.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1293.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,1294.base.cra_ctxsize = sizeof(struct otx_cpt_des3_ctx),1295.base.cra_alignmask = 7,1296.base.cra_priority = 4001,1297.base.cra_module = THIS_MODULE,12981299.init = otx_cpt_enc_dec_init,1300.min_keysize = DES3_EDE_KEY_SIZE,1301.max_keysize = DES3_EDE_KEY_SIZE,1302.ivsize = 0,1303.setkey = otx_cpt_skcipher_ecb_des3_setkey,1304.encrypt = otx_cpt_skcipher_encrypt,1305.decrypt = otx_cpt_skcipher_decrypt,1306} };13071308static struct aead_alg otx_cpt_aeads[] = { {1309.base = {1310.cra_name = "authenc(hmac(sha1),cbc(aes))",1311.cra_driver_name = "cpt_hmac_sha1_cbc_aes",1312.cra_blocksize = AES_BLOCK_SIZE,1313.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1314.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1315.cra_priority = 4001,1316.cra_alignmask = 0,1317.cra_module = THIS_MODULE,1318},1319.init = otx_cpt_aead_cbc_aes_sha1_init,1320.exit = otx_cpt_aead_exit,1321.setkey = otx_cpt_aead_cbc_aes_sha_setkey,1322.setauthsize = otx_cpt_aead_set_authsize,1323.encrypt = otx_cpt_aead_encrypt,1324.decrypt = otx_cpt_aead_decrypt,1325.ivsize = AES_BLOCK_SIZE,1326.maxauthsize = SHA1_DIGEST_SIZE,1327}, {1328.base = {1329.cra_name = "authenc(hmac(sha256),cbc(aes))",1330.cra_driver_name = "cpt_hmac_sha256_cbc_aes",1331.cra_blocksize = AES_BLOCK_SIZE,1332.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1333.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1334.cra_priority = 4001,1335.cra_alignmask = 0,1336.cra_module = THIS_MODULE,1337},1338.init = otx_cpt_aead_cbc_aes_sha256_init,1339.exit = otx_cpt_aead_exit,1340.setkey = otx_cpt_aead_cbc_aes_sha_setkey,1341.setauthsize = otx_cpt_aead_set_authsize,1342.encrypt = otx_cpt_aead_encrypt,1343.decrypt = otx_cpt_aead_decrypt,1344.ivsize = AES_BLOCK_SIZE,1345.maxauthsize = SHA256_DIGEST_SIZE,1346}, {1347.base = {1348.cra_name = "authenc(hmac(sha384),cbc(aes))",1349.cra_driver_name = "cpt_hmac_sha384_cbc_aes",1350.cra_blocksize = AES_BLOCK_SIZE,1351.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1352.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1353.cra_priority = 4001,1354.cra_alignmask = 0,1355.cra_module = THIS_MODULE,1356},1357.init = otx_cpt_aead_cbc_aes_sha384_init,1358.exit = otx_cpt_aead_exit,1359.setkey = otx_cpt_aead_cbc_aes_sha_setkey,1360.setauthsize = otx_cpt_aead_set_authsize,1361.encrypt = otx_cpt_aead_encrypt,1362.decrypt = otx_cpt_aead_decrypt,1363.ivsize = AES_BLOCK_SIZE,1364.maxauthsize = SHA384_DIGEST_SIZE,1365}, {1366.base = {1367.cra_name = "authenc(hmac(sha512),cbc(aes))",1368.cra_driver_name = "cpt_hmac_sha512_cbc_aes",1369.cra_blocksize = AES_BLOCK_SIZE,1370.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1371.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1372.cra_priority = 4001,1373.cra_alignmask = 0,1374.cra_module = THIS_MODULE,1375},1376.init = otx_cpt_aead_cbc_aes_sha512_init,1377.exit = otx_cpt_aead_exit,1378.setkey = otx_cpt_aead_cbc_aes_sha_setkey,1379.setauthsize = otx_cpt_aead_set_authsize,1380.encrypt = otx_cpt_aead_encrypt,1381.decrypt = otx_cpt_aead_decrypt,1382.ivsize = AES_BLOCK_SIZE,1383.maxauthsize = SHA512_DIGEST_SIZE,1384}, {1385.base = {1386.cra_name = "authenc(hmac(sha1),ecb(cipher_null))",1387.cra_driver_name = "cpt_hmac_sha1_ecb_null",1388.cra_blocksize = 1,1389.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1390.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1391.cra_priority = 4001,1392.cra_alignmask = 0,1393.cra_module = THIS_MODULE,1394},1395.init = otx_cpt_aead_ecb_null_sha1_init,1396.exit = otx_cpt_aead_exit,1397.setkey = otx_cpt_aead_ecb_null_sha_setkey,1398.setauthsize = otx_cpt_aead_set_authsize,1399.encrypt = otx_cpt_aead_null_encrypt,1400.decrypt = otx_cpt_aead_null_decrypt,1401.ivsize = 0,1402.maxauthsize = SHA1_DIGEST_SIZE,1403}, {1404.base = {1405.cra_name = "authenc(hmac(sha256),ecb(cipher_null))",1406.cra_driver_name = "cpt_hmac_sha256_ecb_null",1407.cra_blocksize = 1,1408.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1409.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1410.cra_priority = 4001,1411.cra_alignmask = 0,1412.cra_module = THIS_MODULE,1413},1414.init = otx_cpt_aead_ecb_null_sha256_init,1415.exit = otx_cpt_aead_exit,1416.setkey = otx_cpt_aead_ecb_null_sha_setkey,1417.setauthsize = otx_cpt_aead_set_authsize,1418.encrypt = otx_cpt_aead_null_encrypt,1419.decrypt = otx_cpt_aead_null_decrypt,1420.ivsize = 0,1421.maxauthsize = SHA256_DIGEST_SIZE,1422}, {1423.base = {1424.cra_name = "authenc(hmac(sha384),ecb(cipher_null))",1425.cra_driver_name = "cpt_hmac_sha384_ecb_null",1426.cra_blocksize = 1,1427.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1428.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1429.cra_priority = 4001,1430.cra_alignmask = 0,1431.cra_module = THIS_MODULE,1432},1433.init = otx_cpt_aead_ecb_null_sha384_init,1434.exit = otx_cpt_aead_exit,1435.setkey = otx_cpt_aead_ecb_null_sha_setkey,1436.setauthsize = otx_cpt_aead_set_authsize,1437.encrypt = otx_cpt_aead_null_encrypt,1438.decrypt = otx_cpt_aead_null_decrypt,1439.ivsize = 0,1440.maxauthsize = SHA384_DIGEST_SIZE,1441}, {1442.base = {1443.cra_name = "authenc(hmac(sha512),ecb(cipher_null))",1444.cra_driver_name = "cpt_hmac_sha512_ecb_null",1445.cra_blocksize = 1,1446.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1447.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1448.cra_priority = 4001,1449.cra_alignmask = 0,1450.cra_module = THIS_MODULE,1451},1452.init = otx_cpt_aead_ecb_null_sha512_init,1453.exit = otx_cpt_aead_exit,1454.setkey = otx_cpt_aead_ecb_null_sha_setkey,1455.setauthsize = otx_cpt_aead_set_authsize,1456.encrypt = otx_cpt_aead_null_encrypt,1457.decrypt = otx_cpt_aead_null_decrypt,1458.ivsize = 0,1459.maxauthsize = SHA512_DIGEST_SIZE,1460}, {1461.base = {1462.cra_name = "rfc4106(gcm(aes))",1463.cra_driver_name = "cpt_rfc4106_gcm_aes",1464.cra_blocksize = 1,1465.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY,1466.cra_ctxsize = sizeof(struct otx_cpt_aead_ctx) + CRYPTO_DMA_PADDING,1467.cra_priority = 4001,1468.cra_alignmask = 0,1469.cra_module = THIS_MODULE,1470},1471.init = otx_cpt_aead_gcm_aes_init,1472.exit = otx_cpt_aead_exit,1473.setkey = otx_cpt_aead_gcm_aes_setkey,1474.setauthsize = otx_cpt_aead_set_authsize,1475.encrypt = otx_cpt_aead_encrypt,1476.decrypt = otx_cpt_aead_decrypt,1477.ivsize = AES_GCM_IV_SIZE,1478.maxauthsize = AES_GCM_ICV_SIZE,1479} };14801481static inline int is_any_alg_used(void)1482{1483int i;14841485for (i = 0; i < ARRAY_SIZE(otx_cpt_skciphers); i++)1486if (refcount_read(&otx_cpt_skciphers[i].base.cra_refcnt) != 1)1487return true;1488for (i = 0; i < ARRAY_SIZE(otx_cpt_aeads); i++)1489if (refcount_read(&otx_cpt_aeads[i].base.cra_refcnt) != 1)1490return true;1491return false;1492}14931494static inline int cpt_register_algs(void)1495{1496int i, err = 0;14971498if (!IS_ENABLED(CONFIG_DM_CRYPT)) {1499for (i = 0; i < ARRAY_SIZE(otx_cpt_skciphers); i++)1500otx_cpt_skciphers[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;15011502err = crypto_register_skciphers(otx_cpt_skciphers,1503ARRAY_SIZE(otx_cpt_skciphers));1504if (err)1505return err;1506}15071508for (i = 0; i < ARRAY_SIZE(otx_cpt_aeads); i++)1509otx_cpt_aeads[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;15101511err = crypto_register_aeads(otx_cpt_aeads, ARRAY_SIZE(otx_cpt_aeads));1512if (err) {1513crypto_unregister_skciphers(otx_cpt_skciphers,1514ARRAY_SIZE(otx_cpt_skciphers));1515return err;1516}15171518return 0;1519}15201521static inline void cpt_unregister_algs(void)1522{1523crypto_unregister_skciphers(otx_cpt_skciphers,1524ARRAY_SIZE(otx_cpt_skciphers));1525crypto_unregister_aeads(otx_cpt_aeads, ARRAY_SIZE(otx_cpt_aeads));1526}15271528static int compare_func(const void *lptr, const void *rptr)1529{1530struct cpt_device_desc *ldesc = (struct cpt_device_desc *) lptr;1531struct cpt_device_desc *rdesc = (struct cpt_device_desc *) rptr;15321533if (ldesc->dev->devfn < rdesc->dev->devfn)1534return -1;1535if (ldesc->dev->devfn > rdesc->dev->devfn)1536return 1;1537return 0;1538}15391540int otx_cpt_crypto_init(struct pci_dev *pdev, struct module *mod,1541enum otx_cptpf_type pf_type,1542enum otx_cptvf_type engine_type,1543int num_queues, int num_devices)1544{1545int ret = 0;1546int count;15471548mutex_lock(&mutex);1549switch (engine_type) {1550case OTX_CPT_SE_TYPES:1551count = atomic_read(&se_devices.count);1552if (count >= CPT_MAX_VF_NUM) {1553dev_err(&pdev->dev, "No space to add a new device\n");1554ret = -ENOSPC;1555goto err;1556}1557se_devices.desc[count].pf_type = pf_type;1558se_devices.desc[count].num_queues = num_queues;1559se_devices.desc[count++].dev = pdev;1560atomic_inc(&se_devices.count);15611562if (atomic_read(&se_devices.count) == num_devices &&1563is_crypto_registered == false) {1564if (cpt_register_algs()) {1565dev_err(&pdev->dev,1566"Error in registering crypto algorithms\n");1567ret = -EINVAL;1568goto err;1569}1570try_module_get(mod);1571is_crypto_registered = true;1572}1573sort(se_devices.desc, count, sizeof(struct cpt_device_desc),1574compare_func, NULL);1575break;15761577case OTX_CPT_AE_TYPES:1578count = atomic_read(&ae_devices.count);1579if (count >= CPT_MAX_VF_NUM) {1580dev_err(&pdev->dev, "No space to a add new device\n");1581ret = -ENOSPC;1582goto err;1583}1584ae_devices.desc[count].pf_type = pf_type;1585ae_devices.desc[count].num_queues = num_queues;1586ae_devices.desc[count++].dev = pdev;1587atomic_inc(&ae_devices.count);1588sort(ae_devices.desc, count, sizeof(struct cpt_device_desc),1589compare_func, NULL);1590break;15911592default:1593dev_err(&pdev->dev, "Unknown VF type %d\n", engine_type);1594ret = BAD_OTX_CPTVF_TYPE;1595}1596err:1597mutex_unlock(&mutex);1598return ret;1599}16001601void otx_cpt_crypto_exit(struct pci_dev *pdev, struct module *mod,1602enum otx_cptvf_type engine_type)1603{1604struct cpt_device_table *dev_tbl;1605bool dev_found = false;1606int i, j, count;16071608mutex_lock(&mutex);16091610dev_tbl = (engine_type == OTX_CPT_AE_TYPES) ? &ae_devices : &se_devices;1611count = atomic_read(&dev_tbl->count);1612for (i = 0; i < count; i++)1613if (pdev == dev_tbl->desc[i].dev) {1614for (j = i; j < count-1; j++)1615dev_tbl->desc[j] = dev_tbl->desc[j+1];1616dev_found = true;1617break;1618}16191620if (!dev_found) {1621dev_err(&pdev->dev, "%s device not found\n", __func__);1622goto exit;1623}16241625if (engine_type != OTX_CPT_AE_TYPES) {1626if (atomic_dec_and_test(&se_devices.count) &&1627!is_any_alg_used()) {1628cpt_unregister_algs();1629module_put(mod);1630is_crypto_registered = false;1631}1632} else1633atomic_dec(&ae_devices.count);1634exit:1635mutex_unlock(&mutex);1636}163716381639