13b1fa94aSNagadheeraj Rottela /* SPDX-License-Identifier: BSD-3-Clause 23b1fa94aSNagadheeraj Rottela * Copyright(C) 2019 Marvell International Ltd. 33b1fa94aSNagadheeraj Rottela */ 43b1fa94aSNagadheeraj Rottela 53b1fa94aSNagadheeraj Rottela #include <rte_crypto.h> 692cb1309SAkhil Goyal #include <cryptodev_pmd.h> 71acffa39SNagadheeraj Rottela #include <rte_cycles.h> 83b1fa94aSNagadheeraj Rottela #include <rte_errno.h> 93b1fa94aSNagadheeraj Rottela 103b1fa94aSNagadheeraj Rottela #include "nitrox_sym_reqmgr.h" 113b1fa94aSNagadheeraj Rottela #include "nitrox_logs.h" 123b1fa94aSNagadheeraj Rottela 134a469e12SNagadheeraj Rottela #define MAX_SUPPORTED_MBUF_SEGS 16 144a469e12SNagadheeraj Rottela /* IV + AAD + ORH + CC + DIGEST */ 154a469e12SNagadheeraj Rottela #define ADDITIONAL_SGBUF_CNT 5 164a469e12SNagadheeraj Rottela #define MAX_SGBUF_CNT (MAX_SUPPORTED_MBUF_SEGS + ADDITIONAL_SGBUF_CNT) 174a469e12SNagadheeraj Rottela #define MAX_SGCOMP_CNT (RTE_ALIGN_MUL_CEIL(MAX_SGBUF_CNT, 4) / 4) 189282bdeeSNagadheeraj Rottela /* SLC_STORE_INFO */ 199282bdeeSNagadheeraj Rottela #define MIN_UDD_LEN 16 209282bdeeSNagadheeraj Rottela /* PKT_IN_HDR + SLC_STORE_INFO */ 219282bdeeSNagadheeraj Rottela #define FDATA_SIZE 32 229282bdeeSNagadheeraj Rottela /* Base destination port for the solicited requests */ 239282bdeeSNagadheeraj Rottela #define SOLICIT_BASE_DPORT 256 241acffa39SNagadheeraj Rottela #define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL 251acffa39SNagadheeraj Rottela #define CMD_TIMEOUT 2 2660531a2cSNagadheeraj Rottela /* For AES_CCM actual AAD will be copied 18 bytes after the AAD pointer, according to the API */ 2760531a2cSNagadheeraj Rottela #define DPDK_AES_CCM_ADD_OFFSET 18 281acffa39SNagadheeraj Rottela 299282bdeeSNagadheeraj Rottela struct gphdr { 309282bdeeSNagadheeraj Rottela uint16_t param0; 319282bdeeSNagadheeraj Rottela uint16_t param1; 329282bdeeSNagadheeraj Rottela uint16_t param2; 339282bdeeSNagadheeraj Rottela uint16_t param3; 349282bdeeSNagadheeraj Rottela }; 359282bdeeSNagadheeraj Rottela 361acffa39SNagadheeraj Rottela union pkt_instr_hdr { 371acffa39SNagadheeraj Rottela uint64_t value; 381acffa39SNagadheeraj Rottela struct { 391acffa39SNagadheeraj Rottela #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 401acffa39SNagadheeraj Rottela uint64_t raz_48_63 : 16; 411acffa39SNagadheeraj Rottela uint64_t g : 1; 421acffa39SNagadheeraj Rottela uint64_t gsz : 7; 431acffa39SNagadheeraj Rottela uint64_t ihi : 1; 441acffa39SNagadheeraj Rottela uint64_t ssz : 7; 451acffa39SNagadheeraj Rottela uint64_t raz_30_31 : 2; 461acffa39SNagadheeraj Rottela uint64_t fsz : 6; 471acffa39SNagadheeraj Rottela uint64_t raz_16_23 : 8; 481acffa39SNagadheeraj Rottela uint64_t tlen : 16; 491acffa39SNagadheeraj Rottela #else 501acffa39SNagadheeraj Rottela uint64_t tlen : 16; 511acffa39SNagadheeraj Rottela uint64_t raz_16_23 : 8; 521acffa39SNagadheeraj Rottela uint64_t fsz : 6; 531acffa39SNagadheeraj Rottela uint64_t raz_30_31 : 2; 541acffa39SNagadheeraj Rottela uint64_t ssz : 7; 551acffa39SNagadheeraj Rottela uint64_t ihi : 1; 561acffa39SNagadheeraj Rottela uint64_t gsz : 7; 571acffa39SNagadheeraj Rottela uint64_t g : 1; 581acffa39SNagadheeraj Rottela uint64_t raz_48_63 : 16; 591acffa39SNagadheeraj Rottela #endif 601acffa39SNagadheeraj Rottela } s; 611acffa39SNagadheeraj Rottela }; 621acffa39SNagadheeraj Rottela 631acffa39SNagadheeraj Rottela union pkt_hdr { 641acffa39SNagadheeraj Rottela uint64_t value[2]; 651acffa39SNagadheeraj Rottela struct { 661acffa39SNagadheeraj Rottela #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 671acffa39SNagadheeraj Rottela uint64_t opcode : 8; 681acffa39SNagadheeraj Rottela uint64_t arg : 8; 691acffa39SNagadheeraj Rottela uint64_t ctxc : 2; 701acffa39SNagadheeraj Rottela uint64_t unca : 1; 711acffa39SNagadheeraj Rottela uint64_t raz_44 : 1; 721acffa39SNagadheeraj Rottela uint64_t info : 3; 731acffa39SNagadheeraj Rottela uint64_t destport : 9; 741acffa39SNagadheeraj Rottela uint64_t unc : 8; 751acffa39SNagadheeraj Rottela uint64_t raz_19_23 : 5; 761acffa39SNagadheeraj Rottela uint64_t grp : 3; 771acffa39SNagadheeraj Rottela uint64_t raz_15 : 1; 781acffa39SNagadheeraj Rottela uint64_t ctxl : 7; 791acffa39SNagadheeraj Rottela uint64_t uddl : 8; 801acffa39SNagadheeraj Rottela #else 811acffa39SNagadheeraj Rottela uint64_t uddl : 8; 821acffa39SNagadheeraj Rottela uint64_t ctxl : 7; 831acffa39SNagadheeraj Rottela uint64_t raz_15 : 1; 841acffa39SNagadheeraj Rottela uint64_t grp : 3; 851acffa39SNagadheeraj Rottela uint64_t raz_19_23 : 5; 861acffa39SNagadheeraj Rottela uint64_t unc : 8; 871acffa39SNagadheeraj Rottela uint64_t destport : 9; 881acffa39SNagadheeraj Rottela uint64_t info : 3; 891acffa39SNagadheeraj Rottela uint64_t raz_44 : 1; 901acffa39SNagadheeraj Rottela uint64_t unca : 1; 911acffa39SNagadheeraj Rottela uint64_t ctxc : 2; 921acffa39SNagadheeraj Rottela uint64_t arg : 8; 931acffa39SNagadheeraj Rottela uint64_t opcode : 8; 941acffa39SNagadheeraj Rottela #endif 951acffa39SNagadheeraj Rottela uint64_t ctxp; 961acffa39SNagadheeraj Rottela } s; 971acffa39SNagadheeraj Rottela }; 981acffa39SNagadheeraj Rottela 991acffa39SNagadheeraj Rottela union slc_store_info { 1001acffa39SNagadheeraj Rottela uint64_t value[2]; 1011acffa39SNagadheeraj Rottela struct { 1021acffa39SNagadheeraj Rottela #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 1031acffa39SNagadheeraj Rottela uint64_t raz_39_63 : 25; 1041acffa39SNagadheeraj Rottela uint64_t ssz : 7; 1051acffa39SNagadheeraj Rottela uint64_t raz_0_31 : 32; 1061acffa39SNagadheeraj Rottela #else 1071acffa39SNagadheeraj Rottela uint64_t raz_0_31 : 32; 1081acffa39SNagadheeraj Rottela uint64_t ssz : 7; 1091acffa39SNagadheeraj Rottela uint64_t raz_39_63 : 25; 1101acffa39SNagadheeraj Rottela #endif 1111acffa39SNagadheeraj Rottela uint64_t rptr; 1121acffa39SNagadheeraj Rottela } s; 1131acffa39SNagadheeraj Rottela }; 1141acffa39SNagadheeraj Rottela 1151acffa39SNagadheeraj Rottela struct nps_pkt_instr { 1161acffa39SNagadheeraj Rottela uint64_t dptr0; 1171acffa39SNagadheeraj Rottela union pkt_instr_hdr ih; 1181acffa39SNagadheeraj Rottela union pkt_hdr irh; 1191acffa39SNagadheeraj Rottela union slc_store_info slc; 1201acffa39SNagadheeraj Rottela uint64_t fdata[2]; 1211acffa39SNagadheeraj Rottela }; 1221acffa39SNagadheeraj Rottela 1231acffa39SNagadheeraj Rottela struct resp_hdr { 1241acffa39SNagadheeraj Rottela uint64_t orh; 1251acffa39SNagadheeraj Rottela uint64_t completion; 1261acffa39SNagadheeraj Rottela }; 1271acffa39SNagadheeraj Rottela 1289282bdeeSNagadheeraj Rottela struct nitrox_sglist { 1299282bdeeSNagadheeraj Rottela uint16_t len; 1309282bdeeSNagadheeraj Rottela uint16_t raz0; 1319282bdeeSNagadheeraj Rottela uint32_t raz1; 1329282bdeeSNagadheeraj Rottela rte_iova_t iova; 1339282bdeeSNagadheeraj Rottela void *virt; 1349282bdeeSNagadheeraj Rottela }; 1359282bdeeSNagadheeraj Rottela 1369282bdeeSNagadheeraj Rottela struct nitrox_sgcomp { 1379282bdeeSNagadheeraj Rottela uint16_t len[4]; 1389282bdeeSNagadheeraj Rottela uint64_t iova[4]; 1399282bdeeSNagadheeraj Rottela }; 1409282bdeeSNagadheeraj Rottela 1419282bdeeSNagadheeraj Rottela struct nitrox_sgtable { 1429282bdeeSNagadheeraj Rottela uint8_t map_bufs_cnt; 1439282bdeeSNagadheeraj Rottela uint8_t nr_sgcomp; 1449282bdeeSNagadheeraj Rottela uint16_t total_bytes; 1459282bdeeSNagadheeraj Rottela 1469282bdeeSNagadheeraj Rottela struct nitrox_sglist sglist[MAX_SGBUF_CNT]; 1479282bdeeSNagadheeraj Rottela struct nitrox_sgcomp sgcomp[MAX_SGCOMP_CNT]; 1489282bdeeSNagadheeraj Rottela }; 1499282bdeeSNagadheeraj Rottela 1509282bdeeSNagadheeraj Rottela struct iv { 1519282bdeeSNagadheeraj Rottela uint8_t *virt; 1529282bdeeSNagadheeraj Rottela rte_iova_t iova; 1539282bdeeSNagadheeraj Rottela uint16_t len; 1549282bdeeSNagadheeraj Rottela }; 1559282bdeeSNagadheeraj Rottela 1563b1fa94aSNagadheeraj Rottela struct nitrox_softreq { 1571acffa39SNagadheeraj Rottela struct nitrox_crypto_ctx *ctx; 1581acffa39SNagadheeraj Rottela struct rte_crypto_op *op; 1599282bdeeSNagadheeraj Rottela struct gphdr gph; 1601acffa39SNagadheeraj Rottela struct nps_pkt_instr instr; 1611acffa39SNagadheeraj Rottela struct resp_hdr resp; 1629282bdeeSNagadheeraj Rottela struct nitrox_sgtable in; 1639282bdeeSNagadheeraj Rottela struct nitrox_sgtable out; 1649282bdeeSNagadheeraj Rottela struct iv iv; 1651acffa39SNagadheeraj Rottela uint64_t timeout; 1669282bdeeSNagadheeraj Rottela rte_iova_t dptr; 1679282bdeeSNagadheeraj Rottela rte_iova_t rptr; 1683b1fa94aSNagadheeraj Rottela rte_iova_t iova; 1693b1fa94aSNagadheeraj Rottela }; 1703b1fa94aSNagadheeraj Rottela 1713b1fa94aSNagadheeraj Rottela static void 1723b1fa94aSNagadheeraj Rottela softreq_init(struct nitrox_softreq *sr, rte_iova_t iova) 1733b1fa94aSNagadheeraj Rottela { 1743b1fa94aSNagadheeraj Rottela memset(sr, 0, sizeof(*sr)); 1753b1fa94aSNagadheeraj Rottela sr->iova = iova; 1763b1fa94aSNagadheeraj Rottela } 1773b1fa94aSNagadheeraj Rottela 1789282bdeeSNagadheeraj Rottela /* 1799282bdeeSNagadheeraj Rottela * 64-Byte Instruction Format 1809282bdeeSNagadheeraj Rottela * 1819282bdeeSNagadheeraj Rottela * ---------------------- 1829282bdeeSNagadheeraj Rottela * | DPTR0 | 8 bytes 1839282bdeeSNagadheeraj Rottela * ---------------------- 1849282bdeeSNagadheeraj Rottela * | PKT_IN_INSTR_HDR | 8 bytes 1859282bdeeSNagadheeraj Rottela * ---------------------- 1869282bdeeSNagadheeraj Rottela * | PKT_IN_HDR | 16 bytes 1879282bdeeSNagadheeraj Rottela * ---------------------- 1889282bdeeSNagadheeraj Rottela * | SLC_INFO | 16 bytes 1899282bdeeSNagadheeraj Rottela * ---------------------- 1909282bdeeSNagadheeraj Rottela * | Front data | 16 bytes 1919282bdeeSNagadheeraj Rottela * ---------------------- 1929282bdeeSNagadheeraj Rottela */ 1939282bdeeSNagadheeraj Rottela static void 1949282bdeeSNagadheeraj Rottela create_se_instr(struct nitrox_softreq *sr, uint8_t qno) 1959282bdeeSNagadheeraj Rottela { 1969282bdeeSNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 1979282bdeeSNagadheeraj Rottela rte_iova_t ctx_handle; 1989282bdeeSNagadheeraj Rottela 1999282bdeeSNagadheeraj Rottela /* fill the packet instruction */ 2009282bdeeSNagadheeraj Rottela /* word 0 */ 2019282bdeeSNagadheeraj Rottela sr->instr.dptr0 = rte_cpu_to_be_64(sr->dptr); 2029282bdeeSNagadheeraj Rottela 2039282bdeeSNagadheeraj Rottela /* word 1 */ 2049282bdeeSNagadheeraj Rottela sr->instr.ih.value = 0; 2059282bdeeSNagadheeraj Rottela sr->instr.ih.s.g = 1; 2069282bdeeSNagadheeraj Rottela sr->instr.ih.s.gsz = sr->in.map_bufs_cnt; 2079282bdeeSNagadheeraj Rottela sr->instr.ih.s.ssz = sr->out.map_bufs_cnt; 2089282bdeeSNagadheeraj Rottela sr->instr.ih.s.fsz = FDATA_SIZE + sizeof(struct gphdr); 2099282bdeeSNagadheeraj Rottela sr->instr.ih.s.tlen = sr->instr.ih.s.fsz + sr->in.total_bytes; 2109282bdeeSNagadheeraj Rottela sr->instr.ih.value = rte_cpu_to_be_64(sr->instr.ih.value); 2119282bdeeSNagadheeraj Rottela 2129282bdeeSNagadheeraj Rottela /* word 2 */ 2139282bdeeSNagadheeraj Rottela sr->instr.irh.value[0] = 0; 2149282bdeeSNagadheeraj Rottela sr->instr.irh.s.uddl = MIN_UDD_LEN; 2159282bdeeSNagadheeraj Rottela /* context length in 64-bit words */ 2169282bdeeSNagadheeraj Rottela sr->instr.irh.s.ctxl = RTE_ALIGN_MUL_CEIL(sizeof(ctx->fctx), 8) / 8; 2179282bdeeSNagadheeraj Rottela /* offset from solicit base port 256 */ 2189282bdeeSNagadheeraj Rottela sr->instr.irh.s.destport = SOLICIT_BASE_DPORT + qno; 2199282bdeeSNagadheeraj Rottela /* Invalid context cache */ 2209282bdeeSNagadheeraj Rottela sr->instr.irh.s.ctxc = 0x3; 2219282bdeeSNagadheeraj Rottela sr->instr.irh.s.arg = ctx->req_op; 2229282bdeeSNagadheeraj Rottela sr->instr.irh.s.opcode = ctx->opcode; 2239282bdeeSNagadheeraj Rottela sr->instr.irh.value[0] = rte_cpu_to_be_64(sr->instr.irh.value[0]); 2249282bdeeSNagadheeraj Rottela 2259282bdeeSNagadheeraj Rottela /* word 3 */ 2269282bdeeSNagadheeraj Rottela ctx_handle = ctx->iova + offsetof(struct nitrox_crypto_ctx, fctx); 2279282bdeeSNagadheeraj Rottela sr->instr.irh.s.ctxp = rte_cpu_to_be_64(ctx_handle); 2289282bdeeSNagadheeraj Rottela 2299282bdeeSNagadheeraj Rottela /* word 4 */ 2309282bdeeSNagadheeraj Rottela sr->instr.slc.value[0] = 0; 2319282bdeeSNagadheeraj Rottela sr->instr.slc.s.ssz = sr->out.map_bufs_cnt; 2329282bdeeSNagadheeraj Rottela sr->instr.slc.value[0] = rte_cpu_to_be_64(sr->instr.slc.value[0]); 2339282bdeeSNagadheeraj Rottela 2349282bdeeSNagadheeraj Rottela /* word 5 */ 2359282bdeeSNagadheeraj Rottela sr->instr.slc.s.rptr = rte_cpu_to_be_64(sr->rptr); 2369282bdeeSNagadheeraj Rottela /* 2379282bdeeSNagadheeraj Rottela * No conversion for front data, 2389282bdeeSNagadheeraj Rottela * It goes into payload 2399282bdeeSNagadheeraj Rottela * put GP Header in front data 2409282bdeeSNagadheeraj Rottela */ 2419282bdeeSNagadheeraj Rottela memcpy(&sr->instr.fdata[0], &sr->gph, sizeof(sr->instr.fdata[0])); 2429282bdeeSNagadheeraj Rottela sr->instr.fdata[1] = 0; 2439282bdeeSNagadheeraj Rottela } 2449282bdeeSNagadheeraj Rottela 2459282bdeeSNagadheeraj Rottela static void 24693ba4a6eSNagadheeraj Rottela softreq_copy_iv(struct nitrox_softreq *sr, uint8_t salt_size) 2479282bdeeSNagadheeraj Rottela { 24893ba4a6eSNagadheeraj Rottela uint16_t offset = sr->ctx->iv.offset + salt_size; 24993ba4a6eSNagadheeraj Rottela 25093ba4a6eSNagadheeraj Rottela sr->iv.virt = rte_crypto_op_ctod_offset(sr->op, uint8_t *, offset); 25193ba4a6eSNagadheeraj Rottela sr->iv.iova = rte_crypto_op_ctophys_offset(sr->op, offset); 25293ba4a6eSNagadheeraj Rottela sr->iv.len = sr->ctx->iv.length - salt_size; 2539282bdeeSNagadheeraj Rottela } 2549282bdeeSNagadheeraj Rottela 2559282bdeeSNagadheeraj Rottela static void 2569282bdeeSNagadheeraj Rottela fill_sglist(struct nitrox_sgtable *sgtbl, uint16_t len, rte_iova_t iova, 2579282bdeeSNagadheeraj Rottela void *virt) 2589282bdeeSNagadheeraj Rottela { 2599282bdeeSNagadheeraj Rottela struct nitrox_sglist *sglist = sgtbl->sglist; 2609282bdeeSNagadheeraj Rottela uint8_t cnt = sgtbl->map_bufs_cnt; 2619282bdeeSNagadheeraj Rottela 2629282bdeeSNagadheeraj Rottela if (unlikely(!len)) 2639282bdeeSNagadheeraj Rottela return; 2649282bdeeSNagadheeraj Rottela 2659282bdeeSNagadheeraj Rottela sglist[cnt].len = len; 2669282bdeeSNagadheeraj Rottela sglist[cnt].iova = iova; 2679282bdeeSNagadheeraj Rottela sglist[cnt].virt = virt; 2689282bdeeSNagadheeraj Rottela sgtbl->total_bytes += len; 2699282bdeeSNagadheeraj Rottela cnt++; 2709282bdeeSNagadheeraj Rottela sgtbl->map_bufs_cnt = cnt; 2719282bdeeSNagadheeraj Rottela } 2729282bdeeSNagadheeraj Rottela 2739282bdeeSNagadheeraj Rottela static int 2749282bdeeSNagadheeraj Rottela create_sglist_from_mbuf(struct nitrox_sgtable *sgtbl, struct rte_mbuf *mbuf, 2759282bdeeSNagadheeraj Rottela uint32_t off, int datalen) 2769282bdeeSNagadheeraj Rottela { 2779282bdeeSNagadheeraj Rottela struct nitrox_sglist *sglist = sgtbl->sglist; 2789282bdeeSNagadheeraj Rottela uint8_t cnt = sgtbl->map_bufs_cnt; 2799282bdeeSNagadheeraj Rottela struct rte_mbuf *m; 2809282bdeeSNagadheeraj Rottela int mlen; 2819282bdeeSNagadheeraj Rottela 2829282bdeeSNagadheeraj Rottela if (unlikely(datalen <= 0)) 2839282bdeeSNagadheeraj Rottela return 0; 2849282bdeeSNagadheeraj Rottela 2859282bdeeSNagadheeraj Rottela for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next) 2869282bdeeSNagadheeraj Rottela off -= rte_pktmbuf_data_len(m); 2879282bdeeSNagadheeraj Rottela 2889282bdeeSNagadheeraj Rottela if (unlikely(!m)) 2899282bdeeSNagadheeraj Rottela return -EIO; 2909282bdeeSNagadheeraj Rottela 2919282bdeeSNagadheeraj Rottela mlen = rte_pktmbuf_data_len(m) - off; 2929282bdeeSNagadheeraj Rottela if (datalen <= mlen) 2939282bdeeSNagadheeraj Rottela mlen = datalen; 2949282bdeeSNagadheeraj Rottela sglist[cnt].len = mlen; 295ce627d63SThomas Monjalon sglist[cnt].iova = rte_pktmbuf_iova_offset(m, off); 2969282bdeeSNagadheeraj Rottela sglist[cnt].virt = rte_pktmbuf_mtod_offset(m, uint8_t *, off); 2979282bdeeSNagadheeraj Rottela sgtbl->total_bytes += mlen; 2989282bdeeSNagadheeraj Rottela cnt++; 2999282bdeeSNagadheeraj Rottela datalen -= mlen; 3009282bdeeSNagadheeraj Rottela for (m = m->next; m && datalen; m = m->next) { 3019282bdeeSNagadheeraj Rottela mlen = rte_pktmbuf_data_len(m) < datalen ? 3029282bdeeSNagadheeraj Rottela rte_pktmbuf_data_len(m) : datalen; 3039282bdeeSNagadheeraj Rottela sglist[cnt].len = mlen; 304ce627d63SThomas Monjalon sglist[cnt].iova = rte_pktmbuf_iova(m); 3059282bdeeSNagadheeraj Rottela sglist[cnt].virt = rte_pktmbuf_mtod(m, uint8_t *); 3069282bdeeSNagadheeraj Rottela sgtbl->total_bytes += mlen; 3079282bdeeSNagadheeraj Rottela cnt++; 3089282bdeeSNagadheeraj Rottela datalen -= mlen; 3099282bdeeSNagadheeraj Rottela } 3109282bdeeSNagadheeraj Rottela 3114a469e12SNagadheeraj Rottela RTE_ASSERT(cnt <= MAX_SGBUF_CNT); 3129282bdeeSNagadheeraj Rottela sgtbl->map_bufs_cnt = cnt; 3139282bdeeSNagadheeraj Rottela return 0; 3149282bdeeSNagadheeraj Rottela } 3159282bdeeSNagadheeraj Rottela 316678f3ecaSNagadheeraj Rottela static void 317678f3ecaSNagadheeraj Rottela create_sgcomp(struct nitrox_sgtable *sgtbl) 318678f3ecaSNagadheeraj Rottela { 319678f3ecaSNagadheeraj Rottela int i, j, nr_sgcomp; 320678f3ecaSNagadheeraj Rottela struct nitrox_sgcomp *sgcomp = sgtbl->sgcomp; 321678f3ecaSNagadheeraj Rottela struct nitrox_sglist *sglist = sgtbl->sglist; 322678f3ecaSNagadheeraj Rottela 323678f3ecaSNagadheeraj Rottela nr_sgcomp = RTE_ALIGN_MUL_CEIL(sgtbl->map_bufs_cnt, 4) / 4; 324678f3ecaSNagadheeraj Rottela sgtbl->nr_sgcomp = nr_sgcomp; 325678f3ecaSNagadheeraj Rottela for (i = 0; i < nr_sgcomp; i++, sgcomp++) { 326678f3ecaSNagadheeraj Rottela for (j = 0; j < 4; j++, sglist++) { 327678f3ecaSNagadheeraj Rottela sgcomp->len[j] = rte_cpu_to_be_16(sglist->len); 328678f3ecaSNagadheeraj Rottela sgcomp->iova[j] = rte_cpu_to_be_64(sglist->iova); 329678f3ecaSNagadheeraj Rottela } 330678f3ecaSNagadheeraj Rottela } 331678f3ecaSNagadheeraj Rottela } 332678f3ecaSNagadheeraj Rottela 333678f3ecaSNagadheeraj Rottela static int 334678f3ecaSNagadheeraj Rottela create_cipher_inbuf(struct nitrox_softreq *sr) 335678f3ecaSNagadheeraj Rottela { 336678f3ecaSNagadheeraj Rottela int err; 337678f3ecaSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 338678f3ecaSNagadheeraj Rottela 339678f3ecaSNagadheeraj Rottela fill_sglist(&sr->in, sr->iv.len, sr->iv.iova, sr->iv.virt); 340678f3ecaSNagadheeraj Rottela err = create_sglist_from_mbuf(&sr->in, op->sym->m_src, 341678f3ecaSNagadheeraj Rottela op->sym->cipher.data.offset, 342678f3ecaSNagadheeraj Rottela op->sym->cipher.data.length); 343678f3ecaSNagadheeraj Rottela if (unlikely(err)) 344678f3ecaSNagadheeraj Rottela return err; 345678f3ecaSNagadheeraj Rottela 346678f3ecaSNagadheeraj Rottela create_sgcomp(&sr->in); 347678f3ecaSNagadheeraj Rottela sr->dptr = sr->iova + offsetof(struct nitrox_softreq, in.sgcomp); 348678f3ecaSNagadheeraj Rottela 349678f3ecaSNagadheeraj Rottela return 0; 350678f3ecaSNagadheeraj Rottela } 351678f3ecaSNagadheeraj Rottela 352678f3ecaSNagadheeraj Rottela static int 353678f3ecaSNagadheeraj Rottela create_cipher_outbuf(struct nitrox_softreq *sr) 354678f3ecaSNagadheeraj Rottela { 355678f3ecaSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 356678f3ecaSNagadheeraj Rottela int err, cnt = 0; 357678f3ecaSNagadheeraj Rottela struct rte_mbuf *m_dst = op->sym->m_dst ? op->sym->m_dst : 358678f3ecaSNagadheeraj Rottela op->sym->m_src; 359678f3ecaSNagadheeraj Rottela 360678f3ecaSNagadheeraj Rottela sr->resp.orh = PENDING_SIG; 361678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].len = sizeof(sr->resp.orh); 362678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq, 363678f3ecaSNagadheeraj Rottela resp.orh); 364678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].virt = &sr->resp.orh; 365678f3ecaSNagadheeraj Rottela cnt++; 366678f3ecaSNagadheeraj Rottela 367678f3ecaSNagadheeraj Rottela sr->out.map_bufs_cnt = cnt; 368678f3ecaSNagadheeraj Rottela fill_sglist(&sr->out, sr->iv.len, sr->iv.iova, sr->iv.virt); 369678f3ecaSNagadheeraj Rottela err = create_sglist_from_mbuf(&sr->out, m_dst, 370678f3ecaSNagadheeraj Rottela op->sym->cipher.data.offset, 371678f3ecaSNagadheeraj Rottela op->sym->cipher.data.length); 372678f3ecaSNagadheeraj Rottela if (unlikely(err)) 373678f3ecaSNagadheeraj Rottela return err; 374678f3ecaSNagadheeraj Rottela 375678f3ecaSNagadheeraj Rottela cnt = sr->out.map_bufs_cnt; 376678f3ecaSNagadheeraj Rottela sr->resp.completion = PENDING_SIG; 377678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].len = sizeof(sr->resp.completion); 378678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq, 379678f3ecaSNagadheeraj Rottela resp.completion); 380678f3ecaSNagadheeraj Rottela sr->out.sglist[cnt].virt = &sr->resp.completion; 381678f3ecaSNagadheeraj Rottela cnt++; 382678f3ecaSNagadheeraj Rottela 3834a469e12SNagadheeraj Rottela RTE_ASSERT(cnt <= MAX_SGBUF_CNT); 384678f3ecaSNagadheeraj Rottela sr->out.map_bufs_cnt = cnt; 385678f3ecaSNagadheeraj Rottela 386678f3ecaSNagadheeraj Rottela create_sgcomp(&sr->out); 387678f3ecaSNagadheeraj Rottela sr->rptr = sr->iova + offsetof(struct nitrox_softreq, out.sgcomp); 388678f3ecaSNagadheeraj Rottela 389678f3ecaSNagadheeraj Rottela return 0; 390678f3ecaSNagadheeraj Rottela } 391678f3ecaSNagadheeraj Rottela 392678f3ecaSNagadheeraj Rottela static void 393678f3ecaSNagadheeraj Rottela create_cipher_gph(uint32_t cryptlen, uint16_t ivlen, struct gphdr *gph) 394678f3ecaSNagadheeraj Rottela { 395678f3ecaSNagadheeraj Rottela gph->param0 = rte_cpu_to_be_16(cryptlen); 396678f3ecaSNagadheeraj Rottela gph->param1 = 0; 397678f3ecaSNagadheeraj Rottela gph->param2 = rte_cpu_to_be_16(ivlen); 398678f3ecaSNagadheeraj Rottela gph->param3 = 0; 399678f3ecaSNagadheeraj Rottela } 400678f3ecaSNagadheeraj Rottela 401678f3ecaSNagadheeraj Rottela static int 402678f3ecaSNagadheeraj Rottela process_cipher_data(struct nitrox_softreq *sr) 403678f3ecaSNagadheeraj Rottela { 404678f3ecaSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 405678f3ecaSNagadheeraj Rottela int err; 406678f3ecaSNagadheeraj Rottela 407678f3ecaSNagadheeraj Rottela softreq_copy_iv(sr, 0); 408678f3ecaSNagadheeraj Rottela err = create_cipher_inbuf(sr); 409678f3ecaSNagadheeraj Rottela if (unlikely(err)) 410678f3ecaSNagadheeraj Rottela return err; 411678f3ecaSNagadheeraj Rottela 412678f3ecaSNagadheeraj Rottela err = create_cipher_outbuf(sr); 413678f3ecaSNagadheeraj Rottela if (unlikely(err)) 414678f3ecaSNagadheeraj Rottela return err; 415678f3ecaSNagadheeraj Rottela 416678f3ecaSNagadheeraj Rottela create_cipher_gph(op->sym->cipher.data.length, sr->iv.len, &sr->gph); 417678f3ecaSNagadheeraj Rottela 418678f3ecaSNagadheeraj Rottela return 0; 419678f3ecaSNagadheeraj Rottela } 420678f3ecaSNagadheeraj Rottela 421678f3ecaSNagadheeraj Rottela static int 422678f3ecaSNagadheeraj Rottela extract_cipher_auth_digest(struct nitrox_softreq *sr, 423678f3ecaSNagadheeraj Rottela struct nitrox_sglist *digest) 424678f3ecaSNagadheeraj Rottela { 425678f3ecaSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 426678f3ecaSNagadheeraj Rottela struct rte_mbuf *mdst = op->sym->m_dst ? op->sym->m_dst : 427678f3ecaSNagadheeraj Rottela op->sym->m_src; 428678f3ecaSNagadheeraj Rottela 429678f3ecaSNagadheeraj Rottela if (sr->ctx->req_op == NITROX_OP_DECRYPT && 430678f3ecaSNagadheeraj Rottela unlikely(!op->sym->auth.digest.data)) 431678f3ecaSNagadheeraj Rottela return -EINVAL; 432678f3ecaSNagadheeraj Rottela 433678f3ecaSNagadheeraj Rottela digest->len = sr->ctx->digest_length; 434678f3ecaSNagadheeraj Rottela if (op->sym->auth.digest.data) { 435678f3ecaSNagadheeraj Rottela digest->iova = op->sym->auth.digest.phys_addr; 436678f3ecaSNagadheeraj Rottela digest->virt = op->sym->auth.digest.data; 437678f3ecaSNagadheeraj Rottela return 0; 438678f3ecaSNagadheeraj Rottela } 439678f3ecaSNagadheeraj Rottela 440678f3ecaSNagadheeraj Rottela if (unlikely(rte_pktmbuf_data_len(mdst) < op->sym->auth.data.offset + 441678f3ecaSNagadheeraj Rottela op->sym->auth.data.length + digest->len)) 442678f3ecaSNagadheeraj Rottela return -EINVAL; 443678f3ecaSNagadheeraj Rottela 444678f3ecaSNagadheeraj Rottela digest->iova = rte_pktmbuf_iova_offset(mdst, 445678f3ecaSNagadheeraj Rottela op->sym->auth.data.offset + 446678f3ecaSNagadheeraj Rottela op->sym->auth.data.length); 447678f3ecaSNagadheeraj Rottela digest->virt = rte_pktmbuf_mtod_offset(mdst, uint8_t *, 448678f3ecaSNagadheeraj Rottela op->sym->auth.data.offset + 449678f3ecaSNagadheeraj Rottela op->sym->auth.data.length); 450678f3ecaSNagadheeraj Rottela return 0; 451678f3ecaSNagadheeraj Rottela } 452678f3ecaSNagadheeraj Rottela 4539282bdeeSNagadheeraj Rottela static int 4549282bdeeSNagadheeraj Rottela create_cipher_auth_sglist(struct nitrox_softreq *sr, 4559282bdeeSNagadheeraj Rottela struct nitrox_sgtable *sgtbl, struct rte_mbuf *mbuf) 4569282bdeeSNagadheeraj Rottela { 4579282bdeeSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 4589282bdeeSNagadheeraj Rottela int auth_only_len; 4599282bdeeSNagadheeraj Rottela int err; 4609282bdeeSNagadheeraj Rottela 4619282bdeeSNagadheeraj Rottela fill_sglist(sgtbl, sr->iv.len, sr->iv.iova, sr->iv.virt); 4629282bdeeSNagadheeraj Rottela auth_only_len = op->sym->auth.data.length - op->sym->cipher.data.length; 4639282bdeeSNagadheeraj Rottela if (unlikely(auth_only_len < 0)) 4649282bdeeSNagadheeraj Rottela return -EINVAL; 4659282bdeeSNagadheeraj Rottela 46693ba4a6eSNagadheeraj Rottela if (unlikely( 46793ba4a6eSNagadheeraj Rottela op->sym->cipher.data.offset + op->sym->cipher.data.length != 46893ba4a6eSNagadheeraj Rottela op->sym->auth.data.offset + op->sym->auth.data.length)) { 469*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Auth only data after cipher data not supported"); 47093ba4a6eSNagadheeraj Rottela return -ENOTSUP; 47193ba4a6eSNagadheeraj Rottela } 47293ba4a6eSNagadheeraj Rottela 4739282bdeeSNagadheeraj Rottela err = create_sglist_from_mbuf(sgtbl, mbuf, op->sym->auth.data.offset, 4749282bdeeSNagadheeraj Rottela auth_only_len); 4759282bdeeSNagadheeraj Rottela if (unlikely(err)) 4769282bdeeSNagadheeraj Rottela return err; 4779282bdeeSNagadheeraj Rottela 4789282bdeeSNagadheeraj Rottela err = create_sglist_from_mbuf(sgtbl, mbuf, op->sym->cipher.data.offset, 4799282bdeeSNagadheeraj Rottela op->sym->cipher.data.length); 4809282bdeeSNagadheeraj Rottela if (unlikely(err)) 4819282bdeeSNagadheeraj Rottela return err; 4829282bdeeSNagadheeraj Rottela 4839282bdeeSNagadheeraj Rottela return 0; 4849282bdeeSNagadheeraj Rottela } 4859282bdeeSNagadheeraj Rottela 48693ba4a6eSNagadheeraj Rottela static int 48793ba4a6eSNagadheeraj Rottela create_combined_sglist(struct nitrox_softreq *sr, struct nitrox_sgtable *sgtbl, 48893ba4a6eSNagadheeraj Rottela struct rte_mbuf *mbuf) 48993ba4a6eSNagadheeraj Rottela { 49093ba4a6eSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 49160531a2cSNagadheeraj Rottela uint32_t aad_offset = 0; 49260531a2cSNagadheeraj Rottela 49360531a2cSNagadheeraj Rottela if (sr->ctx->aead_algo == RTE_CRYPTO_AEAD_AES_CCM) 49460531a2cSNagadheeraj Rottela aad_offset = DPDK_AES_CCM_ADD_OFFSET; 49593ba4a6eSNagadheeraj Rottela 49693ba4a6eSNagadheeraj Rottela fill_sglist(sgtbl, sr->iv.len, sr->iv.iova, sr->iv.virt); 49760531a2cSNagadheeraj Rottela fill_sglist(sgtbl, sr->ctx->aad_length, 49860531a2cSNagadheeraj Rottela op->sym->aead.aad.phys_addr + aad_offset, 49960531a2cSNagadheeraj Rottela op->sym->aead.aad.data + aad_offset); 50093ba4a6eSNagadheeraj Rottela return create_sglist_from_mbuf(sgtbl, mbuf, op->sym->cipher.data.offset, 50193ba4a6eSNagadheeraj Rottela op->sym->cipher.data.length); 50293ba4a6eSNagadheeraj Rottela } 50393ba4a6eSNagadheeraj Rottela 50493ba4a6eSNagadheeraj Rottela static int 50593ba4a6eSNagadheeraj Rottela create_aead_sglist(struct nitrox_softreq *sr, struct nitrox_sgtable *sgtbl, 50693ba4a6eSNagadheeraj Rottela struct rte_mbuf *mbuf) 50793ba4a6eSNagadheeraj Rottela { 50893ba4a6eSNagadheeraj Rottela int err; 50993ba4a6eSNagadheeraj Rottela 51093ba4a6eSNagadheeraj Rottela switch (sr->ctx->nitrox_chain) { 51193ba4a6eSNagadheeraj Rottela case NITROX_CHAIN_CIPHER_AUTH: 51293ba4a6eSNagadheeraj Rottela case NITROX_CHAIN_AUTH_CIPHER: 51393ba4a6eSNagadheeraj Rottela err = create_cipher_auth_sglist(sr, sgtbl, mbuf); 51493ba4a6eSNagadheeraj Rottela break; 51593ba4a6eSNagadheeraj Rottela case NITROX_CHAIN_COMBINED: 51693ba4a6eSNagadheeraj Rottela err = create_combined_sglist(sr, sgtbl, mbuf); 51793ba4a6eSNagadheeraj Rottela break; 51893ba4a6eSNagadheeraj Rottela default: 51993ba4a6eSNagadheeraj Rottela err = -EINVAL; 52093ba4a6eSNagadheeraj Rottela break; 52193ba4a6eSNagadheeraj Rottela } 52293ba4a6eSNagadheeraj Rottela 52393ba4a6eSNagadheeraj Rottela return err; 52493ba4a6eSNagadheeraj Rottela } 52593ba4a6eSNagadheeraj Rottela 5269282bdeeSNagadheeraj Rottela static int 52793ba4a6eSNagadheeraj Rottela create_aead_inbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest) 5289282bdeeSNagadheeraj Rottela { 5299282bdeeSNagadheeraj Rottela int err; 5309282bdeeSNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 5319282bdeeSNagadheeraj Rottela 53293ba4a6eSNagadheeraj Rottela err = create_aead_sglist(sr, &sr->in, sr->op->sym->m_src); 5339282bdeeSNagadheeraj Rottela if (unlikely(err)) 5349282bdeeSNagadheeraj Rottela return err; 5359282bdeeSNagadheeraj Rottela 53693ba4a6eSNagadheeraj Rottela if (ctx->req_op == NITROX_OP_DECRYPT) 5379282bdeeSNagadheeraj Rottela fill_sglist(&sr->in, digest->len, digest->iova, digest->virt); 5389282bdeeSNagadheeraj Rottela 5399282bdeeSNagadheeraj Rottela create_sgcomp(&sr->in); 5409282bdeeSNagadheeraj Rottela sr->dptr = sr->iova + offsetof(struct nitrox_softreq, in.sgcomp); 5419282bdeeSNagadheeraj Rottela return 0; 5429282bdeeSNagadheeraj Rottela } 5439282bdeeSNagadheeraj Rottela 5449282bdeeSNagadheeraj Rottela static int 54593ba4a6eSNagadheeraj Rottela create_aead_oop_outbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest) 5469282bdeeSNagadheeraj Rottela { 5479282bdeeSNagadheeraj Rottela int err; 5489282bdeeSNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 5499282bdeeSNagadheeraj Rottela 55093ba4a6eSNagadheeraj Rottela err = create_aead_sglist(sr, &sr->out, sr->op->sym->m_dst); 5519282bdeeSNagadheeraj Rottela if (unlikely(err)) 5529282bdeeSNagadheeraj Rottela return err; 5539282bdeeSNagadheeraj Rottela 55493ba4a6eSNagadheeraj Rottela if (ctx->req_op == NITROX_OP_ENCRYPT) 5559282bdeeSNagadheeraj Rottela fill_sglist(&sr->out, digest->len, digest->iova, digest->virt); 5569282bdeeSNagadheeraj Rottela 5579282bdeeSNagadheeraj Rottela return 0; 5589282bdeeSNagadheeraj Rottela } 5599282bdeeSNagadheeraj Rottela 5609282bdeeSNagadheeraj Rottela static void 56193ba4a6eSNagadheeraj Rottela create_aead_inplace_outbuf(struct nitrox_softreq *sr, 5629282bdeeSNagadheeraj Rottela struct nitrox_sglist *digest) 5639282bdeeSNagadheeraj Rottela { 5649282bdeeSNagadheeraj Rottela int i, cnt; 5659282bdeeSNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 5669282bdeeSNagadheeraj Rottela 5679282bdeeSNagadheeraj Rottela cnt = sr->out.map_bufs_cnt; 5689282bdeeSNagadheeraj Rottela for (i = 0; i < sr->in.map_bufs_cnt; i++, cnt++) { 5699282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].len = sr->in.sglist[i].len; 5709282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].iova = sr->in.sglist[i].iova; 5719282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].virt = sr->in.sglist[i].virt; 5729282bdeeSNagadheeraj Rottela } 5739282bdeeSNagadheeraj Rottela 5749282bdeeSNagadheeraj Rottela sr->out.map_bufs_cnt = cnt; 57593ba4a6eSNagadheeraj Rottela if (ctx->req_op == NITROX_OP_ENCRYPT) { 5769282bdeeSNagadheeraj Rottela fill_sglist(&sr->out, digest->len, digest->iova, 5779282bdeeSNagadheeraj Rottela digest->virt); 57893ba4a6eSNagadheeraj Rottela } else if (ctx->req_op == NITROX_OP_DECRYPT) { 5799282bdeeSNagadheeraj Rottela sr->out.map_bufs_cnt--; 5809282bdeeSNagadheeraj Rottela } 5819282bdeeSNagadheeraj Rottela } 5829282bdeeSNagadheeraj Rottela 5839282bdeeSNagadheeraj Rottela static int 58493ba4a6eSNagadheeraj Rottela create_aead_outbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest) 5859282bdeeSNagadheeraj Rottela { 5869282bdeeSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 5879282bdeeSNagadheeraj Rottela int cnt = 0; 5889282bdeeSNagadheeraj Rottela 5899282bdeeSNagadheeraj Rottela sr->resp.orh = PENDING_SIG; 5909282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].len = sizeof(sr->resp.orh); 5919282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq, 5929282bdeeSNagadheeraj Rottela resp.orh); 5939282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].virt = &sr->resp.orh; 5949282bdeeSNagadheeraj Rottela cnt++; 5959282bdeeSNagadheeraj Rottela sr->out.map_bufs_cnt = cnt; 5969282bdeeSNagadheeraj Rottela if (op->sym->m_dst) { 5979282bdeeSNagadheeraj Rottela int err; 5989282bdeeSNagadheeraj Rottela 59993ba4a6eSNagadheeraj Rottela err = create_aead_oop_outbuf(sr, digest); 6009282bdeeSNagadheeraj Rottela if (unlikely(err)) 6019282bdeeSNagadheeraj Rottela return err; 6029282bdeeSNagadheeraj Rottela } else { 60393ba4a6eSNagadheeraj Rottela create_aead_inplace_outbuf(sr, digest); 6049282bdeeSNagadheeraj Rottela } 6059282bdeeSNagadheeraj Rottela 6069282bdeeSNagadheeraj Rottela cnt = sr->out.map_bufs_cnt; 6079282bdeeSNagadheeraj Rottela sr->resp.completion = PENDING_SIG; 6089282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].len = sizeof(sr->resp.completion); 6099282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq, 6109282bdeeSNagadheeraj Rottela resp.completion); 6119282bdeeSNagadheeraj Rottela sr->out.sglist[cnt].virt = &sr->resp.completion; 6129282bdeeSNagadheeraj Rottela cnt++; 6134a469e12SNagadheeraj Rottela RTE_ASSERT(cnt <= MAX_SGBUF_CNT); 6149282bdeeSNagadheeraj Rottela sr->out.map_bufs_cnt = cnt; 6159282bdeeSNagadheeraj Rottela 6169282bdeeSNagadheeraj Rottela create_sgcomp(&sr->out); 6179282bdeeSNagadheeraj Rottela sr->rptr = sr->iova + offsetof(struct nitrox_softreq, out.sgcomp); 6189282bdeeSNagadheeraj Rottela return 0; 6199282bdeeSNagadheeraj Rottela } 6209282bdeeSNagadheeraj Rottela 6219282bdeeSNagadheeraj Rottela static void 6229282bdeeSNagadheeraj Rottela create_aead_gph(uint32_t cryptlen, uint16_t ivlen, uint32_t authlen, 6239282bdeeSNagadheeraj Rottela struct gphdr *gph) 6249282bdeeSNagadheeraj Rottela { 6259282bdeeSNagadheeraj Rottela int auth_only_len; 6269282bdeeSNagadheeraj Rottela union { 6279282bdeeSNagadheeraj Rottela struct { 6289282bdeeSNagadheeraj Rottela #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 6299282bdeeSNagadheeraj Rottela uint16_t iv_offset : 8; 6309282bdeeSNagadheeraj Rottela uint16_t auth_offset : 8; 6319282bdeeSNagadheeraj Rottela #else 6329282bdeeSNagadheeraj Rottela uint16_t auth_offset : 8; 6339282bdeeSNagadheeraj Rottela uint16_t iv_offset : 8; 6349282bdeeSNagadheeraj Rottela #endif 6359282bdeeSNagadheeraj Rottela }; 6369282bdeeSNagadheeraj Rottela uint16_t value; 6379282bdeeSNagadheeraj Rottela } param3; 6389282bdeeSNagadheeraj Rottela 6399282bdeeSNagadheeraj Rottela gph->param0 = rte_cpu_to_be_16(cryptlen); 6409282bdeeSNagadheeraj Rottela gph->param1 = rte_cpu_to_be_16(authlen); 6419282bdeeSNagadheeraj Rottela 6429282bdeeSNagadheeraj Rottela auth_only_len = authlen - cryptlen; 6439282bdeeSNagadheeraj Rottela gph->param2 = rte_cpu_to_be_16(ivlen + auth_only_len); 6449282bdeeSNagadheeraj Rottela 6459282bdeeSNagadheeraj Rottela param3.iv_offset = 0; 6469282bdeeSNagadheeraj Rottela param3.auth_offset = ivlen; 6479282bdeeSNagadheeraj Rottela gph->param3 = rte_cpu_to_be_16(param3.value); 6489282bdeeSNagadheeraj Rottela } 6499282bdeeSNagadheeraj Rottela 6501acffa39SNagadheeraj Rottela static int 6511acffa39SNagadheeraj Rottela process_cipher_auth_data(struct nitrox_softreq *sr) 6521acffa39SNagadheeraj Rottela { 6539282bdeeSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 6549282bdeeSNagadheeraj Rottela int err; 6559282bdeeSNagadheeraj Rottela struct nitrox_sglist digest; 6569282bdeeSNagadheeraj Rottela 65793ba4a6eSNagadheeraj Rottela softreq_copy_iv(sr, 0); 6589282bdeeSNagadheeraj Rottela err = extract_cipher_auth_digest(sr, &digest); 6599282bdeeSNagadheeraj Rottela if (unlikely(err)) 6609282bdeeSNagadheeraj Rottela return err; 6619282bdeeSNagadheeraj Rottela 66293ba4a6eSNagadheeraj Rottela err = create_aead_inbuf(sr, &digest); 6639282bdeeSNagadheeraj Rottela if (unlikely(err)) 6649282bdeeSNagadheeraj Rottela return err; 6659282bdeeSNagadheeraj Rottela 66693ba4a6eSNagadheeraj Rottela err = create_aead_outbuf(sr, &digest); 6679282bdeeSNagadheeraj Rottela if (unlikely(err)) 6689282bdeeSNagadheeraj Rottela return err; 6699282bdeeSNagadheeraj Rottela 6709282bdeeSNagadheeraj Rottela create_aead_gph(op->sym->cipher.data.length, sr->iv.len, 6719282bdeeSNagadheeraj Rottela op->sym->auth.data.length, &sr->gph); 6721acffa39SNagadheeraj Rottela return 0; 6731acffa39SNagadheeraj Rottela } 6741acffa39SNagadheeraj Rottela 6751acffa39SNagadheeraj Rottela static int 67693ba4a6eSNagadheeraj Rottela softreq_copy_salt(struct nitrox_softreq *sr) 67793ba4a6eSNagadheeraj Rottela { 67893ba4a6eSNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 67993ba4a6eSNagadheeraj Rottela uint8_t *addr; 68093ba4a6eSNagadheeraj Rottela 68193ba4a6eSNagadheeraj Rottela if (unlikely(ctx->iv.length < AES_GCM_SALT_SIZE)) { 682*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid IV length %d", ctx->iv.length); 68393ba4a6eSNagadheeraj Rottela return -EINVAL; 68493ba4a6eSNagadheeraj Rottela } 68593ba4a6eSNagadheeraj Rottela 68693ba4a6eSNagadheeraj Rottela addr = rte_crypto_op_ctod_offset(sr->op, uint8_t *, ctx->iv.offset); 68793ba4a6eSNagadheeraj Rottela if (!memcmp(ctx->salt, addr, AES_GCM_SALT_SIZE)) 68893ba4a6eSNagadheeraj Rottela return 0; 68993ba4a6eSNagadheeraj Rottela 69093ba4a6eSNagadheeraj Rottela memcpy(ctx->salt, addr, AES_GCM_SALT_SIZE); 69193ba4a6eSNagadheeraj Rottela memcpy(ctx->fctx.crypto.iv, addr, AES_GCM_SALT_SIZE); 69293ba4a6eSNagadheeraj Rottela return 0; 69393ba4a6eSNagadheeraj Rottela } 69493ba4a6eSNagadheeraj Rottela 69593ba4a6eSNagadheeraj Rottela static int 69693ba4a6eSNagadheeraj Rottela extract_combined_digest(struct nitrox_softreq *sr, struct nitrox_sglist *digest) 69793ba4a6eSNagadheeraj Rottela { 69893ba4a6eSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 69993ba4a6eSNagadheeraj Rottela struct rte_mbuf *mdst = op->sym->m_dst ? op->sym->m_dst : 70093ba4a6eSNagadheeraj Rottela op->sym->m_src; 70193ba4a6eSNagadheeraj Rottela 70293ba4a6eSNagadheeraj Rottela digest->len = sr->ctx->digest_length; 70393ba4a6eSNagadheeraj Rottela if (op->sym->aead.digest.data) { 70493ba4a6eSNagadheeraj Rottela digest->iova = op->sym->aead.digest.phys_addr; 70593ba4a6eSNagadheeraj Rottela digest->virt = op->sym->aead.digest.data; 70693ba4a6eSNagadheeraj Rottela 70793ba4a6eSNagadheeraj Rottela return 0; 70893ba4a6eSNagadheeraj Rottela } 70993ba4a6eSNagadheeraj Rottela 71093ba4a6eSNagadheeraj Rottela if (unlikely(rte_pktmbuf_data_len(mdst) < op->sym->aead.data.offset + 71193ba4a6eSNagadheeraj Rottela op->sym->aead.data.length + digest->len)) 71293ba4a6eSNagadheeraj Rottela return -EINVAL; 71393ba4a6eSNagadheeraj Rottela 71493ba4a6eSNagadheeraj Rottela digest->iova = rte_pktmbuf_iova_offset(mdst, 71593ba4a6eSNagadheeraj Rottela op->sym->aead.data.offset + 71693ba4a6eSNagadheeraj Rottela op->sym->aead.data.length); 71793ba4a6eSNagadheeraj Rottela digest->virt = rte_pktmbuf_mtod_offset(mdst, uint8_t *, 71893ba4a6eSNagadheeraj Rottela op->sym->aead.data.offset + 71993ba4a6eSNagadheeraj Rottela op->sym->aead.data.length); 72093ba4a6eSNagadheeraj Rottela 72193ba4a6eSNagadheeraj Rottela return 0; 72293ba4a6eSNagadheeraj Rottela } 72393ba4a6eSNagadheeraj Rottela 72493ba4a6eSNagadheeraj Rottela static int 72593ba4a6eSNagadheeraj Rottela process_combined_data(struct nitrox_softreq *sr) 72693ba4a6eSNagadheeraj Rottela { 72793ba4a6eSNagadheeraj Rottela int err; 72893ba4a6eSNagadheeraj Rottela struct nitrox_sglist digest; 72993ba4a6eSNagadheeraj Rottela struct rte_crypto_op *op = sr->op; 73093ba4a6eSNagadheeraj Rottela 73160531a2cSNagadheeraj Rottela if (sr->ctx->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) { 73293ba4a6eSNagadheeraj Rottela err = softreq_copy_salt(sr); 73393ba4a6eSNagadheeraj Rottela if (unlikely(err)) 73493ba4a6eSNagadheeraj Rottela return err; 73593ba4a6eSNagadheeraj Rottela 73693ba4a6eSNagadheeraj Rottela softreq_copy_iv(sr, AES_GCM_SALT_SIZE); 73760531a2cSNagadheeraj Rottela } else if (sr->ctx->aead_algo == RTE_CRYPTO_AEAD_AES_CCM) { 73860531a2cSNagadheeraj Rottela union { 73960531a2cSNagadheeraj Rottela uint8_t value; 74060531a2cSNagadheeraj Rottela struct { 74160531a2cSNagadheeraj Rottela #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 74260531a2cSNagadheeraj Rottela uint8_t rsvd: 1; 74360531a2cSNagadheeraj Rottela uint8_t adata: 1; 74460531a2cSNagadheeraj Rottela uint8_t mstar: 3; 74560531a2cSNagadheeraj Rottela uint8_t lstar: 3; 74660531a2cSNagadheeraj Rottela #else 74760531a2cSNagadheeraj Rottela uint8_t lstar: 3; 74860531a2cSNagadheeraj Rottela uint8_t mstar: 3; 74960531a2cSNagadheeraj Rottela uint8_t adata: 1; 75060531a2cSNagadheeraj Rottela uint8_t rsvd: 1; 75160531a2cSNagadheeraj Rottela #endif 75260531a2cSNagadheeraj Rottela }; 75360531a2cSNagadheeraj Rottela } flags; 75460531a2cSNagadheeraj Rottela uint8_t L; 75560531a2cSNagadheeraj Rottela uint8_t *iv_addr; 75660531a2cSNagadheeraj Rottela 75760531a2cSNagadheeraj Rottela flags.value = 0; 75860531a2cSNagadheeraj Rottela flags.rsvd = 0; 75960531a2cSNagadheeraj Rottela flags.adata = (sr->ctx->aad_length > 0) ? 1 : 0; 76060531a2cSNagadheeraj Rottela flags.mstar = (sr->ctx->digest_length - 2) / 2; 76160531a2cSNagadheeraj Rottela L = 15 - sr->ctx->iv.length; 76260531a2cSNagadheeraj Rottela flags.lstar = L - 1; 76360531a2cSNagadheeraj Rottela iv_addr = rte_crypto_op_ctod_offset(sr->op, uint8_t *, 76460531a2cSNagadheeraj Rottela sr->ctx->iv.offset); 76560531a2cSNagadheeraj Rottela /* initialize IV flags */ 76660531a2cSNagadheeraj Rottela iv_addr[0] = flags.value; 76760531a2cSNagadheeraj Rottela /* initialize IV counter to 0 */ 76860531a2cSNagadheeraj Rottela memset(&iv_addr[1] + sr->ctx->iv.length, 0, L); 76960531a2cSNagadheeraj Rottela sr->iv.virt = rte_crypto_op_ctod_offset(sr->op, uint8_t *, 77060531a2cSNagadheeraj Rottela sr->ctx->iv.offset); 77160531a2cSNagadheeraj Rottela sr->iv.iova = rte_crypto_op_ctophys_offset(sr->op, 77260531a2cSNagadheeraj Rottela sr->ctx->iv.offset); 77360531a2cSNagadheeraj Rottela sr->iv.len = 16; 77460531a2cSNagadheeraj Rottela } else { 77560531a2cSNagadheeraj Rottela return -EINVAL; 77660531a2cSNagadheeraj Rottela } 77760531a2cSNagadheeraj Rottela 77893ba4a6eSNagadheeraj Rottela err = extract_combined_digest(sr, &digest); 77993ba4a6eSNagadheeraj Rottela if (unlikely(err)) 78093ba4a6eSNagadheeraj Rottela return err; 78193ba4a6eSNagadheeraj Rottela 78293ba4a6eSNagadheeraj Rottela err = create_aead_inbuf(sr, &digest); 78393ba4a6eSNagadheeraj Rottela if (unlikely(err)) 78493ba4a6eSNagadheeraj Rottela return err; 78593ba4a6eSNagadheeraj Rottela 78693ba4a6eSNagadheeraj Rottela err = create_aead_outbuf(sr, &digest); 78793ba4a6eSNagadheeraj Rottela if (unlikely(err)) 78893ba4a6eSNagadheeraj Rottela return err; 78993ba4a6eSNagadheeraj Rottela 79093ba4a6eSNagadheeraj Rottela create_aead_gph(op->sym->aead.data.length, sr->iv.len, 79193ba4a6eSNagadheeraj Rottela op->sym->aead.data.length + sr->ctx->aad_length, 79293ba4a6eSNagadheeraj Rottela &sr->gph); 79393ba4a6eSNagadheeraj Rottela 79493ba4a6eSNagadheeraj Rottela return 0; 79593ba4a6eSNagadheeraj Rottela } 79693ba4a6eSNagadheeraj Rottela 79793ba4a6eSNagadheeraj Rottela static int 7981acffa39SNagadheeraj Rottela process_softreq(struct nitrox_softreq *sr) 7991acffa39SNagadheeraj Rottela { 8001acffa39SNagadheeraj Rottela struct nitrox_crypto_ctx *ctx = sr->ctx; 8011acffa39SNagadheeraj Rottela int err = 0; 8021acffa39SNagadheeraj Rottela 8031acffa39SNagadheeraj Rottela switch (ctx->nitrox_chain) { 804678f3ecaSNagadheeraj Rottela case NITROX_CHAIN_CIPHER_ONLY: 805678f3ecaSNagadheeraj Rottela err = process_cipher_data(sr); 806678f3ecaSNagadheeraj Rottela break; 8071acffa39SNagadheeraj Rottela case NITROX_CHAIN_CIPHER_AUTH: 8081acffa39SNagadheeraj Rottela case NITROX_CHAIN_AUTH_CIPHER: 8091acffa39SNagadheeraj Rottela err = process_cipher_auth_data(sr); 8101acffa39SNagadheeraj Rottela break; 81193ba4a6eSNagadheeraj Rottela case NITROX_CHAIN_COMBINED: 81293ba4a6eSNagadheeraj Rottela err = process_combined_data(sr); 81393ba4a6eSNagadheeraj Rottela break; 8141acffa39SNagadheeraj Rottela default: 8151acffa39SNagadheeraj Rottela err = -EINVAL; 8161acffa39SNagadheeraj Rottela break; 8171acffa39SNagadheeraj Rottela } 8181acffa39SNagadheeraj Rottela 8191acffa39SNagadheeraj Rottela return err; 8201acffa39SNagadheeraj Rottela } 8211acffa39SNagadheeraj Rottela 8221acffa39SNagadheeraj Rottela int 8231acffa39SNagadheeraj Rottela nitrox_process_se_req(uint16_t qno, struct rte_crypto_op *op, 8241acffa39SNagadheeraj Rottela struct nitrox_crypto_ctx *ctx, 8251acffa39SNagadheeraj Rottela struct nitrox_softreq *sr) 8261acffa39SNagadheeraj Rottela { 82793ba4a6eSNagadheeraj Rottela int err; 82893ba4a6eSNagadheeraj Rottela 8294a469e12SNagadheeraj Rottela if (unlikely(op->sym->m_src->nb_segs > MAX_SUPPORTED_MBUF_SEGS || 8304a469e12SNagadheeraj Rottela (op->sym->m_dst && 8314a469e12SNagadheeraj Rottela op->sym->m_dst->nb_segs > MAX_SUPPORTED_MBUF_SEGS))) { 832*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Mbuf segments not supported. " 833*e99981afSDavid Marchand "Max supported %d", MAX_SUPPORTED_MBUF_SEGS); 8344a469e12SNagadheeraj Rottela return -ENOTSUP; 8354a469e12SNagadheeraj Rottela } 8364a469e12SNagadheeraj Rottela 8371acffa39SNagadheeraj Rottela softreq_init(sr, sr->iova); 8381acffa39SNagadheeraj Rottela sr->ctx = ctx; 8391acffa39SNagadheeraj Rottela sr->op = op; 84093ba4a6eSNagadheeraj Rottela err = process_softreq(sr); 84193ba4a6eSNagadheeraj Rottela if (unlikely(err)) 84293ba4a6eSNagadheeraj Rottela return err; 84393ba4a6eSNagadheeraj Rottela 8449282bdeeSNagadheeraj Rottela create_se_instr(sr, qno); 8451acffa39SNagadheeraj Rottela sr->timeout = rte_get_timer_cycles() + CMD_TIMEOUT * rte_get_timer_hz(); 8461acffa39SNagadheeraj Rottela return 0; 8471acffa39SNagadheeraj Rottela } 8481acffa39SNagadheeraj Rottela 8491acffa39SNagadheeraj Rottela int 8501acffa39SNagadheeraj Rottela nitrox_check_se_req(struct nitrox_softreq *sr, struct rte_crypto_op **op) 8511acffa39SNagadheeraj Rottela { 8521acffa39SNagadheeraj Rottela uint64_t cc; 8531acffa39SNagadheeraj Rottela uint64_t orh; 8541acffa39SNagadheeraj Rottela int err; 8551acffa39SNagadheeraj Rottela 8561acffa39SNagadheeraj Rottela cc = *(volatile uint64_t *)(&sr->resp.completion); 8571acffa39SNagadheeraj Rottela orh = *(volatile uint64_t *)(&sr->resp.orh); 8581acffa39SNagadheeraj Rottela if (cc != PENDING_SIG) 85993ba4a6eSNagadheeraj Rottela err = orh & 0xff; 8601acffa39SNagadheeraj Rottela else if ((orh != PENDING_SIG) && (orh & 0xff)) 8611acffa39SNagadheeraj Rottela err = orh & 0xff; 8621acffa39SNagadheeraj Rottela else if (rte_get_timer_cycles() >= sr->timeout) 8631acffa39SNagadheeraj Rottela err = 0xff; 8641acffa39SNagadheeraj Rottela else 8651acffa39SNagadheeraj Rottela return -EAGAIN; 8661acffa39SNagadheeraj Rottela 8671acffa39SNagadheeraj Rottela if (unlikely(err)) 868*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Request err 0x%x, orh 0x%"PRIx64, err, 8691acffa39SNagadheeraj Rottela sr->resp.orh); 8701acffa39SNagadheeraj Rottela 8711acffa39SNagadheeraj Rottela *op = sr->op; 8721acffa39SNagadheeraj Rottela return err; 8731acffa39SNagadheeraj Rottela } 8741acffa39SNagadheeraj Rottela 8751acffa39SNagadheeraj Rottela void * 8761acffa39SNagadheeraj Rottela nitrox_sym_instr_addr(struct nitrox_softreq *sr) 8771acffa39SNagadheeraj Rottela { 8781acffa39SNagadheeraj Rottela return &sr->instr; 8791acffa39SNagadheeraj Rottela } 8801acffa39SNagadheeraj Rottela 8813b1fa94aSNagadheeraj Rottela static void 8823b1fa94aSNagadheeraj Rottela req_pool_obj_init(__rte_unused struct rte_mempool *mp, 8833b1fa94aSNagadheeraj Rottela __rte_unused void *opaque, void *obj, 8843b1fa94aSNagadheeraj Rottela __rte_unused unsigned int obj_idx) 8853b1fa94aSNagadheeraj Rottela { 8863b1fa94aSNagadheeraj Rottela softreq_init(obj, rte_mempool_virt2iova(obj)); 8873b1fa94aSNagadheeraj Rottela } 8883b1fa94aSNagadheeraj Rottela 8893b1fa94aSNagadheeraj Rottela struct rte_mempool * 8903b1fa94aSNagadheeraj Rottela nitrox_sym_req_pool_create(struct rte_cryptodev *cdev, uint32_t nobjs, 8913b1fa94aSNagadheeraj Rottela uint16_t qp_id, int socket_id) 8923b1fa94aSNagadheeraj Rottela { 8933b1fa94aSNagadheeraj Rottela char softreq_pool_name[RTE_RING_NAMESIZE]; 8943b1fa94aSNagadheeraj Rottela struct rte_mempool *mp; 8953b1fa94aSNagadheeraj Rottela 8963b1fa94aSNagadheeraj Rottela snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_sr_%d", 8973b1fa94aSNagadheeraj Rottela cdev->data->name, qp_id); 8983b1fa94aSNagadheeraj Rottela mp = rte_mempool_create(softreq_pool_name, 8993b1fa94aSNagadheeraj Rottela RTE_ALIGN_MUL_CEIL(nobjs, 64), 9003b1fa94aSNagadheeraj Rottela sizeof(struct nitrox_softreq), 9013b1fa94aSNagadheeraj Rottela 64, 0, NULL, NULL, req_pool_obj_init, NULL, 9023b1fa94aSNagadheeraj Rottela socket_id, 0); 9033b1fa94aSNagadheeraj Rottela if (unlikely(!mp)) 904*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Failed to create req pool, qid %d, err %d", 9053b1fa94aSNagadheeraj Rottela qp_id, rte_errno); 9063b1fa94aSNagadheeraj Rottela 9073b1fa94aSNagadheeraj Rottela return mp; 9083b1fa94aSNagadheeraj Rottela } 9093b1fa94aSNagadheeraj Rottela 9103b1fa94aSNagadheeraj Rottela void 9113b1fa94aSNagadheeraj Rottela nitrox_sym_req_pool_free(struct rte_mempool *mp) 9123b1fa94aSNagadheeraj Rottela { 9133b1fa94aSNagadheeraj Rottela rte_mempool_free(mp); 9143b1fa94aSNagadheeraj Rottela } 915