18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Marvell OcteonTX CPT driver 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2019 Marvell International Ltd. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 78c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License version 2 as 88c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <crypto/aes.h> 128c2ecf20Sopenharmony_ci#include <crypto/authenc.h> 138c2ecf20Sopenharmony_ci#include <crypto/cryptd.h> 148c2ecf20Sopenharmony_ci#include <crypto/des.h> 158c2ecf20Sopenharmony_ci#include <crypto/internal/aead.h> 168c2ecf20Sopenharmony_ci#include <crypto/sha.h> 178c2ecf20Sopenharmony_ci#include <crypto/xts.h> 188c2ecf20Sopenharmony_ci#include <crypto/scatterwalk.h> 198c2ecf20Sopenharmony_ci#include <linux/rtnetlink.h> 208c2ecf20Sopenharmony_ci#include <linux/sort.h> 218c2ecf20Sopenharmony_ci#include <linux/module.h> 228c2ecf20Sopenharmony_ci#include "otx_cptvf.h" 238c2ecf20Sopenharmony_ci#include "otx_cptvf_algs.h" 248c2ecf20Sopenharmony_ci#include "otx_cptvf_reqmgr.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define CPT_MAX_VF_NUM 64 278c2ecf20Sopenharmony_ci/* Size of salt in AES GCM mode */ 288c2ecf20Sopenharmony_ci#define AES_GCM_SALT_SIZE 4 298c2ecf20Sopenharmony_ci/* Size of IV in AES GCM mode */ 308c2ecf20Sopenharmony_ci#define AES_GCM_IV_SIZE 8 318c2ecf20Sopenharmony_ci/* Size of ICV (Integrity Check Value) in AES GCM mode */ 328c2ecf20Sopenharmony_ci#define AES_GCM_ICV_SIZE 16 338c2ecf20Sopenharmony_ci/* Offset of IV in AES GCM mode */ 348c2ecf20Sopenharmony_ci#define AES_GCM_IV_OFFSET 8 358c2ecf20Sopenharmony_ci#define CONTROL_WORD_LEN 8 368c2ecf20Sopenharmony_ci#define KEY2_OFFSET 48 378c2ecf20Sopenharmony_ci#define DMA_MODE_FLAG(dma_mode) \ 388c2ecf20Sopenharmony_ci (((dma_mode) == OTX_CPT_DMA_GATHER_SCATTER) ? (1 << 7) : 0) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* Truncated SHA digest size */ 418c2ecf20Sopenharmony_ci#define SHA1_TRUNC_DIGEST_SIZE 12 428c2ecf20Sopenharmony_ci#define SHA256_TRUNC_DIGEST_SIZE 16 438c2ecf20Sopenharmony_ci#define SHA384_TRUNC_DIGEST_SIZE 24 448c2ecf20Sopenharmony_ci#define SHA512_TRUNC_DIGEST_SIZE 32 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex); 478c2ecf20Sopenharmony_cistatic int is_crypto_registered; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistruct cpt_device_desc { 508c2ecf20Sopenharmony_ci enum otx_cptpf_type pf_type; 518c2ecf20Sopenharmony_ci struct pci_dev *dev; 528c2ecf20Sopenharmony_ci int num_queues; 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct cpt_device_table { 568c2ecf20Sopenharmony_ci atomic_t count; 578c2ecf20Sopenharmony_ci struct cpt_device_desc desc[CPT_MAX_VF_NUM]; 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic struct cpt_device_table se_devices = { 618c2ecf20Sopenharmony_ci .count = ATOMIC_INIT(0) 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic struct cpt_device_table ae_devices = { 658c2ecf20Sopenharmony_ci .count = ATOMIC_INIT(0) 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic inline int get_se_device(struct pci_dev **pdev, int *cpu_num) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci int count, ret = 0; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci count = atomic_read(&se_devices.count); 738c2ecf20Sopenharmony_ci if (count < 1) 748c2ecf20Sopenharmony_ci return -ENODEV; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci *cpu_num = get_cpu(); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (se_devices.desc[0].pf_type == OTX_CPT_SE) { 798c2ecf20Sopenharmony_ci /* 808c2ecf20Sopenharmony_ci * On OcteonTX platform there is one CPT instruction queue bound 818c2ecf20Sopenharmony_ci * to each VF. We get maximum performance if one CPT queue 828c2ecf20Sopenharmony_ci * is available for each cpu otherwise CPT queues need to be 838c2ecf20Sopenharmony_ci * shared between cpus. 848c2ecf20Sopenharmony_ci */ 858c2ecf20Sopenharmony_ci if (*cpu_num >= count) 868c2ecf20Sopenharmony_ci *cpu_num %= count; 878c2ecf20Sopenharmony_ci *pdev = se_devices.desc[*cpu_num].dev; 888c2ecf20Sopenharmony_ci } else { 898c2ecf20Sopenharmony_ci pr_err("Unknown PF type %d\n", se_devices.desc[0].pf_type); 908c2ecf20Sopenharmony_ci ret = -EINVAL; 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci put_cpu(); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci return ret; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic inline int validate_hmac_cipher_null(struct otx_cpt_req_info *cpt_req) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx; 1008c2ecf20Sopenharmony_ci struct aead_request *req; 1018c2ecf20Sopenharmony_ci struct crypto_aead *tfm; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci req = container_of(cpt_req->areq, struct aead_request, base); 1048c2ecf20Sopenharmony_ci tfm = crypto_aead_reqtfm(req); 1058c2ecf20Sopenharmony_ci rctx = aead_request_ctx(req); 1068c2ecf20Sopenharmony_ci if (memcmp(rctx->fctx.hmac.s.hmac_calc, 1078c2ecf20Sopenharmony_ci rctx->fctx.hmac.s.hmac_recv, 1088c2ecf20Sopenharmony_ci crypto_aead_authsize(tfm)) != 0) 1098c2ecf20Sopenharmony_ci return -EBADMSG; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci return 0; 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic void otx_cpt_aead_callback(int status, void *arg1, void *arg2) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci struct otx_cpt_info_buffer *cpt_info = arg2; 1178c2ecf20Sopenharmony_ci struct crypto_async_request *areq = arg1; 1188c2ecf20Sopenharmony_ci struct otx_cpt_req_info *cpt_req; 1198c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (!cpt_info) 1228c2ecf20Sopenharmony_ci goto complete; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci cpt_req = cpt_info->req; 1258c2ecf20Sopenharmony_ci if (!status) { 1268c2ecf20Sopenharmony_ci /* 1278c2ecf20Sopenharmony_ci * When selected cipher is NULL we need to manually 1288c2ecf20Sopenharmony_ci * verify whether calculated hmac value matches 1298c2ecf20Sopenharmony_ci * received hmac value 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci if (cpt_req->req_type == OTX_CPT_AEAD_ENC_DEC_NULL_REQ && 1328c2ecf20Sopenharmony_ci !cpt_req->is_enc) 1338c2ecf20Sopenharmony_ci status = validate_hmac_cipher_null(cpt_req); 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci pdev = cpt_info->pdev; 1368c2ecf20Sopenharmony_ci do_request_cleanup(pdev, cpt_info); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cicomplete: 1398c2ecf20Sopenharmony_ci if (areq) 1408c2ecf20Sopenharmony_ci areq->complete(areq, status); 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic void output_iv_copyback(struct crypto_async_request *areq) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info; 1468c2ecf20Sopenharmony_ci struct skcipher_request *sreq; 1478c2ecf20Sopenharmony_ci struct crypto_skcipher *stfm; 1488c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx; 1498c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx; 1508c2ecf20Sopenharmony_ci u32 start, ivsize; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci sreq = container_of(areq, struct skcipher_request, base); 1538c2ecf20Sopenharmony_ci stfm = crypto_skcipher_reqtfm(sreq); 1548c2ecf20Sopenharmony_ci ctx = crypto_skcipher_ctx(stfm); 1558c2ecf20Sopenharmony_ci if (ctx->cipher_type == OTX_CPT_AES_CBC || 1568c2ecf20Sopenharmony_ci ctx->cipher_type == OTX_CPT_DES3_CBC) { 1578c2ecf20Sopenharmony_ci rctx = skcipher_request_ctx(sreq); 1588c2ecf20Sopenharmony_ci req_info = &rctx->cpt_req; 1598c2ecf20Sopenharmony_ci ivsize = crypto_skcipher_ivsize(stfm); 1608c2ecf20Sopenharmony_ci start = sreq->cryptlen - ivsize; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci if (req_info->is_enc) { 1638c2ecf20Sopenharmony_ci scatterwalk_map_and_copy(sreq->iv, sreq->dst, start, 1648c2ecf20Sopenharmony_ci ivsize, 0); 1658c2ecf20Sopenharmony_ci } else { 1668c2ecf20Sopenharmony_ci if (sreq->src != sreq->dst) { 1678c2ecf20Sopenharmony_ci scatterwalk_map_and_copy(sreq->iv, sreq->src, 1688c2ecf20Sopenharmony_ci start, ivsize, 0); 1698c2ecf20Sopenharmony_ci } else { 1708c2ecf20Sopenharmony_ci memcpy(sreq->iv, req_info->iv_out, ivsize); 1718c2ecf20Sopenharmony_ci kfree(req_info->iv_out); 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic void otx_cpt_skcipher_callback(int status, void *arg1, void *arg2) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci struct otx_cpt_info_buffer *cpt_info = arg2; 1808c2ecf20Sopenharmony_ci struct crypto_async_request *areq = arg1; 1818c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci if (areq) { 1848c2ecf20Sopenharmony_ci if (!status) 1858c2ecf20Sopenharmony_ci output_iv_copyback(areq); 1868c2ecf20Sopenharmony_ci if (cpt_info) { 1878c2ecf20Sopenharmony_ci pdev = cpt_info->pdev; 1888c2ecf20Sopenharmony_ci do_request_cleanup(pdev, cpt_info); 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci areq->complete(areq, status); 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic inline void update_input_data(struct otx_cpt_req_info *req_info, 1958c2ecf20Sopenharmony_ci struct scatterlist *inp_sg, 1968c2ecf20Sopenharmony_ci u32 nbytes, u32 *argcnt) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci req_info->req.dlen += nbytes; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci while (nbytes) { 2018c2ecf20Sopenharmony_ci u32 len = min(nbytes, inp_sg->length); 2028c2ecf20Sopenharmony_ci u8 *ptr = sg_virt(inp_sg); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (void *)ptr; 2058c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = len; 2068c2ecf20Sopenharmony_ci nbytes -= len; 2078c2ecf20Sopenharmony_ci ++(*argcnt); 2088c2ecf20Sopenharmony_ci inp_sg = sg_next(inp_sg); 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline void update_output_data(struct otx_cpt_req_info *req_info, 2138c2ecf20Sopenharmony_ci struct scatterlist *outp_sg, 2148c2ecf20Sopenharmony_ci u32 offset, u32 nbytes, u32 *argcnt) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci req_info->rlen += nbytes; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci while (nbytes) { 2198c2ecf20Sopenharmony_ci u32 len = min(nbytes, outp_sg->length - offset); 2208c2ecf20Sopenharmony_ci u8 *ptr = sg_virt(outp_sg); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci req_info->out[*argcnt].vptr = (void *) (ptr + offset); 2238c2ecf20Sopenharmony_ci req_info->out[*argcnt].size = len; 2248c2ecf20Sopenharmony_ci nbytes -= len; 2258c2ecf20Sopenharmony_ci ++(*argcnt); 2268c2ecf20Sopenharmony_ci offset = 0; 2278c2ecf20Sopenharmony_ci outp_sg = sg_next(outp_sg); 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc, 2328c2ecf20Sopenharmony_ci u32 *argcnt) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req); 2358c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = skcipher_request_ctx(req); 2368c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 2378c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(stfm); 2388c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx = crypto_tfm_ctx(tfm); 2398c2ecf20Sopenharmony_ci struct otx_cpt_fc_ctx *fctx = &rctx->fctx; 2408c2ecf20Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(stfm); 2418c2ecf20Sopenharmony_ci u32 start = req->cryptlen - ivsize; 2428c2ecf20Sopenharmony_ci gfp_t flags; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 2458c2ecf20Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 2468c2ecf20Sopenharmony_ci req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER; 2478c2ecf20Sopenharmony_ci req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_FC | 2508c2ecf20Sopenharmony_ci DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER); 2518c2ecf20Sopenharmony_ci if (enc) { 2528c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 2; 2538c2ecf20Sopenharmony_ci } else { 2548c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 3; 2558c2ecf20Sopenharmony_ci if ((ctx->cipher_type == OTX_CPT_AES_CBC || 2568c2ecf20Sopenharmony_ci ctx->cipher_type == OTX_CPT_DES3_CBC) && 2578c2ecf20Sopenharmony_ci req->src == req->dst) { 2588c2ecf20Sopenharmony_ci req_info->iv_out = kmalloc(ivsize, flags); 2598c2ecf20Sopenharmony_ci if (!req_info->iv_out) 2608c2ecf20Sopenharmony_ci return -ENOMEM; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci scatterwalk_map_and_copy(req_info->iv_out, req->src, 2638c2ecf20Sopenharmony_ci start, ivsize, 0); 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci /* Encryption data length */ 2678c2ecf20Sopenharmony_ci req_info->req.param1 = req->cryptlen; 2688c2ecf20Sopenharmony_ci /* Authentication data length */ 2698c2ecf20Sopenharmony_ci req_info->req.param2 = 0; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 2728c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 2738c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_CPTR; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci if (ctx->cipher_type == OTX_CPT_AES_XTS) 2768c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2); 2778c2ecf20Sopenharmony_ci else 2788c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_iv, req->iv, crypto_skcipher_ivsize(stfm)); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.flags = cpu_to_be64(fctx->enc.enc_ctrl.cflags); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci /* 2858c2ecf20Sopenharmony_ci * Storing Packet Data Information in offset 2868c2ecf20Sopenharmony_ci * Control Word First 8 bytes 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word; 2898c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = CONTROL_WORD_LEN; 2908c2ecf20Sopenharmony_ci req_info->req.dlen += CONTROL_WORD_LEN; 2918c2ecf20Sopenharmony_ci ++(*argcnt); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)fctx; 2948c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = sizeof(struct otx_cpt_fc_ctx); 2958c2ecf20Sopenharmony_ci req_info->req.dlen += sizeof(struct otx_cpt_fc_ctx); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci ++(*argcnt); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic inline u32 create_input_list(struct skcipher_request *req, u32 enc, 3038c2ecf20Sopenharmony_ci u32 enc_iv_len) 3048c2ecf20Sopenharmony_ci{ 3058c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = skcipher_request_ctx(req); 3068c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 3078c2ecf20Sopenharmony_ci u32 argcnt = 0; 3088c2ecf20Sopenharmony_ci int ret; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci ret = create_ctx_hdr(req, enc, &argcnt); 3118c2ecf20Sopenharmony_ci if (ret) 3128c2ecf20Sopenharmony_ci return ret; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci update_input_data(req_info, req->src, req->cryptlen, &argcnt); 3158c2ecf20Sopenharmony_ci req_info->incnt = argcnt; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci return 0; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic inline void create_output_list(struct skcipher_request *req, 3218c2ecf20Sopenharmony_ci u32 enc_iv_len) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = skcipher_request_ctx(req); 3248c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 3258c2ecf20Sopenharmony_ci u32 argcnt = 0; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci /* 3288c2ecf20Sopenharmony_ci * OUTPUT Buffer Processing 3298c2ecf20Sopenharmony_ci * AES encryption/decryption output would be 3308c2ecf20Sopenharmony_ci * received in the following format 3318c2ecf20Sopenharmony_ci * 3328c2ecf20Sopenharmony_ci * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----| 3338c2ecf20Sopenharmony_ci * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ] 3348c2ecf20Sopenharmony_ci */ 3358c2ecf20Sopenharmony_ci update_output_data(req_info, req->dst, 0, req->cryptlen, &argcnt); 3368c2ecf20Sopenharmony_ci req_info->outcnt = argcnt; 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_cistatic inline int cpt_enc_dec(struct skcipher_request *req, u32 enc) 3408c2ecf20Sopenharmony_ci{ 3418c2ecf20Sopenharmony_ci struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(req); 3428c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = skcipher_request_ctx(req); 3438c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 3448c2ecf20Sopenharmony_ci u32 enc_iv_len = crypto_skcipher_ivsize(stfm); 3458c2ecf20Sopenharmony_ci struct pci_dev *pdev; 3468c2ecf20Sopenharmony_ci int status, cpu_num; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci /* Validate that request doesn't exceed maximum CPT supported size */ 3498c2ecf20Sopenharmony_ci if (req->cryptlen > OTX_CPT_MAX_REQ_SIZE) 3508c2ecf20Sopenharmony_ci return -E2BIG; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci /* Clear control words */ 3538c2ecf20Sopenharmony_ci rctx->ctrl_word.flags = 0; 3548c2ecf20Sopenharmony_ci rctx->fctx.enc.enc_ctrl.flags = 0; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci status = create_input_list(req, enc, enc_iv_len); 3578c2ecf20Sopenharmony_ci if (status) 3588c2ecf20Sopenharmony_ci return status; 3598c2ecf20Sopenharmony_ci create_output_list(req, enc_iv_len); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci status = get_se_device(&pdev, &cpu_num); 3628c2ecf20Sopenharmony_ci if (status) 3638c2ecf20Sopenharmony_ci return status; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci req_info->callback = (void *)otx_cpt_skcipher_callback; 3668c2ecf20Sopenharmony_ci req_info->areq = &req->base; 3678c2ecf20Sopenharmony_ci req_info->req_type = OTX_CPT_ENC_DEC_REQ; 3688c2ecf20Sopenharmony_ci req_info->is_enc = enc; 3698c2ecf20Sopenharmony_ci req_info->is_trunc_hmac = false; 3708c2ecf20Sopenharmony_ci req_info->ctrl.s.grp = 0; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci /* 3738c2ecf20Sopenharmony_ci * We perform an asynchronous send and once 3748c2ecf20Sopenharmony_ci * the request is completed the driver would 3758c2ecf20Sopenharmony_ci * intimate through registered call back functions 3768c2ecf20Sopenharmony_ci */ 3778c2ecf20Sopenharmony_ci status = otx_cpt_do_request(pdev, req_info, cpu_num); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci return status; 3808c2ecf20Sopenharmony_ci} 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_encrypt(struct skcipher_request *req) 3838c2ecf20Sopenharmony_ci{ 3848c2ecf20Sopenharmony_ci return cpt_enc_dec(req, true); 3858c2ecf20Sopenharmony_ci} 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_decrypt(struct skcipher_request *req) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci return cpt_enc_dec(req, false); 3908c2ecf20Sopenharmony_ci} 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_xts_setkey(struct crypto_skcipher *tfm, 3938c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 3968c2ecf20Sopenharmony_ci const u8 *key2 = key + (keylen / 2); 3978c2ecf20Sopenharmony_ci const u8 *key1 = key; 3988c2ecf20Sopenharmony_ci int ret; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci ret = xts_check_key(crypto_skcipher_tfm(tfm), key, keylen); 4018c2ecf20Sopenharmony_ci if (ret) 4028c2ecf20Sopenharmony_ci return ret; 4038c2ecf20Sopenharmony_ci ctx->key_len = keylen; 4048c2ecf20Sopenharmony_ci memcpy(ctx->enc_key, key1, keylen / 2); 4058c2ecf20Sopenharmony_ci memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2); 4068c2ecf20Sopenharmony_ci ctx->cipher_type = OTX_CPT_AES_XTS; 4078c2ecf20Sopenharmony_ci switch (ctx->key_len) { 4088c2ecf20Sopenharmony_ci case 2 * AES_KEYSIZE_128: 4098c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_128_BIT; 4108c2ecf20Sopenharmony_ci break; 4118c2ecf20Sopenharmony_ci case 2 * AES_KEYSIZE_256: 4128c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_256_BIT; 4138c2ecf20Sopenharmony_ci break; 4148c2ecf20Sopenharmony_ci default: 4158c2ecf20Sopenharmony_ci return -EINVAL; 4168c2ecf20Sopenharmony_ci } 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci return 0; 4198c2ecf20Sopenharmony_ci} 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_cistatic int cpt_des_setkey(struct crypto_skcipher *tfm, const u8 *key, 4228c2ecf20Sopenharmony_ci u32 keylen, u8 cipher_type) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci if (keylen != DES3_EDE_KEY_SIZE) 4278c2ecf20Sopenharmony_ci return -EINVAL; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci ctx->key_len = keylen; 4308c2ecf20Sopenharmony_ci ctx->cipher_type = cipher_type; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci memcpy(ctx->enc_key, key, keylen); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci return 0; 4358c2ecf20Sopenharmony_ci} 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_cistatic int cpt_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, 4388c2ecf20Sopenharmony_ci u32 keylen, u8 cipher_type) 4398c2ecf20Sopenharmony_ci{ 4408c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci switch (keylen) { 4438c2ecf20Sopenharmony_ci case AES_KEYSIZE_128: 4448c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_128_BIT; 4458c2ecf20Sopenharmony_ci break; 4468c2ecf20Sopenharmony_ci case AES_KEYSIZE_192: 4478c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_192_BIT; 4488c2ecf20Sopenharmony_ci break; 4498c2ecf20Sopenharmony_ci case AES_KEYSIZE_256: 4508c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_256_BIT; 4518c2ecf20Sopenharmony_ci break; 4528c2ecf20Sopenharmony_ci default: 4538c2ecf20Sopenharmony_ci return -EINVAL; 4548c2ecf20Sopenharmony_ci } 4558c2ecf20Sopenharmony_ci ctx->key_len = keylen; 4568c2ecf20Sopenharmony_ci ctx->cipher_type = cipher_type; 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci memcpy(ctx->enc_key, key, keylen); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci return 0; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_cbc_aes_setkey(struct crypto_skcipher *tfm, 4648c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci return cpt_aes_setkey(tfm, key, keylen, OTX_CPT_AES_CBC); 4678c2ecf20Sopenharmony_ci} 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_ecb_aes_setkey(struct crypto_skcipher *tfm, 4708c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 4718c2ecf20Sopenharmony_ci{ 4728c2ecf20Sopenharmony_ci return cpt_aes_setkey(tfm, key, keylen, OTX_CPT_AES_ECB); 4738c2ecf20Sopenharmony_ci} 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_cfb_aes_setkey(struct crypto_skcipher *tfm, 4768c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 4778c2ecf20Sopenharmony_ci{ 4788c2ecf20Sopenharmony_ci return cpt_aes_setkey(tfm, key, keylen, OTX_CPT_AES_CFB); 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_cbc_des3_setkey(struct crypto_skcipher *tfm, 4828c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 4838c2ecf20Sopenharmony_ci{ 4848c2ecf20Sopenharmony_ci return cpt_des_setkey(tfm, key, keylen, OTX_CPT_DES3_CBC); 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic int otx_cpt_skcipher_ecb_des3_setkey(struct crypto_skcipher *tfm, 4888c2ecf20Sopenharmony_ci const u8 *key, u32 keylen) 4898c2ecf20Sopenharmony_ci{ 4908c2ecf20Sopenharmony_ci return cpt_des_setkey(tfm, key, keylen, OTX_CPT_DES3_ECB); 4918c2ecf20Sopenharmony_ci} 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_cistatic int otx_cpt_enc_dec_init(struct crypto_skcipher *tfm) 4948c2ecf20Sopenharmony_ci{ 4958c2ecf20Sopenharmony_ci struct otx_cpt_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci memset(ctx, 0, sizeof(*ctx)); 4988c2ecf20Sopenharmony_ci /* 4998c2ecf20Sopenharmony_ci * Additional memory for skcipher_request is 5008c2ecf20Sopenharmony_ci * allocated since the cryptd daemon uses 5018c2ecf20Sopenharmony_ci * this memory for request_ctx information 5028c2ecf20Sopenharmony_ci */ 5038c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, sizeof(struct otx_cpt_req_ctx) + 5048c2ecf20Sopenharmony_ci sizeof(struct skcipher_request)); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci return 0; 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cistatic int cpt_aead_init(struct crypto_aead *tfm, u8 cipher_type, u8 mac_type) 5108c2ecf20Sopenharmony_ci{ 5118c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(tfm); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci ctx->cipher_type = cipher_type; 5148c2ecf20Sopenharmony_ci ctx->mac_type = mac_type; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci /* 5178c2ecf20Sopenharmony_ci * When selected cipher is NULL we use HMAC opcode instead of 5188c2ecf20Sopenharmony_ci * FLEXICRYPTO opcode therefore we don't need to use HASH algorithms 5198c2ecf20Sopenharmony_ci * for calculating ipad and opad 5208c2ecf20Sopenharmony_ci */ 5218c2ecf20Sopenharmony_ci if (ctx->cipher_type != OTX_CPT_CIPHER_NULL) { 5228c2ecf20Sopenharmony_ci switch (ctx->mac_type) { 5238c2ecf20Sopenharmony_ci case OTX_CPT_SHA1: 5248c2ecf20Sopenharmony_ci ctx->hashalg = crypto_alloc_shash("sha1", 0, 5258c2ecf20Sopenharmony_ci CRYPTO_ALG_ASYNC); 5268c2ecf20Sopenharmony_ci if (IS_ERR(ctx->hashalg)) 5278c2ecf20Sopenharmony_ci return PTR_ERR(ctx->hashalg); 5288c2ecf20Sopenharmony_ci break; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci case OTX_CPT_SHA256: 5318c2ecf20Sopenharmony_ci ctx->hashalg = crypto_alloc_shash("sha256", 0, 5328c2ecf20Sopenharmony_ci CRYPTO_ALG_ASYNC); 5338c2ecf20Sopenharmony_ci if (IS_ERR(ctx->hashalg)) 5348c2ecf20Sopenharmony_ci return PTR_ERR(ctx->hashalg); 5358c2ecf20Sopenharmony_ci break; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci case OTX_CPT_SHA384: 5388c2ecf20Sopenharmony_ci ctx->hashalg = crypto_alloc_shash("sha384", 0, 5398c2ecf20Sopenharmony_ci CRYPTO_ALG_ASYNC); 5408c2ecf20Sopenharmony_ci if (IS_ERR(ctx->hashalg)) 5418c2ecf20Sopenharmony_ci return PTR_ERR(ctx->hashalg); 5428c2ecf20Sopenharmony_ci break; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci case OTX_CPT_SHA512: 5458c2ecf20Sopenharmony_ci ctx->hashalg = crypto_alloc_shash("sha512", 0, 5468c2ecf20Sopenharmony_ci CRYPTO_ALG_ASYNC); 5478c2ecf20Sopenharmony_ci if (IS_ERR(ctx->hashalg)) 5488c2ecf20Sopenharmony_ci return PTR_ERR(ctx->hashalg); 5498c2ecf20Sopenharmony_ci break; 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci } 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci crypto_aead_set_reqsize(tfm, sizeof(struct otx_cpt_req_ctx)); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci return 0; 5568c2ecf20Sopenharmony_ci} 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_cistatic int otx_cpt_aead_cbc_aes_sha1_init(struct crypto_aead *tfm) 5598c2ecf20Sopenharmony_ci{ 5608c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA1); 5618c2ecf20Sopenharmony_ci} 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_cistatic int otx_cpt_aead_cbc_aes_sha256_init(struct crypto_aead *tfm) 5648c2ecf20Sopenharmony_ci{ 5658c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA256); 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistatic int otx_cpt_aead_cbc_aes_sha384_init(struct crypto_aead *tfm) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA384); 5718c2ecf20Sopenharmony_ci} 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_cistatic int otx_cpt_aead_cbc_aes_sha512_init(struct crypto_aead *tfm) 5748c2ecf20Sopenharmony_ci{ 5758c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_AES_CBC, OTX_CPT_SHA512); 5768c2ecf20Sopenharmony_ci} 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_cistatic int otx_cpt_aead_ecb_null_sha1_init(struct crypto_aead *tfm) 5798c2ecf20Sopenharmony_ci{ 5808c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA1); 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic int otx_cpt_aead_ecb_null_sha256_init(struct crypto_aead *tfm) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA256); 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic int otx_cpt_aead_ecb_null_sha384_init(struct crypto_aead *tfm) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA384); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic int otx_cpt_aead_ecb_null_sha512_init(struct crypto_aead *tfm) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_CIPHER_NULL, OTX_CPT_SHA512); 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic int otx_cpt_aead_gcm_aes_init(struct crypto_aead *tfm) 5998c2ecf20Sopenharmony_ci{ 6008c2ecf20Sopenharmony_ci return cpt_aead_init(tfm, OTX_CPT_AES_GCM, OTX_CPT_MAC_NULL); 6018c2ecf20Sopenharmony_ci} 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_cistatic void otx_cpt_aead_exit(struct crypto_aead *tfm) 6048c2ecf20Sopenharmony_ci{ 6058c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(tfm); 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci kfree(ctx->ipad); 6088c2ecf20Sopenharmony_ci kfree(ctx->opad); 6098c2ecf20Sopenharmony_ci if (ctx->hashalg) 6108c2ecf20Sopenharmony_ci crypto_free_shash(ctx->hashalg); 6118c2ecf20Sopenharmony_ci kfree(ctx->sdesc); 6128c2ecf20Sopenharmony_ci} 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci/* 6158c2ecf20Sopenharmony_ci * This is the Integrity Check Value validation (aka the authentication tag 6168c2ecf20Sopenharmony_ci * length) 6178c2ecf20Sopenharmony_ci */ 6188c2ecf20Sopenharmony_cistatic int otx_cpt_aead_set_authsize(struct crypto_aead *tfm, 6198c2ecf20Sopenharmony_ci unsigned int authsize) 6208c2ecf20Sopenharmony_ci{ 6218c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(tfm); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci switch (ctx->mac_type) { 6248c2ecf20Sopenharmony_ci case OTX_CPT_SHA1: 6258c2ecf20Sopenharmony_ci if (authsize != SHA1_DIGEST_SIZE && 6268c2ecf20Sopenharmony_ci authsize != SHA1_TRUNC_DIGEST_SIZE) 6278c2ecf20Sopenharmony_ci return -EINVAL; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci if (authsize == SHA1_TRUNC_DIGEST_SIZE) 6308c2ecf20Sopenharmony_ci ctx->is_trunc_hmac = true; 6318c2ecf20Sopenharmony_ci break; 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci case OTX_CPT_SHA256: 6348c2ecf20Sopenharmony_ci if (authsize != SHA256_DIGEST_SIZE && 6358c2ecf20Sopenharmony_ci authsize != SHA256_TRUNC_DIGEST_SIZE) 6368c2ecf20Sopenharmony_ci return -EINVAL; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci if (authsize == SHA256_TRUNC_DIGEST_SIZE) 6398c2ecf20Sopenharmony_ci ctx->is_trunc_hmac = true; 6408c2ecf20Sopenharmony_ci break; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci case OTX_CPT_SHA384: 6438c2ecf20Sopenharmony_ci if (authsize != SHA384_DIGEST_SIZE && 6448c2ecf20Sopenharmony_ci authsize != SHA384_TRUNC_DIGEST_SIZE) 6458c2ecf20Sopenharmony_ci return -EINVAL; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci if (authsize == SHA384_TRUNC_DIGEST_SIZE) 6488c2ecf20Sopenharmony_ci ctx->is_trunc_hmac = true; 6498c2ecf20Sopenharmony_ci break; 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci case OTX_CPT_SHA512: 6528c2ecf20Sopenharmony_ci if (authsize != SHA512_DIGEST_SIZE && 6538c2ecf20Sopenharmony_ci authsize != SHA512_TRUNC_DIGEST_SIZE) 6548c2ecf20Sopenharmony_ci return -EINVAL; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci if (authsize == SHA512_TRUNC_DIGEST_SIZE) 6578c2ecf20Sopenharmony_ci ctx->is_trunc_hmac = true; 6588c2ecf20Sopenharmony_ci break; 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci case OTX_CPT_MAC_NULL: 6618c2ecf20Sopenharmony_ci if (ctx->cipher_type == OTX_CPT_AES_GCM) { 6628c2ecf20Sopenharmony_ci if (authsize != AES_GCM_ICV_SIZE) 6638c2ecf20Sopenharmony_ci return -EINVAL; 6648c2ecf20Sopenharmony_ci } else 6658c2ecf20Sopenharmony_ci return -EINVAL; 6668c2ecf20Sopenharmony_ci break; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci default: 6698c2ecf20Sopenharmony_ci return -EINVAL; 6708c2ecf20Sopenharmony_ci } 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci tfm->authsize = authsize; 6738c2ecf20Sopenharmony_ci return 0; 6748c2ecf20Sopenharmony_ci} 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_cistatic struct otx_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg) 6778c2ecf20Sopenharmony_ci{ 6788c2ecf20Sopenharmony_ci struct otx_cpt_sdesc *sdesc; 6798c2ecf20Sopenharmony_ci int size; 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); 6828c2ecf20Sopenharmony_ci sdesc = kmalloc(size, GFP_KERNEL); 6838c2ecf20Sopenharmony_ci if (!sdesc) 6848c2ecf20Sopenharmony_ci return NULL; 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ci sdesc->shash.tfm = alg; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci return sdesc; 6898c2ecf20Sopenharmony_ci} 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_cistatic inline void swap_data32(void *buf, u32 len) 6928c2ecf20Sopenharmony_ci{ 6938c2ecf20Sopenharmony_ci cpu_to_be32_array(buf, buf, len / 4); 6948c2ecf20Sopenharmony_ci} 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_cistatic inline void swap_data64(void *buf, u32 len) 6978c2ecf20Sopenharmony_ci{ 6988c2ecf20Sopenharmony_ci __be64 *dst = buf; 6998c2ecf20Sopenharmony_ci u64 *src = buf; 7008c2ecf20Sopenharmony_ci int i = 0; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci for (i = 0 ; i < len / 8; i++, src++, dst++) 7038c2ecf20Sopenharmony_ci *dst = cpu_to_be64p(src); 7048c2ecf20Sopenharmony_ci} 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_cistatic int copy_pad(u8 mac_type, u8 *out_pad, u8 *in_pad) 7078c2ecf20Sopenharmony_ci{ 7088c2ecf20Sopenharmony_ci struct sha512_state *sha512; 7098c2ecf20Sopenharmony_ci struct sha256_state *sha256; 7108c2ecf20Sopenharmony_ci struct sha1_state *sha1; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci switch (mac_type) { 7138c2ecf20Sopenharmony_ci case OTX_CPT_SHA1: 7148c2ecf20Sopenharmony_ci sha1 = (struct sha1_state *) in_pad; 7158c2ecf20Sopenharmony_ci swap_data32(sha1->state, SHA1_DIGEST_SIZE); 7168c2ecf20Sopenharmony_ci memcpy(out_pad, &sha1->state, SHA1_DIGEST_SIZE); 7178c2ecf20Sopenharmony_ci break; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci case OTX_CPT_SHA256: 7208c2ecf20Sopenharmony_ci sha256 = (struct sha256_state *) in_pad; 7218c2ecf20Sopenharmony_ci swap_data32(sha256->state, SHA256_DIGEST_SIZE); 7228c2ecf20Sopenharmony_ci memcpy(out_pad, &sha256->state, SHA256_DIGEST_SIZE); 7238c2ecf20Sopenharmony_ci break; 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci case OTX_CPT_SHA384: 7268c2ecf20Sopenharmony_ci case OTX_CPT_SHA512: 7278c2ecf20Sopenharmony_ci sha512 = (struct sha512_state *) in_pad; 7288c2ecf20Sopenharmony_ci swap_data64(sha512->state, SHA512_DIGEST_SIZE); 7298c2ecf20Sopenharmony_ci memcpy(out_pad, &sha512->state, SHA512_DIGEST_SIZE); 7308c2ecf20Sopenharmony_ci break; 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci default: 7338c2ecf20Sopenharmony_ci return -EINVAL; 7348c2ecf20Sopenharmony_ci } 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci return 0; 7378c2ecf20Sopenharmony_ci} 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_cistatic int aead_hmac_init(struct crypto_aead *cipher) 7408c2ecf20Sopenharmony_ci{ 7418c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(cipher); 7428c2ecf20Sopenharmony_ci int state_size = crypto_shash_statesize(ctx->hashalg); 7438c2ecf20Sopenharmony_ci int ds = crypto_shash_digestsize(ctx->hashalg); 7448c2ecf20Sopenharmony_ci int bs = crypto_shash_blocksize(ctx->hashalg); 7458c2ecf20Sopenharmony_ci int authkeylen = ctx->auth_key_len; 7468c2ecf20Sopenharmony_ci u8 *ipad = NULL, *opad = NULL; 7478c2ecf20Sopenharmony_ci int ret = 0, icount = 0; 7488c2ecf20Sopenharmony_ci 7498c2ecf20Sopenharmony_ci ctx->sdesc = alloc_sdesc(ctx->hashalg); 7508c2ecf20Sopenharmony_ci if (!ctx->sdesc) 7518c2ecf20Sopenharmony_ci return -ENOMEM; 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci ctx->ipad = kzalloc(bs, GFP_KERNEL); 7548c2ecf20Sopenharmony_ci if (!ctx->ipad) { 7558c2ecf20Sopenharmony_ci ret = -ENOMEM; 7568c2ecf20Sopenharmony_ci goto calc_fail; 7578c2ecf20Sopenharmony_ci } 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci ctx->opad = kzalloc(bs, GFP_KERNEL); 7608c2ecf20Sopenharmony_ci if (!ctx->opad) { 7618c2ecf20Sopenharmony_ci ret = -ENOMEM; 7628c2ecf20Sopenharmony_ci goto calc_fail; 7638c2ecf20Sopenharmony_ci } 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci ipad = kzalloc(state_size, GFP_KERNEL); 7668c2ecf20Sopenharmony_ci if (!ipad) { 7678c2ecf20Sopenharmony_ci ret = -ENOMEM; 7688c2ecf20Sopenharmony_ci goto calc_fail; 7698c2ecf20Sopenharmony_ci } 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci opad = kzalloc(state_size, GFP_KERNEL); 7728c2ecf20Sopenharmony_ci if (!opad) { 7738c2ecf20Sopenharmony_ci ret = -ENOMEM; 7748c2ecf20Sopenharmony_ci goto calc_fail; 7758c2ecf20Sopenharmony_ci } 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci if (authkeylen > bs) { 7788c2ecf20Sopenharmony_ci ret = crypto_shash_digest(&ctx->sdesc->shash, ctx->key, 7798c2ecf20Sopenharmony_ci authkeylen, ipad); 7808c2ecf20Sopenharmony_ci if (ret) 7818c2ecf20Sopenharmony_ci goto calc_fail; 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci authkeylen = ds; 7848c2ecf20Sopenharmony_ci } else { 7858c2ecf20Sopenharmony_ci memcpy(ipad, ctx->key, authkeylen); 7868c2ecf20Sopenharmony_ci } 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci memset(ipad + authkeylen, 0, bs - authkeylen); 7898c2ecf20Sopenharmony_ci memcpy(opad, ipad, bs); 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci for (icount = 0; icount < bs; icount++) { 7928c2ecf20Sopenharmony_ci ipad[icount] ^= 0x36; 7938c2ecf20Sopenharmony_ci opad[icount] ^= 0x5c; 7948c2ecf20Sopenharmony_ci } 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci /* 7978c2ecf20Sopenharmony_ci * Partial Hash calculated from the software 7988c2ecf20Sopenharmony_ci * algorithm is retrieved for IPAD & OPAD 7998c2ecf20Sopenharmony_ci */ 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci /* IPAD Calculation */ 8028c2ecf20Sopenharmony_ci crypto_shash_init(&ctx->sdesc->shash); 8038c2ecf20Sopenharmony_ci crypto_shash_update(&ctx->sdesc->shash, ipad, bs); 8048c2ecf20Sopenharmony_ci crypto_shash_export(&ctx->sdesc->shash, ipad); 8058c2ecf20Sopenharmony_ci ret = copy_pad(ctx->mac_type, ctx->ipad, ipad); 8068c2ecf20Sopenharmony_ci if (ret) 8078c2ecf20Sopenharmony_ci goto calc_fail; 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_ci /* OPAD Calculation */ 8108c2ecf20Sopenharmony_ci crypto_shash_init(&ctx->sdesc->shash); 8118c2ecf20Sopenharmony_ci crypto_shash_update(&ctx->sdesc->shash, opad, bs); 8128c2ecf20Sopenharmony_ci crypto_shash_export(&ctx->sdesc->shash, opad); 8138c2ecf20Sopenharmony_ci ret = copy_pad(ctx->mac_type, ctx->opad, opad); 8148c2ecf20Sopenharmony_ci if (ret) 8158c2ecf20Sopenharmony_ci goto calc_fail; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci kfree(ipad); 8188c2ecf20Sopenharmony_ci kfree(opad); 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci return 0; 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_cicalc_fail: 8238c2ecf20Sopenharmony_ci kfree(ctx->ipad); 8248c2ecf20Sopenharmony_ci ctx->ipad = NULL; 8258c2ecf20Sopenharmony_ci kfree(ctx->opad); 8268c2ecf20Sopenharmony_ci ctx->opad = NULL; 8278c2ecf20Sopenharmony_ci kfree(ipad); 8288c2ecf20Sopenharmony_ci kfree(opad); 8298c2ecf20Sopenharmony_ci kfree(ctx->sdesc); 8308c2ecf20Sopenharmony_ci ctx->sdesc = NULL; 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci return ret; 8338c2ecf20Sopenharmony_ci} 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_cistatic int otx_cpt_aead_cbc_aes_sha_setkey(struct crypto_aead *cipher, 8368c2ecf20Sopenharmony_ci const unsigned char *key, 8378c2ecf20Sopenharmony_ci unsigned int keylen) 8388c2ecf20Sopenharmony_ci{ 8398c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(cipher); 8408c2ecf20Sopenharmony_ci struct crypto_authenc_key_param *param; 8418c2ecf20Sopenharmony_ci int enckeylen = 0, authkeylen = 0; 8428c2ecf20Sopenharmony_ci struct rtattr *rta = (void *)key; 8438c2ecf20Sopenharmony_ci int status = -EINVAL; 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_ci if (!RTA_OK(rta, keylen)) 8468c2ecf20Sopenharmony_ci goto badkey; 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 8498c2ecf20Sopenharmony_ci goto badkey; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci if (RTA_PAYLOAD(rta) < sizeof(*param)) 8528c2ecf20Sopenharmony_ci goto badkey; 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ci param = RTA_DATA(rta); 8558c2ecf20Sopenharmony_ci enckeylen = be32_to_cpu(param->enckeylen); 8568c2ecf20Sopenharmony_ci key += RTA_ALIGN(rta->rta_len); 8578c2ecf20Sopenharmony_ci keylen -= RTA_ALIGN(rta->rta_len); 8588c2ecf20Sopenharmony_ci if (keylen < enckeylen) 8598c2ecf20Sopenharmony_ci goto badkey; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci if (keylen > OTX_CPT_MAX_KEY_SIZE) 8628c2ecf20Sopenharmony_ci goto badkey; 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci authkeylen = keylen - enckeylen; 8658c2ecf20Sopenharmony_ci memcpy(ctx->key, key, keylen); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci switch (enckeylen) { 8688c2ecf20Sopenharmony_ci case AES_KEYSIZE_128: 8698c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_128_BIT; 8708c2ecf20Sopenharmony_ci break; 8718c2ecf20Sopenharmony_ci case AES_KEYSIZE_192: 8728c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_192_BIT; 8738c2ecf20Sopenharmony_ci break; 8748c2ecf20Sopenharmony_ci case AES_KEYSIZE_256: 8758c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_256_BIT; 8768c2ecf20Sopenharmony_ci break; 8778c2ecf20Sopenharmony_ci default: 8788c2ecf20Sopenharmony_ci /* Invalid key length */ 8798c2ecf20Sopenharmony_ci goto badkey; 8808c2ecf20Sopenharmony_ci } 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ci ctx->enc_key_len = enckeylen; 8838c2ecf20Sopenharmony_ci ctx->auth_key_len = authkeylen; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci status = aead_hmac_init(cipher); 8868c2ecf20Sopenharmony_ci if (status) 8878c2ecf20Sopenharmony_ci goto badkey; 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci return 0; 8908c2ecf20Sopenharmony_cibadkey: 8918c2ecf20Sopenharmony_ci return status; 8928c2ecf20Sopenharmony_ci} 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_cistatic int otx_cpt_aead_ecb_null_sha_setkey(struct crypto_aead *cipher, 8958c2ecf20Sopenharmony_ci const unsigned char *key, 8968c2ecf20Sopenharmony_ci unsigned int keylen) 8978c2ecf20Sopenharmony_ci{ 8988c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(cipher); 8998c2ecf20Sopenharmony_ci struct crypto_authenc_key_param *param; 9008c2ecf20Sopenharmony_ci struct rtattr *rta = (void *)key; 9018c2ecf20Sopenharmony_ci int enckeylen = 0; 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci if (!RTA_OK(rta, keylen)) 9048c2ecf20Sopenharmony_ci goto badkey; 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 9078c2ecf20Sopenharmony_ci goto badkey; 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci if (RTA_PAYLOAD(rta) < sizeof(*param)) 9108c2ecf20Sopenharmony_ci goto badkey; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci param = RTA_DATA(rta); 9138c2ecf20Sopenharmony_ci enckeylen = be32_to_cpu(param->enckeylen); 9148c2ecf20Sopenharmony_ci key += RTA_ALIGN(rta->rta_len); 9158c2ecf20Sopenharmony_ci keylen -= RTA_ALIGN(rta->rta_len); 9168c2ecf20Sopenharmony_ci if (enckeylen != 0) 9178c2ecf20Sopenharmony_ci goto badkey; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci if (keylen > OTX_CPT_MAX_KEY_SIZE) 9208c2ecf20Sopenharmony_ci goto badkey; 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci memcpy(ctx->key, key, keylen); 9238c2ecf20Sopenharmony_ci ctx->enc_key_len = enckeylen; 9248c2ecf20Sopenharmony_ci ctx->auth_key_len = keylen; 9258c2ecf20Sopenharmony_ci return 0; 9268c2ecf20Sopenharmony_cibadkey: 9278c2ecf20Sopenharmony_ci return -EINVAL; 9288c2ecf20Sopenharmony_ci} 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_cistatic int otx_cpt_aead_gcm_aes_setkey(struct crypto_aead *cipher, 9318c2ecf20Sopenharmony_ci const unsigned char *key, 9328c2ecf20Sopenharmony_ci unsigned int keylen) 9338c2ecf20Sopenharmony_ci{ 9348c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(cipher); 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci /* 9378c2ecf20Sopenharmony_ci * For aes gcm we expect to get encryption key (16, 24, 32 bytes) 9388c2ecf20Sopenharmony_ci * and salt (4 bytes) 9398c2ecf20Sopenharmony_ci */ 9408c2ecf20Sopenharmony_ci switch (keylen) { 9418c2ecf20Sopenharmony_ci case AES_KEYSIZE_128 + AES_GCM_SALT_SIZE: 9428c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_128_BIT; 9438c2ecf20Sopenharmony_ci ctx->enc_key_len = AES_KEYSIZE_128; 9448c2ecf20Sopenharmony_ci break; 9458c2ecf20Sopenharmony_ci case AES_KEYSIZE_192 + AES_GCM_SALT_SIZE: 9468c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_192_BIT; 9478c2ecf20Sopenharmony_ci ctx->enc_key_len = AES_KEYSIZE_192; 9488c2ecf20Sopenharmony_ci break; 9498c2ecf20Sopenharmony_ci case AES_KEYSIZE_256 + AES_GCM_SALT_SIZE: 9508c2ecf20Sopenharmony_ci ctx->key_type = OTX_CPT_AES_256_BIT; 9518c2ecf20Sopenharmony_ci ctx->enc_key_len = AES_KEYSIZE_256; 9528c2ecf20Sopenharmony_ci break; 9538c2ecf20Sopenharmony_ci default: 9548c2ecf20Sopenharmony_ci /* Invalid key and salt length */ 9558c2ecf20Sopenharmony_ci return -EINVAL; 9568c2ecf20Sopenharmony_ci } 9578c2ecf20Sopenharmony_ci 9588c2ecf20Sopenharmony_ci /* Store encryption key and salt */ 9598c2ecf20Sopenharmony_ci memcpy(ctx->key, key, keylen); 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci return 0; 9628c2ecf20Sopenharmony_ci} 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_cistatic inline u32 create_aead_ctx_hdr(struct aead_request *req, u32 enc, 9658c2ecf20Sopenharmony_ci u32 *argcnt) 9668c2ecf20Sopenharmony_ci{ 9678c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 9688c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 9698c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(tfm); 9708c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 9718c2ecf20Sopenharmony_ci struct otx_cpt_fc_ctx *fctx = &rctx->fctx; 9728c2ecf20Sopenharmony_ci int mac_len = crypto_aead_authsize(tfm); 9738c2ecf20Sopenharmony_ci int ds; 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci rctx->ctrl_word.e.enc_data_offset = req->assoclen; 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci switch (ctx->cipher_type) { 9788c2ecf20Sopenharmony_ci case OTX_CPT_AES_CBC: 9798c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_CPTR; 9808c2ecf20Sopenharmony_ci /* Copy encryption key to context */ 9818c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->key + ctx->auth_key_len, 9828c2ecf20Sopenharmony_ci ctx->enc_key_len); 9838c2ecf20Sopenharmony_ci /* Copy IV to context */ 9848c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_iv, req->iv, crypto_aead_ivsize(tfm)); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci ds = crypto_shash_digestsize(ctx->hashalg); 9878c2ecf20Sopenharmony_ci if (ctx->mac_type == OTX_CPT_SHA384) 9888c2ecf20Sopenharmony_ci ds = SHA512_DIGEST_SIZE; 9898c2ecf20Sopenharmony_ci if (ctx->ipad) 9908c2ecf20Sopenharmony_ci memcpy(fctx->hmac.e.ipad, ctx->ipad, ds); 9918c2ecf20Sopenharmony_ci if (ctx->opad) 9928c2ecf20Sopenharmony_ci memcpy(fctx->hmac.e.opad, ctx->opad, ds); 9938c2ecf20Sopenharmony_ci break; 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci case OTX_CPT_AES_GCM: 9968c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.iv_source = OTX_CPT_FROM_DPTR; 9978c2ecf20Sopenharmony_ci /* Copy encryption key to context */ 9988c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->key, ctx->enc_key_len); 9998c2ecf20Sopenharmony_ci /* Copy salt to context */ 10008c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_iv, ctx->key + ctx->enc_key_len, 10018c2ecf20Sopenharmony_ci AES_GCM_SALT_SIZE); 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci rctx->ctrl_word.e.iv_offset = req->assoclen - AES_GCM_IV_OFFSET; 10048c2ecf20Sopenharmony_ci break; 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci default: 10078c2ecf20Sopenharmony_ci /* Unknown cipher type */ 10088c2ecf20Sopenharmony_ci return -EINVAL; 10098c2ecf20Sopenharmony_ci } 10108c2ecf20Sopenharmony_ci rctx->ctrl_word.flags = cpu_to_be64(rctx->ctrl_word.cflags); 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ci req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER; 10138c2ecf20Sopenharmony_ci req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ; 10148c2ecf20Sopenharmony_ci req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_FC | 10158c2ecf20Sopenharmony_ci DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER); 10168c2ecf20Sopenharmony_ci if (enc) { 10178c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 2; 10188c2ecf20Sopenharmony_ci req_info->req.param1 = req->cryptlen; 10198c2ecf20Sopenharmony_ci req_info->req.param2 = req->cryptlen + req->assoclen; 10208c2ecf20Sopenharmony_ci } else { 10218c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 3; 10228c2ecf20Sopenharmony_ci req_info->req.param1 = req->cryptlen - mac_len; 10238c2ecf20Sopenharmony_ci req_info->req.param2 = req->cryptlen + req->assoclen - mac_len; 10248c2ecf20Sopenharmony_ci } 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 10278c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 10288c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.mac_type = ctx->mac_type; 10298c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.mac_len = mac_len; 10308c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.flags = cpu_to_be64(fctx->enc.enc_ctrl.cflags); 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci /* 10338c2ecf20Sopenharmony_ci * Storing Packet Data Information in offset 10348c2ecf20Sopenharmony_ci * Control Word First 8 bytes 10358c2ecf20Sopenharmony_ci */ 10368c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)&rctx->ctrl_word; 10378c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = CONTROL_WORD_LEN; 10388c2ecf20Sopenharmony_ci req_info->req.dlen += CONTROL_WORD_LEN; 10398c2ecf20Sopenharmony_ci ++(*argcnt); 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)fctx; 10428c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = sizeof(struct otx_cpt_fc_ctx); 10438c2ecf20Sopenharmony_ci req_info->req.dlen += sizeof(struct otx_cpt_fc_ctx); 10448c2ecf20Sopenharmony_ci ++(*argcnt); 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci return 0; 10478c2ecf20Sopenharmony_ci} 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_cistatic inline u32 create_hmac_ctx_hdr(struct aead_request *req, u32 *argcnt, 10508c2ecf20Sopenharmony_ci u32 enc) 10518c2ecf20Sopenharmony_ci{ 10528c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 10538c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 10548c2ecf20Sopenharmony_ci struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx(tfm); 10558c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci req_info->ctrl.s.dma_mode = OTX_CPT_DMA_GATHER_SCATTER; 10588c2ecf20Sopenharmony_ci req_info->ctrl.s.se_req = OTX_CPT_SE_CORE_REQ; 10598c2ecf20Sopenharmony_ci req_info->req.opcode.s.major = OTX_CPT_MAJOR_OP_HMAC | 10608c2ecf20Sopenharmony_ci DMA_MODE_FLAG(OTX_CPT_DMA_GATHER_SCATTER); 10618c2ecf20Sopenharmony_ci req_info->is_trunc_hmac = ctx->is_trunc_hmac; 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 0; 10648c2ecf20Sopenharmony_ci req_info->req.param1 = ctx->auth_key_len; 10658c2ecf20Sopenharmony_ci req_info->req.param2 = ctx->mac_type << 8; 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci /* Add authentication key */ 10688c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = ctx->key; 10698c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = round_up(ctx->auth_key_len, 8); 10708c2ecf20Sopenharmony_ci req_info->req.dlen += round_up(ctx->auth_key_len, 8); 10718c2ecf20Sopenharmony_ci ++(*argcnt); 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_ci return 0; 10748c2ecf20Sopenharmony_ci} 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_cistatic inline u32 create_aead_input_list(struct aead_request *req, u32 enc) 10778c2ecf20Sopenharmony_ci{ 10788c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 10798c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 10808c2ecf20Sopenharmony_ci u32 inputlen = req->cryptlen + req->assoclen; 10818c2ecf20Sopenharmony_ci u32 status, argcnt = 0; 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ci status = create_aead_ctx_hdr(req, enc, &argcnt); 10848c2ecf20Sopenharmony_ci if (status) 10858c2ecf20Sopenharmony_ci return status; 10868c2ecf20Sopenharmony_ci update_input_data(req_info, req->src, inputlen, &argcnt); 10878c2ecf20Sopenharmony_ci req_info->incnt = argcnt; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci return 0; 10908c2ecf20Sopenharmony_ci} 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_cistatic inline u32 create_aead_output_list(struct aead_request *req, u32 enc, 10938c2ecf20Sopenharmony_ci u32 mac_len) 10948c2ecf20Sopenharmony_ci{ 10958c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 10968c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 10978c2ecf20Sopenharmony_ci u32 argcnt = 0, outputlen = 0; 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci if (enc) 11008c2ecf20Sopenharmony_ci outputlen = req->cryptlen + req->assoclen + mac_len; 11018c2ecf20Sopenharmony_ci else 11028c2ecf20Sopenharmony_ci outputlen = req->cryptlen + req->assoclen - mac_len; 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci update_output_data(req_info, req->dst, 0, outputlen, &argcnt); 11058c2ecf20Sopenharmony_ci req_info->outcnt = argcnt; 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci return 0; 11088c2ecf20Sopenharmony_ci} 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistatic inline u32 create_aead_null_input_list(struct aead_request *req, 11118c2ecf20Sopenharmony_ci u32 enc, u32 mac_len) 11128c2ecf20Sopenharmony_ci{ 11138c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 11148c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 11158c2ecf20Sopenharmony_ci u32 inputlen, argcnt = 0; 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci if (enc) 11188c2ecf20Sopenharmony_ci inputlen = req->cryptlen + req->assoclen; 11198c2ecf20Sopenharmony_ci else 11208c2ecf20Sopenharmony_ci inputlen = req->cryptlen + req->assoclen - mac_len; 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci create_hmac_ctx_hdr(req, &argcnt, enc); 11238c2ecf20Sopenharmony_ci update_input_data(req_info, req->src, inputlen, &argcnt); 11248c2ecf20Sopenharmony_ci req_info->incnt = argcnt; 11258c2ecf20Sopenharmony_ci 11268c2ecf20Sopenharmony_ci return 0; 11278c2ecf20Sopenharmony_ci} 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_cistatic inline u32 create_aead_null_output_list(struct aead_request *req, 11308c2ecf20Sopenharmony_ci u32 enc, u32 mac_len) 11318c2ecf20Sopenharmony_ci{ 11328c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 11338c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 11348c2ecf20Sopenharmony_ci struct scatterlist *dst; 11358c2ecf20Sopenharmony_ci u8 *ptr = NULL; 11368c2ecf20Sopenharmony_ci int argcnt = 0, status, offset; 11378c2ecf20Sopenharmony_ci u32 inputlen; 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_ci if (enc) 11408c2ecf20Sopenharmony_ci inputlen = req->cryptlen + req->assoclen; 11418c2ecf20Sopenharmony_ci else 11428c2ecf20Sopenharmony_ci inputlen = req->cryptlen + req->assoclen - mac_len; 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_ci /* 11458c2ecf20Sopenharmony_ci * If source and destination are different 11468c2ecf20Sopenharmony_ci * then copy payload to destination 11478c2ecf20Sopenharmony_ci */ 11488c2ecf20Sopenharmony_ci if (req->src != req->dst) { 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci ptr = kmalloc(inputlen, (req_info->areq->flags & 11518c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MAY_SLEEP) ? 11528c2ecf20Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC); 11538c2ecf20Sopenharmony_ci if (!ptr) { 11548c2ecf20Sopenharmony_ci status = -ENOMEM; 11558c2ecf20Sopenharmony_ci goto error; 11568c2ecf20Sopenharmony_ci } 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci status = sg_copy_to_buffer(req->src, sg_nents(req->src), ptr, 11598c2ecf20Sopenharmony_ci inputlen); 11608c2ecf20Sopenharmony_ci if (status != inputlen) { 11618c2ecf20Sopenharmony_ci status = -EINVAL; 11628c2ecf20Sopenharmony_ci goto error_free; 11638c2ecf20Sopenharmony_ci } 11648c2ecf20Sopenharmony_ci status = sg_copy_from_buffer(req->dst, sg_nents(req->dst), ptr, 11658c2ecf20Sopenharmony_ci inputlen); 11668c2ecf20Sopenharmony_ci if (status != inputlen) { 11678c2ecf20Sopenharmony_ci status = -EINVAL; 11688c2ecf20Sopenharmony_ci goto error_free; 11698c2ecf20Sopenharmony_ci } 11708c2ecf20Sopenharmony_ci kfree(ptr); 11718c2ecf20Sopenharmony_ci } 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci if (enc) { 11748c2ecf20Sopenharmony_ci /* 11758c2ecf20Sopenharmony_ci * In an encryption scenario hmac needs 11768c2ecf20Sopenharmony_ci * to be appended after payload 11778c2ecf20Sopenharmony_ci */ 11788c2ecf20Sopenharmony_ci dst = req->dst; 11798c2ecf20Sopenharmony_ci offset = inputlen; 11808c2ecf20Sopenharmony_ci while (offset >= dst->length) { 11818c2ecf20Sopenharmony_ci offset -= dst->length; 11828c2ecf20Sopenharmony_ci dst = sg_next(dst); 11838c2ecf20Sopenharmony_ci if (!dst) { 11848c2ecf20Sopenharmony_ci status = -ENOENT; 11858c2ecf20Sopenharmony_ci goto error; 11868c2ecf20Sopenharmony_ci } 11878c2ecf20Sopenharmony_ci } 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci update_output_data(req_info, dst, offset, mac_len, &argcnt); 11908c2ecf20Sopenharmony_ci } else { 11918c2ecf20Sopenharmony_ci /* 11928c2ecf20Sopenharmony_ci * In a decryption scenario calculated hmac for received 11938c2ecf20Sopenharmony_ci * payload needs to be compare with hmac received 11948c2ecf20Sopenharmony_ci */ 11958c2ecf20Sopenharmony_ci status = sg_copy_buffer(req->src, sg_nents(req->src), 11968c2ecf20Sopenharmony_ci rctx->fctx.hmac.s.hmac_recv, mac_len, 11978c2ecf20Sopenharmony_ci inputlen, true); 11988c2ecf20Sopenharmony_ci if (status != mac_len) { 11998c2ecf20Sopenharmony_ci status = -EINVAL; 12008c2ecf20Sopenharmony_ci goto error; 12018c2ecf20Sopenharmony_ci } 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci req_info->out[argcnt].vptr = rctx->fctx.hmac.s.hmac_calc; 12048c2ecf20Sopenharmony_ci req_info->out[argcnt].size = mac_len; 12058c2ecf20Sopenharmony_ci argcnt++; 12068c2ecf20Sopenharmony_ci } 12078c2ecf20Sopenharmony_ci 12088c2ecf20Sopenharmony_ci req_info->outcnt = argcnt; 12098c2ecf20Sopenharmony_ci return 0; 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_cierror_free: 12128c2ecf20Sopenharmony_ci kfree(ptr); 12138c2ecf20Sopenharmony_cierror: 12148c2ecf20Sopenharmony_ci return status; 12158c2ecf20Sopenharmony_ci} 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_cistatic u32 cpt_aead_enc_dec(struct aead_request *req, u8 reg_type, u8 enc) 12188c2ecf20Sopenharmony_ci{ 12198c2ecf20Sopenharmony_ci struct otx_cpt_req_ctx *rctx = aead_request_ctx(req); 12208c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req_info = &rctx->cpt_req; 12218c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 12228c2ecf20Sopenharmony_ci struct pci_dev *pdev; 12238c2ecf20Sopenharmony_ci u32 status, cpu_num; 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci /* Clear control words */ 12268c2ecf20Sopenharmony_ci rctx->ctrl_word.flags = 0; 12278c2ecf20Sopenharmony_ci rctx->fctx.enc.enc_ctrl.flags = 0; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci req_info->callback = otx_cpt_aead_callback; 12308c2ecf20Sopenharmony_ci req_info->areq = &req->base; 12318c2ecf20Sopenharmony_ci req_info->req_type = reg_type; 12328c2ecf20Sopenharmony_ci req_info->is_enc = enc; 12338c2ecf20Sopenharmony_ci req_info->is_trunc_hmac = false; 12348c2ecf20Sopenharmony_ci 12358c2ecf20Sopenharmony_ci switch (reg_type) { 12368c2ecf20Sopenharmony_ci case OTX_CPT_AEAD_ENC_DEC_REQ: 12378c2ecf20Sopenharmony_ci status = create_aead_input_list(req, enc); 12388c2ecf20Sopenharmony_ci if (status) 12398c2ecf20Sopenharmony_ci return status; 12408c2ecf20Sopenharmony_ci status = create_aead_output_list(req, enc, 12418c2ecf20Sopenharmony_ci crypto_aead_authsize(tfm)); 12428c2ecf20Sopenharmony_ci if (status) 12438c2ecf20Sopenharmony_ci return status; 12448c2ecf20Sopenharmony_ci break; 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci case OTX_CPT_AEAD_ENC_DEC_NULL_REQ: 12478c2ecf20Sopenharmony_ci status = create_aead_null_input_list(req, enc, 12488c2ecf20Sopenharmony_ci crypto_aead_authsize(tfm)); 12498c2ecf20Sopenharmony_ci if (status) 12508c2ecf20Sopenharmony_ci return status; 12518c2ecf20Sopenharmony_ci status = create_aead_null_output_list(req, enc, 12528c2ecf20Sopenharmony_ci crypto_aead_authsize(tfm)); 12538c2ecf20Sopenharmony_ci if (status) 12548c2ecf20Sopenharmony_ci return status; 12558c2ecf20Sopenharmony_ci break; 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci default: 12588c2ecf20Sopenharmony_ci return -EINVAL; 12598c2ecf20Sopenharmony_ci } 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ci /* Validate that request doesn't exceed maximum CPT supported size */ 12628c2ecf20Sopenharmony_ci if (req_info->req.param1 > OTX_CPT_MAX_REQ_SIZE || 12638c2ecf20Sopenharmony_ci req_info->req.param2 > OTX_CPT_MAX_REQ_SIZE) 12648c2ecf20Sopenharmony_ci return -E2BIG; 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci status = get_se_device(&pdev, &cpu_num); 12678c2ecf20Sopenharmony_ci if (status) 12688c2ecf20Sopenharmony_ci return status; 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci req_info->ctrl.s.grp = 0; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci status = otx_cpt_do_request(pdev, req_info, cpu_num); 12738c2ecf20Sopenharmony_ci /* 12748c2ecf20Sopenharmony_ci * We perform an asynchronous send and once 12758c2ecf20Sopenharmony_ci * the request is completed the driver would 12768c2ecf20Sopenharmony_ci * intimate through registered call back functions 12778c2ecf20Sopenharmony_ci */ 12788c2ecf20Sopenharmony_ci return status; 12798c2ecf20Sopenharmony_ci} 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_cistatic int otx_cpt_aead_encrypt(struct aead_request *req) 12828c2ecf20Sopenharmony_ci{ 12838c2ecf20Sopenharmony_ci return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_REQ, true); 12848c2ecf20Sopenharmony_ci} 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_cistatic int otx_cpt_aead_decrypt(struct aead_request *req) 12878c2ecf20Sopenharmony_ci{ 12888c2ecf20Sopenharmony_ci return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_REQ, false); 12898c2ecf20Sopenharmony_ci} 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_cistatic int otx_cpt_aead_null_encrypt(struct aead_request *req) 12928c2ecf20Sopenharmony_ci{ 12938c2ecf20Sopenharmony_ci return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_NULL_REQ, true); 12948c2ecf20Sopenharmony_ci} 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_cistatic int otx_cpt_aead_null_decrypt(struct aead_request *req) 12978c2ecf20Sopenharmony_ci{ 12988c2ecf20Sopenharmony_ci return cpt_aead_enc_dec(req, OTX_CPT_AEAD_ENC_DEC_NULL_REQ, false); 12998c2ecf20Sopenharmony_ci} 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_cistatic struct skcipher_alg otx_cpt_skciphers[] = { { 13028c2ecf20Sopenharmony_ci .base.cra_name = "xts(aes)", 13038c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_xts_aes", 13048c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13058c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 13068c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx), 13078c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13088c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13098c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13108c2ecf20Sopenharmony_ci 13118c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13128c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13138c2ecf20Sopenharmony_ci .min_keysize = 2 * AES_MIN_KEY_SIZE, 13148c2ecf20Sopenharmony_ci .max_keysize = 2 * AES_MAX_KEY_SIZE, 13158c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_xts_setkey, 13168c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 13178c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 13188c2ecf20Sopenharmony_ci}, { 13198c2ecf20Sopenharmony_ci .base.cra_name = "cbc(aes)", 13208c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_cbc_aes", 13218c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13228c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 13238c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx), 13248c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13258c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13268c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13298c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13308c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13318c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13328c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_cbc_aes_setkey, 13338c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 13348c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 13358c2ecf20Sopenharmony_ci}, { 13368c2ecf20Sopenharmony_ci .base.cra_name = "ecb(aes)", 13378c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_ecb_aes", 13388c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13398c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 13408c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx), 13418c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13428c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13438c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13468c2ecf20Sopenharmony_ci .ivsize = 0, 13478c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13488c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13498c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_ecb_aes_setkey, 13508c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 13518c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 13528c2ecf20Sopenharmony_ci}, { 13538c2ecf20Sopenharmony_ci .base.cra_name = "cfb(aes)", 13548c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_cfb_aes", 13558c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13568c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 13578c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_enc_ctx), 13588c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13598c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13608c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13638c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13648c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13658c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13668c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_cfb_aes_setkey, 13678c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 13688c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 13698c2ecf20Sopenharmony_ci}, { 13708c2ecf20Sopenharmony_ci .base.cra_name = "cbc(des3_ede)", 13718c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_cbc_des3_ede", 13728c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13738c2ecf20Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 13748c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_des3_ctx), 13758c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13768c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13778c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13808c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 13818c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 13828c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 13838c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_cbc_des3_setkey, 13848c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 13858c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 13868c2ecf20Sopenharmony_ci}, { 13878c2ecf20Sopenharmony_ci .base.cra_name = "ecb(des3_ede)", 13888c2ecf20Sopenharmony_ci .base.cra_driver_name = "cpt_ecb_des3_ede", 13898c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 13908c2ecf20Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 13918c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct otx_cpt_des3_ctx), 13928c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 13938c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 13948c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci .init = otx_cpt_enc_dec_init, 13978c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 13988c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 13998c2ecf20Sopenharmony_ci .ivsize = 0, 14008c2ecf20Sopenharmony_ci .setkey = otx_cpt_skcipher_ecb_des3_setkey, 14018c2ecf20Sopenharmony_ci .encrypt = otx_cpt_skcipher_encrypt, 14028c2ecf20Sopenharmony_ci .decrypt = otx_cpt_skcipher_decrypt, 14038c2ecf20Sopenharmony_ci} }; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_cistatic struct aead_alg otx_cpt_aeads[] = { { 14068c2ecf20Sopenharmony_ci .base = { 14078c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(aes))", 14088c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha1_cbc_aes", 14098c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 14108c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 14118c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 14128c2ecf20Sopenharmony_ci .cra_priority = 4001, 14138c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14148c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14158c2ecf20Sopenharmony_ci }, 14168c2ecf20Sopenharmony_ci .init = otx_cpt_aead_cbc_aes_sha1_init, 14178c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 14188c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_cbc_aes_sha_setkey, 14198c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 14208c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_encrypt, 14218c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_decrypt, 14228c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 14238c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 14248c2ecf20Sopenharmony_ci}, { 14258c2ecf20Sopenharmony_ci .base = { 14268c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(aes))", 14278c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha256_cbc_aes", 14288c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 14298c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 14308c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 14318c2ecf20Sopenharmony_ci .cra_priority = 4001, 14328c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14338c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14348c2ecf20Sopenharmony_ci }, 14358c2ecf20Sopenharmony_ci .init = otx_cpt_aead_cbc_aes_sha256_init, 14368c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 14378c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_cbc_aes_sha_setkey, 14388c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 14398c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_encrypt, 14408c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_decrypt, 14418c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 14428c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 14438c2ecf20Sopenharmony_ci}, { 14448c2ecf20Sopenharmony_ci .base = { 14458c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(aes))", 14468c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha384_cbc_aes", 14478c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 14488c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 14498c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 14508c2ecf20Sopenharmony_ci .cra_priority = 4001, 14518c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14528c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14538c2ecf20Sopenharmony_ci }, 14548c2ecf20Sopenharmony_ci .init = otx_cpt_aead_cbc_aes_sha384_init, 14558c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 14568c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_cbc_aes_sha_setkey, 14578c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 14588c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_encrypt, 14598c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_decrypt, 14608c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 14618c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 14628c2ecf20Sopenharmony_ci}, { 14638c2ecf20Sopenharmony_ci .base = { 14648c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(aes))", 14658c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha512_cbc_aes", 14668c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 14678c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 14688c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 14698c2ecf20Sopenharmony_ci .cra_priority = 4001, 14708c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14718c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14728c2ecf20Sopenharmony_ci }, 14738c2ecf20Sopenharmony_ci .init = otx_cpt_aead_cbc_aes_sha512_init, 14748c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 14758c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_cbc_aes_sha_setkey, 14768c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 14778c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_encrypt, 14788c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_decrypt, 14798c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 14808c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 14818c2ecf20Sopenharmony_ci}, { 14828c2ecf20Sopenharmony_ci .base = { 14838c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),ecb(cipher_null))", 14848c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha1_ecb_null", 14858c2ecf20Sopenharmony_ci .cra_blocksize = 1, 14868c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 14878c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 14888c2ecf20Sopenharmony_ci .cra_priority = 4001, 14898c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14908c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14918c2ecf20Sopenharmony_ci }, 14928c2ecf20Sopenharmony_ci .init = otx_cpt_aead_ecb_null_sha1_init, 14938c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 14948c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_ecb_null_sha_setkey, 14958c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 14968c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_null_encrypt, 14978c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_null_decrypt, 14988c2ecf20Sopenharmony_ci .ivsize = 0, 14998c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 15008c2ecf20Sopenharmony_ci}, { 15018c2ecf20Sopenharmony_ci .base = { 15028c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),ecb(cipher_null))", 15038c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha256_ecb_null", 15048c2ecf20Sopenharmony_ci .cra_blocksize = 1, 15058c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 15068c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 15078c2ecf20Sopenharmony_ci .cra_priority = 4001, 15088c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15098c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15108c2ecf20Sopenharmony_ci }, 15118c2ecf20Sopenharmony_ci .init = otx_cpt_aead_ecb_null_sha256_init, 15128c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 15138c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_ecb_null_sha_setkey, 15148c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 15158c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_null_encrypt, 15168c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_null_decrypt, 15178c2ecf20Sopenharmony_ci .ivsize = 0, 15188c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 15198c2ecf20Sopenharmony_ci}, { 15208c2ecf20Sopenharmony_ci .base = { 15218c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),ecb(cipher_null))", 15228c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha384_ecb_null", 15238c2ecf20Sopenharmony_ci .cra_blocksize = 1, 15248c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 15258c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 15268c2ecf20Sopenharmony_ci .cra_priority = 4001, 15278c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15288c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15298c2ecf20Sopenharmony_ci }, 15308c2ecf20Sopenharmony_ci .init = otx_cpt_aead_ecb_null_sha384_init, 15318c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 15328c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_ecb_null_sha_setkey, 15338c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 15348c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_null_encrypt, 15358c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_null_decrypt, 15368c2ecf20Sopenharmony_ci .ivsize = 0, 15378c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 15388c2ecf20Sopenharmony_ci}, { 15398c2ecf20Sopenharmony_ci .base = { 15408c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),ecb(cipher_null))", 15418c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_hmac_sha512_ecb_null", 15428c2ecf20Sopenharmony_ci .cra_blocksize = 1, 15438c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 15448c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 15458c2ecf20Sopenharmony_ci .cra_priority = 4001, 15468c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15478c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15488c2ecf20Sopenharmony_ci }, 15498c2ecf20Sopenharmony_ci .init = otx_cpt_aead_ecb_null_sha512_init, 15508c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 15518c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_ecb_null_sha_setkey, 15528c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 15538c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_null_encrypt, 15548c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_null_decrypt, 15558c2ecf20Sopenharmony_ci .ivsize = 0, 15568c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 15578c2ecf20Sopenharmony_ci}, { 15588c2ecf20Sopenharmony_ci .base = { 15598c2ecf20Sopenharmony_ci .cra_name = "rfc4106(gcm(aes))", 15608c2ecf20Sopenharmony_ci .cra_driver_name = "cpt_rfc4106_gcm_aes", 15618c2ecf20Sopenharmony_ci .cra_blocksize = 1, 15628c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 15638c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct otx_cpt_aead_ctx), 15648c2ecf20Sopenharmony_ci .cra_priority = 4001, 15658c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15668c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15678c2ecf20Sopenharmony_ci }, 15688c2ecf20Sopenharmony_ci .init = otx_cpt_aead_gcm_aes_init, 15698c2ecf20Sopenharmony_ci .exit = otx_cpt_aead_exit, 15708c2ecf20Sopenharmony_ci .setkey = otx_cpt_aead_gcm_aes_setkey, 15718c2ecf20Sopenharmony_ci .setauthsize = otx_cpt_aead_set_authsize, 15728c2ecf20Sopenharmony_ci .encrypt = otx_cpt_aead_encrypt, 15738c2ecf20Sopenharmony_ci .decrypt = otx_cpt_aead_decrypt, 15748c2ecf20Sopenharmony_ci .ivsize = AES_GCM_IV_SIZE, 15758c2ecf20Sopenharmony_ci .maxauthsize = AES_GCM_ICV_SIZE, 15768c2ecf20Sopenharmony_ci} }; 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_cistatic inline int is_any_alg_used(void) 15798c2ecf20Sopenharmony_ci{ 15808c2ecf20Sopenharmony_ci int i; 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(otx_cpt_skciphers); i++) 15838c2ecf20Sopenharmony_ci if (refcount_read(&otx_cpt_skciphers[i].base.cra_refcnt) != 1) 15848c2ecf20Sopenharmony_ci return true; 15858c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(otx_cpt_aeads); i++) 15868c2ecf20Sopenharmony_ci if (refcount_read(&otx_cpt_aeads[i].base.cra_refcnt) != 1) 15878c2ecf20Sopenharmony_ci return true; 15888c2ecf20Sopenharmony_ci return false; 15898c2ecf20Sopenharmony_ci} 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_cistatic inline int cpt_register_algs(void) 15928c2ecf20Sopenharmony_ci{ 15938c2ecf20Sopenharmony_ci int i, err = 0; 15948c2ecf20Sopenharmony_ci 15958c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_DM_CRYPT)) { 15968c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(otx_cpt_skciphers); i++) 15978c2ecf20Sopenharmony_ci otx_cpt_skciphers[i].base.cra_flags &= ~CRYPTO_ALG_DEAD; 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_ci err = crypto_register_skciphers(otx_cpt_skciphers, 16008c2ecf20Sopenharmony_ci ARRAY_SIZE(otx_cpt_skciphers)); 16018c2ecf20Sopenharmony_ci if (err) 16028c2ecf20Sopenharmony_ci return err; 16038c2ecf20Sopenharmony_ci } 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(otx_cpt_aeads); i++) 16068c2ecf20Sopenharmony_ci otx_cpt_aeads[i].base.cra_flags &= ~CRYPTO_ALG_DEAD; 16078c2ecf20Sopenharmony_ci 16088c2ecf20Sopenharmony_ci err = crypto_register_aeads(otx_cpt_aeads, ARRAY_SIZE(otx_cpt_aeads)); 16098c2ecf20Sopenharmony_ci if (err) { 16108c2ecf20Sopenharmony_ci crypto_unregister_skciphers(otx_cpt_skciphers, 16118c2ecf20Sopenharmony_ci ARRAY_SIZE(otx_cpt_skciphers)); 16128c2ecf20Sopenharmony_ci return err; 16138c2ecf20Sopenharmony_ci } 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci return 0; 16168c2ecf20Sopenharmony_ci} 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_cistatic inline void cpt_unregister_algs(void) 16198c2ecf20Sopenharmony_ci{ 16208c2ecf20Sopenharmony_ci crypto_unregister_skciphers(otx_cpt_skciphers, 16218c2ecf20Sopenharmony_ci ARRAY_SIZE(otx_cpt_skciphers)); 16228c2ecf20Sopenharmony_ci crypto_unregister_aeads(otx_cpt_aeads, ARRAY_SIZE(otx_cpt_aeads)); 16238c2ecf20Sopenharmony_ci} 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_cistatic int compare_func(const void *lptr, const void *rptr) 16268c2ecf20Sopenharmony_ci{ 16278c2ecf20Sopenharmony_ci struct cpt_device_desc *ldesc = (struct cpt_device_desc *) lptr; 16288c2ecf20Sopenharmony_ci struct cpt_device_desc *rdesc = (struct cpt_device_desc *) rptr; 16298c2ecf20Sopenharmony_ci 16308c2ecf20Sopenharmony_ci if (ldesc->dev->devfn < rdesc->dev->devfn) 16318c2ecf20Sopenharmony_ci return -1; 16328c2ecf20Sopenharmony_ci if (ldesc->dev->devfn > rdesc->dev->devfn) 16338c2ecf20Sopenharmony_ci return 1; 16348c2ecf20Sopenharmony_ci return 0; 16358c2ecf20Sopenharmony_ci} 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_cistatic void swap_func(void *lptr, void *rptr, int size) 16388c2ecf20Sopenharmony_ci{ 16398c2ecf20Sopenharmony_ci struct cpt_device_desc *ldesc = (struct cpt_device_desc *) lptr; 16408c2ecf20Sopenharmony_ci struct cpt_device_desc *rdesc = (struct cpt_device_desc *) rptr; 16418c2ecf20Sopenharmony_ci struct cpt_device_desc desc; 16428c2ecf20Sopenharmony_ci 16438c2ecf20Sopenharmony_ci desc = *ldesc; 16448c2ecf20Sopenharmony_ci *ldesc = *rdesc; 16458c2ecf20Sopenharmony_ci *rdesc = desc; 16468c2ecf20Sopenharmony_ci} 16478c2ecf20Sopenharmony_ci 16488c2ecf20Sopenharmony_ciint otx_cpt_crypto_init(struct pci_dev *pdev, struct module *mod, 16498c2ecf20Sopenharmony_ci enum otx_cptpf_type pf_type, 16508c2ecf20Sopenharmony_ci enum otx_cptvf_type engine_type, 16518c2ecf20Sopenharmony_ci int num_queues, int num_devices) 16528c2ecf20Sopenharmony_ci{ 16538c2ecf20Sopenharmony_ci int ret = 0; 16548c2ecf20Sopenharmony_ci int count; 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci mutex_lock(&mutex); 16578c2ecf20Sopenharmony_ci switch (engine_type) { 16588c2ecf20Sopenharmony_ci case OTX_CPT_SE_TYPES: 16598c2ecf20Sopenharmony_ci count = atomic_read(&se_devices.count); 16608c2ecf20Sopenharmony_ci if (count >= CPT_MAX_VF_NUM) { 16618c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "No space to add a new device\n"); 16628c2ecf20Sopenharmony_ci ret = -ENOSPC; 16638c2ecf20Sopenharmony_ci goto err; 16648c2ecf20Sopenharmony_ci } 16658c2ecf20Sopenharmony_ci se_devices.desc[count].pf_type = pf_type; 16668c2ecf20Sopenharmony_ci se_devices.desc[count].num_queues = num_queues; 16678c2ecf20Sopenharmony_ci se_devices.desc[count++].dev = pdev; 16688c2ecf20Sopenharmony_ci atomic_inc(&se_devices.count); 16698c2ecf20Sopenharmony_ci 16708c2ecf20Sopenharmony_ci if (atomic_read(&se_devices.count) == num_devices && 16718c2ecf20Sopenharmony_ci is_crypto_registered == false) { 16728c2ecf20Sopenharmony_ci if (cpt_register_algs()) { 16738c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 16748c2ecf20Sopenharmony_ci "Error in registering crypto algorithms\n"); 16758c2ecf20Sopenharmony_ci ret = -EINVAL; 16768c2ecf20Sopenharmony_ci goto err; 16778c2ecf20Sopenharmony_ci } 16788c2ecf20Sopenharmony_ci try_module_get(mod); 16798c2ecf20Sopenharmony_ci is_crypto_registered = true; 16808c2ecf20Sopenharmony_ci } 16818c2ecf20Sopenharmony_ci sort(se_devices.desc, count, sizeof(struct cpt_device_desc), 16828c2ecf20Sopenharmony_ci compare_func, swap_func); 16838c2ecf20Sopenharmony_ci break; 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci case OTX_CPT_AE_TYPES: 16868c2ecf20Sopenharmony_ci count = atomic_read(&ae_devices.count); 16878c2ecf20Sopenharmony_ci if (count >= CPT_MAX_VF_NUM) { 16888c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "No space to a add new device\n"); 16898c2ecf20Sopenharmony_ci ret = -ENOSPC; 16908c2ecf20Sopenharmony_ci goto err; 16918c2ecf20Sopenharmony_ci } 16928c2ecf20Sopenharmony_ci ae_devices.desc[count].pf_type = pf_type; 16938c2ecf20Sopenharmony_ci ae_devices.desc[count].num_queues = num_queues; 16948c2ecf20Sopenharmony_ci ae_devices.desc[count++].dev = pdev; 16958c2ecf20Sopenharmony_ci atomic_inc(&ae_devices.count); 16968c2ecf20Sopenharmony_ci sort(ae_devices.desc, count, sizeof(struct cpt_device_desc), 16978c2ecf20Sopenharmony_ci compare_func, swap_func); 16988c2ecf20Sopenharmony_ci break; 16998c2ecf20Sopenharmony_ci 17008c2ecf20Sopenharmony_ci default: 17018c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Unknown VF type %d\n", engine_type); 17028c2ecf20Sopenharmony_ci ret = BAD_OTX_CPTVF_TYPE; 17038c2ecf20Sopenharmony_ci } 17048c2ecf20Sopenharmony_cierr: 17058c2ecf20Sopenharmony_ci mutex_unlock(&mutex); 17068c2ecf20Sopenharmony_ci return ret; 17078c2ecf20Sopenharmony_ci} 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_civoid otx_cpt_crypto_exit(struct pci_dev *pdev, struct module *mod, 17108c2ecf20Sopenharmony_ci enum otx_cptvf_type engine_type) 17118c2ecf20Sopenharmony_ci{ 17128c2ecf20Sopenharmony_ci struct cpt_device_table *dev_tbl; 17138c2ecf20Sopenharmony_ci bool dev_found = false; 17148c2ecf20Sopenharmony_ci int i, j, count; 17158c2ecf20Sopenharmony_ci 17168c2ecf20Sopenharmony_ci mutex_lock(&mutex); 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_ci dev_tbl = (engine_type == OTX_CPT_AE_TYPES) ? &ae_devices : &se_devices; 17198c2ecf20Sopenharmony_ci count = atomic_read(&dev_tbl->count); 17208c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) 17218c2ecf20Sopenharmony_ci if (pdev == dev_tbl->desc[i].dev) { 17228c2ecf20Sopenharmony_ci for (j = i; j < count-1; j++) 17238c2ecf20Sopenharmony_ci dev_tbl->desc[j] = dev_tbl->desc[j+1]; 17248c2ecf20Sopenharmony_ci dev_found = true; 17258c2ecf20Sopenharmony_ci break; 17268c2ecf20Sopenharmony_ci } 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci if (!dev_found) { 17298c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s device not found\n", __func__); 17308c2ecf20Sopenharmony_ci goto exit; 17318c2ecf20Sopenharmony_ci } 17328c2ecf20Sopenharmony_ci 17338c2ecf20Sopenharmony_ci if (engine_type != OTX_CPT_AE_TYPES) { 17348c2ecf20Sopenharmony_ci if (atomic_dec_and_test(&se_devices.count) && 17358c2ecf20Sopenharmony_ci !is_any_alg_used()) { 17368c2ecf20Sopenharmony_ci cpt_unregister_algs(); 17378c2ecf20Sopenharmony_ci module_put(mod); 17388c2ecf20Sopenharmony_ci is_crypto_registered = false; 17398c2ecf20Sopenharmony_ci } 17408c2ecf20Sopenharmony_ci } else 17418c2ecf20Sopenharmony_ci atomic_dec(&ae_devices.count); 17428c2ecf20Sopenharmony_ciexit: 17438c2ecf20Sopenharmony_ci mutex_unlock(&mutex); 17448c2ecf20Sopenharmony_ci} 1745