143d01767SNithin Dabilpuram /* SPDX-License-Identifier: BSD-3-Clause 243d01767SNithin Dabilpuram * Copyright(c) 2018 Cavium, Inc 343d01767SNithin Dabilpuram */ 443d01767SNithin Dabilpuram 543d01767SNithin Dabilpuram #ifndef _CPT_UCODE_H_ 643d01767SNithin Dabilpuram #define _CPT_UCODE_H_ 7b74652f3SRagothaman Jayaraman #include <stdbool.h> 8b74652f3SRagothaman Jayaraman 9b74652f3SRagothaman Jayaraman #include "cpt_common.h" 10b74652f3SRagothaman Jayaraman #include "cpt_hw_types.h" 1143d01767SNithin Dabilpuram #include "cpt_mcode_defines.h" 1243d01767SNithin Dabilpuram 1343d01767SNithin Dabilpuram /* 1443d01767SNithin Dabilpuram * This file defines functions that are interfaces to microcode spec. 1543d01767SNithin Dabilpuram * 1643d01767SNithin Dabilpuram */ 1743d01767SNithin Dabilpuram 186cc54096SNithin Dabilpuram static uint8_t zuc_d[32] = { 196cc54096SNithin Dabilpuram 0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E, 206cc54096SNithin Dabilpuram 0x57, 0x89, 0x35, 0xE2, 0x71, 0x35, 0x09, 0xAF, 216cc54096SNithin Dabilpuram 0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4, 0x1A, 0xF1, 226cc54096SNithin Dabilpuram 0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC 236cc54096SNithin Dabilpuram }; 246cc54096SNithin Dabilpuram 256cc54096SNithin Dabilpuram static __rte_always_inline void 26186b14d6SFan Zhang gen_key_snow3g(const uint8_t *ck, uint32_t *keyx) 276cc54096SNithin Dabilpuram { 286cc54096SNithin Dabilpuram int i, base; 296cc54096SNithin Dabilpuram 306cc54096SNithin Dabilpuram for (i = 0; i < 4; i++) { 316cc54096SNithin Dabilpuram base = 4 * i; 326cc54096SNithin Dabilpuram keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) | 336cc54096SNithin Dabilpuram (ck[base + 2] << 8) | (ck[base + 3]); 346cc54096SNithin Dabilpuram keyx[3 - i] = rte_cpu_to_be_32(keyx[3 - i]); 356cc54096SNithin Dabilpuram } 366cc54096SNithin Dabilpuram } 376cc54096SNithin Dabilpuram 38b74652f3SRagothaman Jayaraman static __rte_always_inline void 39b74652f3SRagothaman Jayaraman cpt_fc_salt_update(void *ctx, 40b74652f3SRagothaman Jayaraman uint8_t *salt) 41b74652f3SRagothaman Jayaraman { 42b74652f3SRagothaman Jayaraman struct cpt_ctx *cpt_ctx = ctx; 43b74652f3SRagothaman Jayaraman memcpy(&cpt_ctx->fctx.enc.encr_iv, salt, 4); 44b74652f3SRagothaman Jayaraman } 45b74652f3SRagothaman Jayaraman 466cc54096SNithin Dabilpuram static __rte_always_inline int 476cc54096SNithin Dabilpuram cpt_fc_ciph_validate_key_aes(uint16_t key_len) 486cc54096SNithin Dabilpuram { 496cc54096SNithin Dabilpuram switch (key_len) { 506cc54096SNithin Dabilpuram case CPT_BYTE_16: 516cc54096SNithin Dabilpuram case CPT_BYTE_24: 526cc54096SNithin Dabilpuram case CPT_BYTE_32: 536cc54096SNithin Dabilpuram return 0; 546cc54096SNithin Dabilpuram default: 556cc54096SNithin Dabilpuram return -1; 566cc54096SNithin Dabilpuram } 576cc54096SNithin Dabilpuram } 586cc54096SNithin Dabilpuram 596cc54096SNithin Dabilpuram static __rte_always_inline int 608de5ede7SAnoob Joseph cpt_fc_ciph_set_type(cipher_type_t type, struct cpt_ctx *ctx, uint16_t key_len) 616cc54096SNithin Dabilpuram { 626cc54096SNithin Dabilpuram int fc_type = 0; 636cc54096SNithin Dabilpuram switch (type) { 646cc54096SNithin Dabilpuram case PASSTHROUGH: 656cc54096SNithin Dabilpuram fc_type = FC_GEN; 666cc54096SNithin Dabilpuram break; 676cc54096SNithin Dabilpuram case DES3_CBC: 686cc54096SNithin Dabilpuram case DES3_ECB: 696cc54096SNithin Dabilpuram fc_type = FC_GEN; 706cc54096SNithin Dabilpuram break; 716cc54096SNithin Dabilpuram case AES_CBC: 726cc54096SNithin Dabilpuram case AES_ECB: 736cc54096SNithin Dabilpuram case AES_CFB: 746cc54096SNithin Dabilpuram case AES_CTR: 756cc54096SNithin Dabilpuram case AES_GCM: 766cc54096SNithin Dabilpuram if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 776cc54096SNithin Dabilpuram return -1; 786cc54096SNithin Dabilpuram fc_type = FC_GEN; 796cc54096SNithin Dabilpuram break; 80*cb7842f2STejasree Kondoj case CHACHA20: 81*cb7842f2STejasree Kondoj fc_type = FC_GEN; 82*cb7842f2STejasree Kondoj break; 836cc54096SNithin Dabilpuram case AES_XTS: 846cc54096SNithin Dabilpuram key_len = key_len / 2; 856cc54096SNithin Dabilpuram if (unlikely(key_len == CPT_BYTE_24)) { 866cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid AES key len for XTS"); 876cc54096SNithin Dabilpuram return -1; 886cc54096SNithin Dabilpuram } 896cc54096SNithin Dabilpuram if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 906cc54096SNithin Dabilpuram return -1; 916cc54096SNithin Dabilpuram fc_type = FC_GEN; 926cc54096SNithin Dabilpuram break; 936cc54096SNithin Dabilpuram case ZUC_EEA3: 946cc54096SNithin Dabilpuram case SNOW3G_UEA2: 956cc54096SNithin Dabilpuram if (unlikely(key_len != 16)) 966cc54096SNithin Dabilpuram return -1; 976cc54096SNithin Dabilpuram /* No support for AEAD yet */ 988de5ede7SAnoob Joseph if (unlikely(ctx->hash_type)) 996cc54096SNithin Dabilpuram return -1; 1006cc54096SNithin Dabilpuram fc_type = ZUC_SNOW3G; 1016cc54096SNithin Dabilpuram break; 1026cc54096SNithin Dabilpuram case KASUMI_F8_CBC: 1036cc54096SNithin Dabilpuram case KASUMI_F8_ECB: 1046cc54096SNithin Dabilpuram if (unlikely(key_len != 16)) 1056cc54096SNithin Dabilpuram return -1; 1066cc54096SNithin Dabilpuram /* No support for AEAD yet */ 1078de5ede7SAnoob Joseph if (unlikely(ctx->hash_type)) 1086cc54096SNithin Dabilpuram return -1; 1096cc54096SNithin Dabilpuram fc_type = KASUMI; 1106cc54096SNithin Dabilpuram break; 1116cc54096SNithin Dabilpuram default: 1126cc54096SNithin Dabilpuram return -1; 1136cc54096SNithin Dabilpuram } 1148de5ede7SAnoob Joseph 1158de5ede7SAnoob Joseph ctx->fc_type = fc_type; 1168de5ede7SAnoob Joseph return 0; 1176cc54096SNithin Dabilpuram } 1186cc54096SNithin Dabilpuram 1196cc54096SNithin Dabilpuram static __rte_always_inline void 1206cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx) 1216cc54096SNithin Dabilpuram { 1226cc54096SNithin Dabilpuram cpt_ctx->enc_cipher = 0; 123c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = 0; 1246cc54096SNithin Dabilpuram } 1256cc54096SNithin Dabilpuram 1266cc54096SNithin Dabilpuram static __rte_always_inline void 1276cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len) 1286cc54096SNithin Dabilpuram { 1296cc54096SNithin Dabilpuram mc_aes_type_t aes_key_type = 0; 1306cc54096SNithin Dabilpuram switch (key_len) { 1316cc54096SNithin Dabilpuram case CPT_BYTE_16: 1326cc54096SNithin Dabilpuram aes_key_type = AES_128_BIT; 1336cc54096SNithin Dabilpuram break; 1346cc54096SNithin Dabilpuram case CPT_BYTE_24: 1356cc54096SNithin Dabilpuram aes_key_type = AES_192_BIT; 1366cc54096SNithin Dabilpuram break; 1376cc54096SNithin Dabilpuram case CPT_BYTE_32: 1386cc54096SNithin Dabilpuram aes_key_type = AES_256_BIT; 1396cc54096SNithin Dabilpuram break; 1406cc54096SNithin Dabilpuram default: 1416cc54096SNithin Dabilpuram /* This should not happen */ 1426cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid AES key len"); 1436cc54096SNithin Dabilpuram return; 1446cc54096SNithin Dabilpuram } 145c3d0bc45SAnoob Joseph fctx->enc.aes_key = aes_key_type; 1466cc54096SNithin Dabilpuram } 1476cc54096SNithin Dabilpuram 1486cc54096SNithin Dabilpuram static __rte_always_inline void 149186b14d6SFan Zhang cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key, 1506cc54096SNithin Dabilpuram uint16_t key_len) 1516cc54096SNithin Dabilpuram { 1526cc54096SNithin Dabilpuram uint32_t keyx[4]; 1536cc54096SNithin Dabilpuram cpt_ctx->snow3g = 1; 1546cc54096SNithin Dabilpuram gen_key_snow3g(key, keyx); 1556cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); 1566cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 1576cc54096SNithin Dabilpuram } 1586cc54096SNithin Dabilpuram 1596cc54096SNithin Dabilpuram static __rte_always_inline void 160186b14d6SFan Zhang cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key, 1616cc54096SNithin Dabilpuram uint16_t key_len) 1626cc54096SNithin Dabilpuram { 1636cc54096SNithin Dabilpuram cpt_ctx->snow3g = 0; 1646cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); 1656cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); 1666cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 1676cc54096SNithin Dabilpuram } 1686cc54096SNithin Dabilpuram 1696cc54096SNithin Dabilpuram static __rte_always_inline void 170186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key, 1716cc54096SNithin Dabilpuram uint16_t key_len) 1726cc54096SNithin Dabilpuram { 1736cc54096SNithin Dabilpuram cpt_ctx->k_ecb = 1; 1746cc54096SNithin Dabilpuram memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 1756cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 1766cc54096SNithin Dabilpuram } 1776cc54096SNithin Dabilpuram 1786cc54096SNithin Dabilpuram static __rte_always_inline void 179186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key, 1806cc54096SNithin Dabilpuram uint16_t key_len) 1816cc54096SNithin Dabilpuram { 1826cc54096SNithin Dabilpuram memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 1836cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 1846cc54096SNithin Dabilpuram } 1856cc54096SNithin Dabilpuram 1866cc54096SNithin Dabilpuram static __rte_always_inline int 187186b14d6SFan Zhang cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, const uint8_t *key, 1886cc54096SNithin Dabilpuram uint16_t key_len, uint8_t *salt) 1896cc54096SNithin Dabilpuram { 1906cc54096SNithin Dabilpuram struct cpt_ctx *cpt_ctx = ctx; 1916cc54096SNithin Dabilpuram mc_fc_context_t *fctx = &cpt_ctx->fctx; 1928de5ede7SAnoob Joseph int ret; 1936cc54096SNithin Dabilpuram 1948de5ede7SAnoob Joseph ret = cpt_fc_ciph_set_type(type, cpt_ctx, key_len); 1958de5ede7SAnoob Joseph if (unlikely(ret)) 1966cc54096SNithin Dabilpuram return -1; 1976cc54096SNithin Dabilpuram 1988de5ede7SAnoob Joseph if (cpt_ctx->fc_type == FC_GEN) { 1996cc54096SNithin Dabilpuram /* 2006cc54096SNithin Dabilpuram * We need to always say IV is from DPTR as user can 2016cc54096SNithin Dabilpuram * sometimes iverride IV per operation. 2026cc54096SNithin Dabilpuram */ 203c3d0bc45SAnoob Joseph fctx->enc.iv_source = CPT_FROM_DPTR; 2042839a8abSSucharitha Sarananaga 2052839a8abSSucharitha Sarananaga if (cpt_ctx->auth_key_len > 64) 2062839a8abSSucharitha Sarananaga return -1; 2076cc54096SNithin Dabilpuram } 2086cc54096SNithin Dabilpuram 2096cc54096SNithin Dabilpuram switch (type) { 2106cc54096SNithin Dabilpuram case PASSTHROUGH: 2116cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx); 212c3d0bc45SAnoob Joseph goto success; 2136cc54096SNithin Dabilpuram case DES3_CBC: 2146cc54096SNithin Dabilpuram /* CPT performs DES using 3DES with the 8B DES-key 2156cc54096SNithin Dabilpuram * replicated 2 more times to match the 24B 3DES-key. 2166cc54096SNithin Dabilpuram * Eg. If org. key is "0x0a 0x0b", then new key is 2176cc54096SNithin Dabilpuram * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b" 2186cc54096SNithin Dabilpuram */ 2196cc54096SNithin Dabilpuram if (key_len == 8) { 2206cc54096SNithin Dabilpuram /* Skipping the first 8B as it will be copied 2216cc54096SNithin Dabilpuram * in the regular code flow 2226cc54096SNithin Dabilpuram */ 2236cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key+key_len, key, key_len); 2246cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key+2*key_len, key, key_len); 2256cc54096SNithin Dabilpuram } 2266cc54096SNithin Dabilpuram break; 2276cc54096SNithin Dabilpuram case DES3_ECB: 2286cc54096SNithin Dabilpuram /* For DES3_ECB IV need to be from CTX. */ 229c3d0bc45SAnoob Joseph fctx->enc.iv_source = CPT_FROM_CTX; 2306cc54096SNithin Dabilpuram break; 2316cc54096SNithin Dabilpuram case AES_CBC: 2326cc54096SNithin Dabilpuram case AES_ECB: 2336cc54096SNithin Dabilpuram case AES_CFB: 2346cc54096SNithin Dabilpuram case AES_CTR: 235*cb7842f2STejasree Kondoj case CHACHA20: 2366cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 2376cc54096SNithin Dabilpuram break; 2386cc54096SNithin Dabilpuram case AES_GCM: 2396cc54096SNithin Dabilpuram /* Even though iv source is from dptr, 2406cc54096SNithin Dabilpuram * aes_gcm salt is taken from ctx 2416cc54096SNithin Dabilpuram */ 2426cc54096SNithin Dabilpuram if (salt) { 2436cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_iv, salt, 4); 2446cc54096SNithin Dabilpuram /* Assuming it was just salt update 2456cc54096SNithin Dabilpuram * and nothing else 2466cc54096SNithin Dabilpuram */ 2476cc54096SNithin Dabilpuram if (!key) 248c3d0bc45SAnoob Joseph goto success; 2496cc54096SNithin Dabilpuram } 2506cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 2516cc54096SNithin Dabilpuram break; 2526cc54096SNithin Dabilpuram case AES_XTS: 2536cc54096SNithin Dabilpuram key_len = key_len / 2; 2546cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 2556cc54096SNithin Dabilpuram 2566cc54096SNithin Dabilpuram /* Copy key2 for XTS into ipad */ 2576cc54096SNithin Dabilpuram memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 2586cc54096SNithin Dabilpuram memcpy(fctx->hmac.ipad, &key[key_len], key_len); 2596cc54096SNithin Dabilpuram break; 2606cc54096SNithin Dabilpuram case SNOW3G_UEA2: 2616cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len); 2626cc54096SNithin Dabilpuram goto success; 2636cc54096SNithin Dabilpuram case ZUC_EEA3: 2646cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len); 2656cc54096SNithin Dabilpuram goto success; 2666cc54096SNithin Dabilpuram case KASUMI_F8_ECB: 2676cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len); 2686cc54096SNithin Dabilpuram goto success; 2696cc54096SNithin Dabilpuram case KASUMI_F8_CBC: 2706cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len); 2716cc54096SNithin Dabilpuram goto success; 2726cc54096SNithin Dabilpuram default: 273e40175c5SArchana Muniganti return -1; 2746cc54096SNithin Dabilpuram } 2756cc54096SNithin Dabilpuram 2766cc54096SNithin Dabilpuram /* Only for FC_GEN case */ 2776cc54096SNithin Dabilpuram 2786cc54096SNithin Dabilpuram /* For GMAC auth, cipher must be NULL */ 2796cc54096SNithin Dabilpuram if (cpt_ctx->hash_type != GMAC_TYPE) 280c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = type; 2816cc54096SNithin Dabilpuram 2826cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key, key, key_len); 2836cc54096SNithin Dabilpuram 2846cc54096SNithin Dabilpuram success: 2856cc54096SNithin Dabilpuram cpt_ctx->enc_cipher = type; 2866cc54096SNithin Dabilpuram 2876cc54096SNithin Dabilpuram return 0; 2886cc54096SNithin Dabilpuram } 2896cc54096SNithin Dabilpuram 290b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 291b74652f3SRagothaman Jayaraman fill_sg_comp(sg_comp_t *list, 292b74652f3SRagothaman Jayaraman uint32_t i, 293b74652f3SRagothaman Jayaraman phys_addr_t dma_addr, 294b74652f3SRagothaman Jayaraman uint32_t size) 295b74652f3SRagothaman Jayaraman { 296b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i>>2]; 297b74652f3SRagothaman Jayaraman 298b74652f3SRagothaman Jayaraman to->u.s.len[i%4] = rte_cpu_to_be_16(size); 299b74652f3SRagothaman Jayaraman to->ptr[i%4] = rte_cpu_to_be_64(dma_addr); 300b74652f3SRagothaman Jayaraman i++; 301b74652f3SRagothaman Jayaraman return i; 302b74652f3SRagothaman Jayaraman } 303b74652f3SRagothaman Jayaraman 304b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 305b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf(sg_comp_t *list, 306b74652f3SRagothaman Jayaraman uint32_t i, 307b74652f3SRagothaman Jayaraman buf_ptr_t *from) 308b74652f3SRagothaman Jayaraman { 309b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i>>2]; 310b74652f3SRagothaman Jayaraman 311b74652f3SRagothaman Jayaraman to->u.s.len[i%4] = rte_cpu_to_be_16(from->size); 312b74652f3SRagothaman Jayaraman to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr); 313b74652f3SRagothaman Jayaraman i++; 314b74652f3SRagothaman Jayaraman return i; 315b74652f3SRagothaman Jayaraman } 316b74652f3SRagothaman Jayaraman 317b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 318b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf_min(sg_comp_t *list, 319b74652f3SRagothaman Jayaraman uint32_t i, 320b74652f3SRagothaman Jayaraman buf_ptr_t *from, 321b74652f3SRagothaman Jayaraman uint32_t *psize) 322b74652f3SRagothaman Jayaraman { 323b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i >> 2]; 324b74652f3SRagothaman Jayaraman uint32_t size = *psize; 325b74652f3SRagothaman Jayaraman uint32_t e_len; 326b74652f3SRagothaman Jayaraman 327b74652f3SRagothaman Jayaraman e_len = (size > from->size) ? from->size : size; 328b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 329b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr); 330b74652f3SRagothaman Jayaraman *psize -= e_len; 331b74652f3SRagothaman Jayaraman i++; 332b74652f3SRagothaman Jayaraman return i; 333b74652f3SRagothaman Jayaraman } 334b74652f3SRagothaman Jayaraman 335b74652f3SRagothaman Jayaraman /* 336b74652f3SRagothaman Jayaraman * This fills the MC expected SGIO list 337b74652f3SRagothaman Jayaraman * from IOV given by user. 338b74652f3SRagothaman Jayaraman */ 339b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 340b74652f3SRagothaman Jayaraman fill_sg_comp_from_iov(sg_comp_t *list, 341b74652f3SRagothaman Jayaraman uint32_t i, 342b74652f3SRagothaman Jayaraman iov_ptr_t *from, uint32_t from_offset, 343b74652f3SRagothaman Jayaraman uint32_t *psize, buf_ptr_t *extra_buf, 344b74652f3SRagothaman Jayaraman uint32_t extra_offset) 345b74652f3SRagothaman Jayaraman { 346b74652f3SRagothaman Jayaraman int32_t j; 347b74652f3SRagothaman Jayaraman uint32_t extra_len = extra_buf ? extra_buf->size : 0; 3480022ae1eSArchana Muniganti uint32_t size = *psize; 349b74652f3SRagothaman Jayaraman buf_ptr_t *bufs; 350b74652f3SRagothaman Jayaraman 351b74652f3SRagothaman Jayaraman bufs = from->bufs; 352b74652f3SRagothaman Jayaraman for (j = 0; (j < from->buf_cnt) && size; j++) { 353b74652f3SRagothaman Jayaraman phys_addr_t e_dma_addr; 354b74652f3SRagothaman Jayaraman uint32_t e_len; 355b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i >> 2]; 356b74652f3SRagothaman Jayaraman 357b74652f3SRagothaman Jayaraman if (unlikely(from_offset)) { 358b74652f3SRagothaman Jayaraman if (from_offset >= bufs[j].size) { 359b74652f3SRagothaman Jayaraman from_offset -= bufs[j].size; 360b74652f3SRagothaman Jayaraman continue; 361b74652f3SRagothaman Jayaraman } 362b74652f3SRagothaman Jayaraman e_dma_addr = bufs[j].dma_addr + from_offset; 363b74652f3SRagothaman Jayaraman e_len = (size > (bufs[j].size - from_offset)) ? 364b74652f3SRagothaman Jayaraman (bufs[j].size - from_offset) : size; 365b74652f3SRagothaman Jayaraman from_offset = 0; 366b74652f3SRagothaman Jayaraman } else { 367b74652f3SRagothaman Jayaraman e_dma_addr = bufs[j].dma_addr; 368b74652f3SRagothaman Jayaraman e_len = (size > bufs[j].size) ? 369b74652f3SRagothaman Jayaraman bufs[j].size : size; 370b74652f3SRagothaman Jayaraman } 371b74652f3SRagothaman Jayaraman 372b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 373b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr); 374b74652f3SRagothaman Jayaraman 375b74652f3SRagothaman Jayaraman if (extra_len && (e_len >= extra_offset)) { 376b74652f3SRagothaman Jayaraman /* Break the data at given offset */ 377b74652f3SRagothaman Jayaraman uint32_t next_len = e_len - extra_offset; 378b74652f3SRagothaman Jayaraman phys_addr_t next_dma = e_dma_addr + extra_offset; 379b74652f3SRagothaman Jayaraman 380b74652f3SRagothaman Jayaraman if (!extra_offset) { 381b74652f3SRagothaman Jayaraman i--; 382b74652f3SRagothaman Jayaraman } else { 383b74652f3SRagothaman Jayaraman e_len = extra_offset; 384b74652f3SRagothaman Jayaraman size -= e_len; 385b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 386b74652f3SRagothaman Jayaraman } 387b74652f3SRagothaman Jayaraman 3880022ae1eSArchana Muniganti extra_len = RTE_MIN(extra_len, size); 389b74652f3SRagothaman Jayaraman /* Insert extra data ptr */ 390b74652f3SRagothaman Jayaraman if (extra_len) { 391b74652f3SRagothaman Jayaraman i++; 392b74652f3SRagothaman Jayaraman to = &list[i >> 2]; 393b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = 3940022ae1eSArchana Muniganti rte_cpu_to_be_16(extra_len); 395b74652f3SRagothaman Jayaraman to->ptr[i % 4] = 396b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(extra_buf->dma_addr); 3970022ae1eSArchana Muniganti size -= extra_len; 398b74652f3SRagothaman Jayaraman } 399b74652f3SRagothaman Jayaraman 4000022ae1eSArchana Muniganti next_len = RTE_MIN(next_len, size); 401b74652f3SRagothaman Jayaraman /* insert the rest of the data */ 402b74652f3SRagothaman Jayaraman if (next_len) { 403b74652f3SRagothaman Jayaraman i++; 404b74652f3SRagothaman Jayaraman to = &list[i >> 2]; 405b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len); 406b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(next_dma); 407b74652f3SRagothaman Jayaraman size -= next_len; 408b74652f3SRagothaman Jayaraman } 409b74652f3SRagothaman Jayaraman extra_len = 0; 410b74652f3SRagothaman Jayaraman 411b74652f3SRagothaman Jayaraman } else { 412b74652f3SRagothaman Jayaraman size -= e_len; 413b74652f3SRagothaman Jayaraman } 414b74652f3SRagothaman Jayaraman if (extra_offset) 415b74652f3SRagothaman Jayaraman extra_offset -= size; 416b74652f3SRagothaman Jayaraman i++; 417b74652f3SRagothaman Jayaraman } 418b74652f3SRagothaman Jayaraman 419b74652f3SRagothaman Jayaraman *psize = size; 420b74652f3SRagothaman Jayaraman return (uint32_t)i; 421b74652f3SRagothaman Jayaraman } 422b74652f3SRagothaman Jayaraman 423f39928e6SAnoob Joseph static __rte_always_inline void 424351fbee2SSrisivasubramanian S cpt_digest_gen_prep(uint32_t flags, 425351fbee2SSrisivasubramanian S uint64_t d_lens, 426351fbee2SSrisivasubramanian S digest_params_t *params, 427351fbee2SSrisivasubramanian S void *op, 428351fbee2SSrisivasubramanian S void **prep_req) 429351fbee2SSrisivasubramanian S { 430351fbee2SSrisivasubramanian S struct cpt_request_info *req; 431351fbee2SSrisivasubramanian S uint32_t size, i; 432351fbee2SSrisivasubramanian S uint16_t data_len, mac_len, key_len; 433351fbee2SSrisivasubramanian S auth_type_t hash_type; 434351fbee2SSrisivasubramanian S buf_ptr_t *meta_p; 435351fbee2SSrisivasubramanian S struct cpt_ctx *ctx; 436351fbee2SSrisivasubramanian S sg_comp_t *gather_comp; 437351fbee2SSrisivasubramanian S sg_comp_t *scatter_comp; 438351fbee2SSrisivasubramanian S uint8_t *in_buffer; 439351fbee2SSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 440351fbee2SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 441351fbee2SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 442351fbee2SSrisivasubramanian S vq_cmd_word3_t vq_cmd_w3; 443351fbee2SSrisivasubramanian S void *c_vaddr, *m_vaddr; 444351fbee2SSrisivasubramanian S uint64_t c_dma, m_dma; 445351fbee2SSrisivasubramanian S opcode_info_t opcode; 446351fbee2SSrisivasubramanian S 447351fbee2SSrisivasubramanian S ctx = params->ctx_buf.vaddr; 448351fbee2SSrisivasubramanian S meta_p = ¶ms->meta_buf; 449351fbee2SSrisivasubramanian S 450351fbee2SSrisivasubramanian S m_vaddr = meta_p->vaddr; 451351fbee2SSrisivasubramanian S m_dma = meta_p->dma_addr; 452351fbee2SSrisivasubramanian S 453351fbee2SSrisivasubramanian S /* 454351fbee2SSrisivasubramanian S * Save initial space that followed app data for completion code & 455351fbee2SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 456351fbee2SSrisivasubramanian S */ 457351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 458351fbee2SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 459351fbee2SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 460351fbee2SSrisivasubramanian S (uint8_t *)m_vaddr; 461351fbee2SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 462351fbee2SSrisivasubramanian S c_dma = m_dma + size; 463351fbee2SSrisivasubramanian S size += sizeof(cpt_res_s_t); 464351fbee2SSrisivasubramanian S 465351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 466351fbee2SSrisivasubramanian S m_dma += size; 467351fbee2SSrisivasubramanian S 468351fbee2SSrisivasubramanian S req = m_vaddr; 469351fbee2SSrisivasubramanian S 470351fbee2SSrisivasubramanian S size = sizeof(struct cpt_request_info); 471351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 472351fbee2SSrisivasubramanian S m_dma += size; 473351fbee2SSrisivasubramanian S 474351fbee2SSrisivasubramanian S hash_type = ctx->hash_type; 475351fbee2SSrisivasubramanian S mac_len = ctx->mac_len; 476351fbee2SSrisivasubramanian S key_len = ctx->auth_key_len; 477351fbee2SSrisivasubramanian S data_len = AUTH_DLEN(d_lens); 478351fbee2SSrisivasubramanian S 479351fbee2SSrisivasubramanian S /*GP op header */ 480351fbee2SSrisivasubramanian S vq_cmd_w0.u64 = 0; 481426af86bSAnoob Joseph vq_cmd_w0.s.param2 = ((uint16_t)hash_type << 8); 482351fbee2SSrisivasubramanian S if (ctx->hmac) { 483351fbee2SSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_HMAC | CPT_DMA_MODE; 484426af86bSAnoob Joseph vq_cmd_w0.s.param1 = key_len; 485426af86bSAnoob Joseph vq_cmd_w0.s.dlen = data_len + ROUNDUP8(key_len); 486351fbee2SSrisivasubramanian S } else { 487351fbee2SSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_HASH | CPT_DMA_MODE; 488351fbee2SSrisivasubramanian S vq_cmd_w0.s.param1 = 0; 489426af86bSAnoob Joseph vq_cmd_w0.s.dlen = data_len; 490351fbee2SSrisivasubramanian S } 491351fbee2SSrisivasubramanian S 492351fbee2SSrisivasubramanian S opcode.s.minor = 0; 493351fbee2SSrisivasubramanian S 494351fbee2SSrisivasubramanian S /* Null auth only case enters the if */ 495351fbee2SSrisivasubramanian S if (unlikely(!hash_type && !ctx->enc_cipher)) { 496351fbee2SSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_MISC; 497351fbee2SSrisivasubramanian S /* Minor op is passthrough */ 498351fbee2SSrisivasubramanian S opcode.s.minor = 0x03; 499351fbee2SSrisivasubramanian S /* Send out completion code only */ 500426af86bSAnoob Joseph vq_cmd_w0.s.param2 = 0x1; 501351fbee2SSrisivasubramanian S } 502351fbee2SSrisivasubramanian S 503426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 504351fbee2SSrisivasubramanian S 505351fbee2SSrisivasubramanian S /* DPTR has SG list */ 506351fbee2SSrisivasubramanian S in_buffer = m_vaddr; 507351fbee2SSrisivasubramanian S dptr_dma = m_dma; 508351fbee2SSrisivasubramanian S 509351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 510351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 511351fbee2SSrisivasubramanian S 512351fbee2SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 513351fbee2SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 514351fbee2SSrisivasubramanian S 515351fbee2SSrisivasubramanian S /* 516351fbee2SSrisivasubramanian S * Input gather list 517351fbee2SSrisivasubramanian S */ 518351fbee2SSrisivasubramanian S 519351fbee2SSrisivasubramanian S i = 0; 520351fbee2SSrisivasubramanian S 521351fbee2SSrisivasubramanian S if (ctx->hmac) { 522351fbee2SSrisivasubramanian S uint64_t k_dma = params->ctx_buf.dma_addr + 523351fbee2SSrisivasubramanian S offsetof(struct cpt_ctx, auth_key); 524351fbee2SSrisivasubramanian S /* Key */ 525351fbee2SSrisivasubramanian S i = fill_sg_comp(gather_comp, i, k_dma, ROUNDUP8(key_len)); 526351fbee2SSrisivasubramanian S } 527351fbee2SSrisivasubramanian S 528351fbee2SSrisivasubramanian S /* input data */ 529351fbee2SSrisivasubramanian S size = data_len; 530351fbee2SSrisivasubramanian S if (size) { 531351fbee2SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 532351fbee2SSrisivasubramanian S 0, &size, NULL, 0); 533f39928e6SAnoob Joseph if (unlikely(size)) { 534351fbee2SSrisivasubramanian S CPT_LOG_DP_DEBUG("Insufficient dst IOV size, short" 535351fbee2SSrisivasubramanian S " by %dB", size); 536f39928e6SAnoob Joseph return; 537351fbee2SSrisivasubramanian S } 538351fbee2SSrisivasubramanian S } else { 539351fbee2SSrisivasubramanian S /* 540351fbee2SSrisivasubramanian S * Looks like we need to support zero data 541351fbee2SSrisivasubramanian S * gather ptr in case of hash & hmac 542351fbee2SSrisivasubramanian S */ 543351fbee2SSrisivasubramanian S i++; 544351fbee2SSrisivasubramanian S } 545351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 546351fbee2SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 547351fbee2SSrisivasubramanian S 548351fbee2SSrisivasubramanian S /* 549351fbee2SSrisivasubramanian S * Output Gather list 550351fbee2SSrisivasubramanian S */ 551351fbee2SSrisivasubramanian S 552351fbee2SSrisivasubramanian S i = 0; 553351fbee2SSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 554351fbee2SSrisivasubramanian S 555351fbee2SSrisivasubramanian S if (flags & VALID_MAC_BUF) { 556f39928e6SAnoob Joseph if (unlikely(params->mac_buf.size < mac_len)) { 557f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient MAC size"); 558f39928e6SAnoob Joseph return; 559f39928e6SAnoob Joseph } 560351fbee2SSrisivasubramanian S 561351fbee2SSrisivasubramanian S size = mac_len; 562351fbee2SSrisivasubramanian S i = fill_sg_comp_from_buf_min(scatter_comp, i, 563351fbee2SSrisivasubramanian S ¶ms->mac_buf, &size); 564351fbee2SSrisivasubramanian S } else { 565351fbee2SSrisivasubramanian S size = mac_len; 566351fbee2SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 567351fbee2SSrisivasubramanian S params->src_iov, data_len, 568351fbee2SSrisivasubramanian S &size, NULL, 0); 569f39928e6SAnoob Joseph if (unlikely(size)) { 570f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient dst IOV size, short by" 571351fbee2SSrisivasubramanian S " %dB", size); 572f39928e6SAnoob Joseph return; 573351fbee2SSrisivasubramanian S } 574351fbee2SSrisivasubramanian S } 575351fbee2SSrisivasubramanian S 576351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 577351fbee2SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 578351fbee2SSrisivasubramanian S 579351fbee2SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 580351fbee2SSrisivasubramanian S 581351fbee2SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 582426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 583351fbee2SSrisivasubramanian S 584351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 585351fbee2SSrisivasubramanian S m_dma += size; 586351fbee2SSrisivasubramanian S 587351fbee2SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 588351fbee2SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 589351fbee2SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 590351fbee2SSrisivasubramanian S rptr_dma = c_dma - 8; 591351fbee2SSrisivasubramanian S 592351fbee2SSrisivasubramanian S req->ist.ei1 = dptr_dma; 593351fbee2SSrisivasubramanian S req->ist.ei2 = rptr_dma; 594351fbee2SSrisivasubramanian S 595351fbee2SSrisivasubramanian S /* vq command w3 */ 596351fbee2SSrisivasubramanian S vq_cmd_w3.u64 = 0; 597351fbee2SSrisivasubramanian S 598351fbee2SSrisivasubramanian S /* 16 byte aligned cpt res address */ 599351fbee2SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 600351fbee2SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 601351fbee2SSrisivasubramanian S req->comp_baddr = c_dma; 602351fbee2SSrisivasubramanian S 603351fbee2SSrisivasubramanian S /* Fill microcode part of instruction */ 604351fbee2SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 605351fbee2SSrisivasubramanian S req->ist.ei3 = vq_cmd_w3.u64; 606351fbee2SSrisivasubramanian S 607351fbee2SSrisivasubramanian S req->op = op; 608351fbee2SSrisivasubramanian S 609351fbee2SSrisivasubramanian S *prep_req = req; 610f39928e6SAnoob Joseph return; 611351fbee2SSrisivasubramanian S } 612351fbee2SSrisivasubramanian S 613f39928e6SAnoob Joseph static __rte_always_inline void 614b74652f3SRagothaman Jayaraman cpt_enc_hmac_prep(uint32_t flags, 615b74652f3SRagothaman Jayaraman uint64_t d_offs, 616b74652f3SRagothaman Jayaraman uint64_t d_lens, 617b74652f3SRagothaman Jayaraman fc_params_t *fc_params, 618b74652f3SRagothaman Jayaraman void *op, 619b74652f3SRagothaman Jayaraman void **prep_req) 620b74652f3SRagothaman Jayaraman { 621b74652f3SRagothaman Jayaraman uint32_t iv_offset = 0; 622b74652f3SRagothaman Jayaraman int32_t inputlen, outputlen, enc_dlen, auth_dlen; 623b74652f3SRagothaman Jayaraman struct cpt_ctx *cpt_ctx; 624b74652f3SRagothaman Jayaraman uint32_t cipher_type, hash_type; 625b74652f3SRagothaman Jayaraman uint32_t mac_len, size; 626b74652f3SRagothaman Jayaraman uint8_t iv_len = 16; 627b74652f3SRagothaman Jayaraman struct cpt_request_info *req; 628b74652f3SRagothaman Jayaraman buf_ptr_t *meta_p, *aad_buf = NULL; 629b74652f3SRagothaman Jayaraman uint32_t encr_offset, auth_offset; 630b74652f3SRagothaman Jayaraman uint32_t encr_data_len, auth_data_len, aad_len = 0; 631b74652f3SRagothaman Jayaraman uint32_t passthrough_len = 0; 632b74652f3SRagothaman Jayaraman void *m_vaddr, *offset_vaddr; 633b74652f3SRagothaman Jayaraman uint64_t m_dma, offset_dma, ctx_dma; 634b74652f3SRagothaman Jayaraman vq_cmd_word0_t vq_cmd_w0; 635b74652f3SRagothaman Jayaraman vq_cmd_word3_t vq_cmd_w3; 636b74652f3SRagothaman Jayaraman void *c_vaddr; 637b74652f3SRagothaman Jayaraman uint64_t c_dma; 638b74652f3SRagothaman Jayaraman opcode_info_t opcode; 639b74652f3SRagothaman Jayaraman 640b74652f3SRagothaman Jayaraman meta_p = &fc_params->meta_buf; 641b74652f3SRagothaman Jayaraman m_vaddr = meta_p->vaddr; 642b74652f3SRagothaman Jayaraman m_dma = meta_p->dma_addr; 643b74652f3SRagothaman Jayaraman 644b74652f3SRagothaman Jayaraman encr_offset = ENCR_OFFSET(d_offs); 645b74652f3SRagothaman Jayaraman auth_offset = AUTH_OFFSET(d_offs); 646b74652f3SRagothaman Jayaraman encr_data_len = ENCR_DLEN(d_lens); 647b74652f3SRagothaman Jayaraman auth_data_len = AUTH_DLEN(d_lens); 648b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 649b74652f3SRagothaman Jayaraman /* 650b74652f3SRagothaman Jayaraman * We dont support both aad 651b74652f3SRagothaman Jayaraman * and auth data separately 652b74652f3SRagothaman Jayaraman */ 653b74652f3SRagothaman Jayaraman auth_data_len = 0; 654b74652f3SRagothaman Jayaraman auth_offset = 0; 655b74652f3SRagothaman Jayaraman aad_len = fc_params->aad_buf.size; 656b74652f3SRagothaman Jayaraman aad_buf = &fc_params->aad_buf; 657b74652f3SRagothaman Jayaraman } 658b74652f3SRagothaman Jayaraman cpt_ctx = fc_params->ctx_buf.vaddr; 659b74652f3SRagothaman Jayaraman cipher_type = cpt_ctx->enc_cipher; 660b74652f3SRagothaman Jayaraman hash_type = cpt_ctx->hash_type; 661b74652f3SRagothaman Jayaraman mac_len = cpt_ctx->mac_len; 662b74652f3SRagothaman Jayaraman 663b74652f3SRagothaman Jayaraman /* 664b74652f3SRagothaman Jayaraman * Save initial space that followed app data for completion code & 665b74652f3SRagothaman Jayaraman * alternate completion code to fall in same cache line as app data 666b74652f3SRagothaman Jayaraman */ 667b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 668b74652f3SRagothaman Jayaraman m_dma += COMPLETION_CODE_SIZE; 669b74652f3SRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 670b74652f3SRagothaman Jayaraman (uint8_t *)m_vaddr; 671b74652f3SRagothaman Jayaraman 672b74652f3SRagothaman Jayaraman c_vaddr = (uint8_t *)m_vaddr + size; 673b74652f3SRagothaman Jayaraman c_dma = m_dma + size; 674b74652f3SRagothaman Jayaraman size += sizeof(cpt_res_s_t); 675b74652f3SRagothaman Jayaraman 676b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 677b74652f3SRagothaman Jayaraman m_dma += size; 678b74652f3SRagothaman Jayaraman 679b74652f3SRagothaman Jayaraman /* start cpt request info struct at 8 byte boundary */ 680b74652f3SRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 681b74652f3SRagothaman Jayaraman (uint8_t *)m_vaddr; 682b74652f3SRagothaman Jayaraman 683b74652f3SRagothaman Jayaraman req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 684b74652f3SRagothaman Jayaraman 685b74652f3SRagothaman Jayaraman size += sizeof(struct cpt_request_info); 686b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 687b74652f3SRagothaman Jayaraman m_dma += size; 688b74652f3SRagothaman Jayaraman 689b74652f3SRagothaman Jayaraman if (unlikely(!(flags & VALID_IV_BUF))) { 690b74652f3SRagothaman Jayaraman iv_len = 0; 691b74652f3SRagothaman Jayaraman iv_offset = ENCR_IV_OFFSET(d_offs); 692b74652f3SRagothaman Jayaraman } 693b74652f3SRagothaman Jayaraman 694b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 695b74652f3SRagothaman Jayaraman /* 696b74652f3SRagothaman Jayaraman * When AAD is given, data above encr_offset is pass through 697b74652f3SRagothaman Jayaraman * Since AAD is given as separate pointer and not as offset, 698b74652f3SRagothaman Jayaraman * this is a special case as we need to fragment input data 699b74652f3SRagothaman Jayaraman * into passthrough + encr_data and then insert AAD in between. 700b74652f3SRagothaman Jayaraman */ 701b74652f3SRagothaman Jayaraman if (hash_type != GMAC_TYPE) { 702b74652f3SRagothaman Jayaraman passthrough_len = encr_offset; 703b74652f3SRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 704b74652f3SRagothaman Jayaraman encr_offset = passthrough_len + aad_len + iv_len; 705b74652f3SRagothaman Jayaraman auth_data_len = aad_len + encr_data_len; 706b74652f3SRagothaman Jayaraman } else { 707b74652f3SRagothaman Jayaraman passthrough_len = 16 + aad_len; 708b74652f3SRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 709b74652f3SRagothaman Jayaraman auth_data_len = aad_len; 710b74652f3SRagothaman Jayaraman } 711b74652f3SRagothaman Jayaraman } else { 712b74652f3SRagothaman Jayaraman encr_offset += iv_len; 713b74652f3SRagothaman Jayaraman auth_offset += iv_len; 714b74652f3SRagothaman Jayaraman } 715b74652f3SRagothaman Jayaraman 716b74652f3SRagothaman Jayaraman /* Encryption */ 717b74652f3SRagothaman Jayaraman opcode.s.major = CPT_MAJOR_OP_FC; 718b74652f3SRagothaman Jayaraman opcode.s.minor = 0; 719b74652f3SRagothaman Jayaraman 7200058f305SAnkur Dwivedi if (hash_type == GMAC_TYPE) { 7210058f305SAnkur Dwivedi encr_offset = 0; 7220058f305SAnkur Dwivedi encr_data_len = 0; 7230058f305SAnkur Dwivedi } 7240058f305SAnkur Dwivedi 725b74652f3SRagothaman Jayaraman auth_dlen = auth_offset + auth_data_len; 726b74652f3SRagothaman Jayaraman enc_dlen = encr_data_len + encr_offset; 727b74652f3SRagothaman Jayaraman if (unlikely(encr_data_len & 0xf)) { 728b74652f3SRagothaman Jayaraman if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB)) 729b74652f3SRagothaman Jayaraman enc_dlen = ROUNDUP8(encr_data_len) + encr_offset; 730b74652f3SRagothaman Jayaraman else if (likely((cipher_type == AES_CBC) || 731b74652f3SRagothaman Jayaraman (cipher_type == AES_ECB))) 732b74652f3SRagothaman Jayaraman enc_dlen = ROUNDUP16(encr_data_len) + encr_offset; 733b74652f3SRagothaman Jayaraman } 734b74652f3SRagothaman Jayaraman 735b74652f3SRagothaman Jayaraman if (unlikely(auth_dlen > enc_dlen)) { 736b74652f3SRagothaman Jayaraman inputlen = auth_dlen; 737b74652f3SRagothaman Jayaraman outputlen = auth_dlen + mac_len; 738b74652f3SRagothaman Jayaraman } else { 739b74652f3SRagothaman Jayaraman inputlen = enc_dlen; 740b74652f3SRagothaman Jayaraman outputlen = enc_dlen + mac_len; 741b74652f3SRagothaman Jayaraman } 742b74652f3SRagothaman Jayaraman 743b74652f3SRagothaman Jayaraman /* GP op header */ 744b74652f3SRagothaman Jayaraman vq_cmd_w0.u64 = 0; 745426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 746426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 747b74652f3SRagothaman Jayaraman /* 748b74652f3SRagothaman Jayaraman * In 83XX since we have a limitation of 749b74652f3SRagothaman Jayaraman * IV & Offset control word not part of instruction 750b74652f3SRagothaman Jayaraman * and need to be part of Data Buffer, we check if 751b74652f3SRagothaman Jayaraman * head room is there and then only do the Direct mode processing 752b74652f3SRagothaman Jayaraman */ 753b74652f3SRagothaman Jayaraman if (likely((flags & SINGLE_BUF_INPLACE) && 754b74652f3SRagothaman Jayaraman (flags & SINGLE_BUF_HEADTAILROOM))) { 755b74652f3SRagothaman Jayaraman void *dm_vaddr = fc_params->bufs[0].vaddr; 756b74652f3SRagothaman Jayaraman uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 757b74652f3SRagothaman Jayaraman /* 758b74652f3SRagothaman Jayaraman * This flag indicates that there is 24 bytes head room and 759b74652f3SRagothaman Jayaraman * 8 bytes tail room available, so that we get to do 760b74652f3SRagothaman Jayaraman * DIRECT MODE with limitation 761b74652f3SRagothaman Jayaraman */ 762b74652f3SRagothaman Jayaraman 763b74652f3SRagothaman Jayaraman offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 764b74652f3SRagothaman Jayaraman offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 765b74652f3SRagothaman Jayaraman 766b74652f3SRagothaman Jayaraman /* DPTR */ 767b74652f3SRagothaman Jayaraman req->ist.ei1 = offset_dma; 768b74652f3SRagothaman Jayaraman /* RPTR should just exclude offset control word */ 769b74652f3SRagothaman Jayaraman req->ist.ei2 = dm_dma_addr - iv_len; 770b74652f3SRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 771b74652f3SRagothaman Jayaraman + outputlen - iv_len); 772b74652f3SRagothaman Jayaraman 773426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 774b74652f3SRagothaman Jayaraman 775426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 776b74652f3SRagothaman Jayaraman 777b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 778b74652f3SRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 779b74652f3SRagothaman Jayaraman + OFF_CTRL_LEN); 780b74652f3SRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 781b74652f3SRagothaman Jayaraman dest[0] = src[0]; 782b74652f3SRagothaman Jayaraman dest[1] = src[1]; 783b74652f3SRagothaman Jayaraman } 784b74652f3SRagothaman Jayaraman 785b74652f3SRagothaman Jayaraman *(uint64_t *)offset_vaddr = 786b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 787b74652f3SRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 788b74652f3SRagothaman Jayaraman ((uint64_t)auth_offset)); 789b74652f3SRagothaman Jayaraman 790b74652f3SRagothaman Jayaraman } else { 791b74652f3SRagothaman Jayaraman uint32_t i, g_size_bytes, s_size_bytes; 792b74652f3SRagothaman Jayaraman uint64_t dptr_dma, rptr_dma; 793b74652f3SRagothaman Jayaraman sg_comp_t *gather_comp; 794b74652f3SRagothaman Jayaraman sg_comp_t *scatter_comp; 795b74652f3SRagothaman Jayaraman uint8_t *in_buffer; 796b74652f3SRagothaman Jayaraman 797b74652f3SRagothaman Jayaraman /* This falls under strict SG mode */ 798b74652f3SRagothaman Jayaraman offset_vaddr = m_vaddr; 799b74652f3SRagothaman Jayaraman offset_dma = m_dma; 800b74652f3SRagothaman Jayaraman size = OFF_CTRL_LEN + iv_len; 801b74652f3SRagothaman Jayaraman 802b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 803b74652f3SRagothaman Jayaraman m_dma += size; 804b74652f3SRagothaman Jayaraman 805b74652f3SRagothaman Jayaraman opcode.s.major |= CPT_DMA_MODE; 806b74652f3SRagothaman Jayaraman 807426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 808b74652f3SRagothaman Jayaraman 809b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 810b74652f3SRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 811b74652f3SRagothaman Jayaraman + OFF_CTRL_LEN); 812b74652f3SRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 813b74652f3SRagothaman Jayaraman dest[0] = src[0]; 814b74652f3SRagothaman Jayaraman dest[1] = src[1]; 815b74652f3SRagothaman Jayaraman } 816b74652f3SRagothaman Jayaraman 817b74652f3SRagothaman Jayaraman *(uint64_t *)offset_vaddr = 818b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 819b74652f3SRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 820b74652f3SRagothaman Jayaraman ((uint64_t)auth_offset)); 821b74652f3SRagothaman Jayaraman 822b74652f3SRagothaman Jayaraman /* DPTR has SG list */ 823b74652f3SRagothaman Jayaraman in_buffer = m_vaddr; 824b74652f3SRagothaman Jayaraman dptr_dma = m_dma; 825b74652f3SRagothaman Jayaraman 826b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[0] = 0; 827b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[1] = 0; 828b74652f3SRagothaman Jayaraman 829b74652f3SRagothaman Jayaraman /* TODO Add error check if space will be sufficient */ 830b74652f3SRagothaman Jayaraman gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 831b74652f3SRagothaman Jayaraman 832b74652f3SRagothaman Jayaraman /* 833b74652f3SRagothaman Jayaraman * Input Gather List 834b74652f3SRagothaman Jayaraman */ 835b74652f3SRagothaman Jayaraman 836b74652f3SRagothaman Jayaraman i = 0; 837b74652f3SRagothaman Jayaraman 838b74652f3SRagothaman Jayaraman /* Offset control word that includes iv */ 839b74652f3SRagothaman Jayaraman i = fill_sg_comp(gather_comp, i, offset_dma, 840b74652f3SRagothaman Jayaraman OFF_CTRL_LEN + iv_len); 841b74652f3SRagothaman Jayaraman 842b74652f3SRagothaman Jayaraman /* Add input data */ 843b74652f3SRagothaman Jayaraman size = inputlen - iv_len; 844b74652f3SRagothaman Jayaraman if (likely(size)) { 845b74652f3SRagothaman Jayaraman uint32_t aad_offset = aad_len ? passthrough_len : 0; 846b74652f3SRagothaman Jayaraman 847b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 848b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min(gather_comp, i, 849b74652f3SRagothaman Jayaraman fc_params->bufs, 850b74652f3SRagothaman Jayaraman &size); 851b74652f3SRagothaman Jayaraman } else { 852b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(gather_comp, i, 853b74652f3SRagothaman Jayaraman fc_params->src_iov, 854b74652f3SRagothaman Jayaraman 0, &size, 855b74652f3SRagothaman Jayaraman aad_buf, aad_offset); 856b74652f3SRagothaman Jayaraman } 857b74652f3SRagothaman Jayaraman 858b74652f3SRagothaman Jayaraman if (unlikely(size)) { 859b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Insufficient buffer space," 860b74652f3SRagothaman Jayaraman " size %d needed", size); 861f39928e6SAnoob Joseph return; 862b74652f3SRagothaman Jayaraman } 863b74652f3SRagothaman Jayaraman } 864b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 865b74652f3SRagothaman Jayaraman g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 866b74652f3SRagothaman Jayaraman 867b74652f3SRagothaman Jayaraman /* 868b74652f3SRagothaman Jayaraman * Output Scatter list 869b74652f3SRagothaman Jayaraman */ 870b74652f3SRagothaman Jayaraman i = 0; 871b74652f3SRagothaman Jayaraman scatter_comp = 872b74652f3SRagothaman Jayaraman (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 873b74652f3SRagothaman Jayaraman 874b74652f3SRagothaman Jayaraman /* Add IV */ 875b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 876b74652f3SRagothaman Jayaraman i = fill_sg_comp(scatter_comp, i, 877b74652f3SRagothaman Jayaraman offset_dma + OFF_CTRL_LEN, 878b74652f3SRagothaman Jayaraman iv_len); 879b74652f3SRagothaman Jayaraman } 880b74652f3SRagothaman Jayaraman 881b74652f3SRagothaman Jayaraman /* output data or output data + digest*/ 882b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_MAC_BUF)) { 883b74652f3SRagothaman Jayaraman size = outputlen - iv_len - mac_len; 884b74652f3SRagothaman Jayaraman if (size) { 885b74652f3SRagothaman Jayaraman uint32_t aad_offset = 886b74652f3SRagothaman Jayaraman aad_len ? passthrough_len : 0; 887b74652f3SRagothaman Jayaraman 888b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 889b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 890b74652f3SRagothaman Jayaraman scatter_comp, 891b74652f3SRagothaman Jayaraman i, 892b74652f3SRagothaman Jayaraman fc_params->bufs, 893b74652f3SRagothaman Jayaraman &size); 894b74652f3SRagothaman Jayaraman } else { 895b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, 896b74652f3SRagothaman Jayaraman i, 897b74652f3SRagothaman Jayaraman fc_params->dst_iov, 898b74652f3SRagothaman Jayaraman 0, 899b74652f3SRagothaman Jayaraman &size, 900b74652f3SRagothaman Jayaraman aad_buf, 901b74652f3SRagothaman Jayaraman aad_offset); 902b74652f3SRagothaman Jayaraman } 903f39928e6SAnoob Joseph if (unlikely(size)) { 904f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 905f39928e6SAnoob Joseph " space, size %d needed", 906f39928e6SAnoob Joseph size); 907f39928e6SAnoob Joseph return; 908f39928e6SAnoob Joseph } 909b74652f3SRagothaman Jayaraman } 910b74652f3SRagothaman Jayaraman /* mac_data */ 911b74652f3SRagothaman Jayaraman if (mac_len) { 912b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf(scatter_comp, i, 913b74652f3SRagothaman Jayaraman &fc_params->mac_buf); 914b74652f3SRagothaman Jayaraman } 915b74652f3SRagothaman Jayaraman } else { 916b74652f3SRagothaman Jayaraman /* Output including mac */ 917b74652f3SRagothaman Jayaraman size = outputlen - iv_len; 918b74652f3SRagothaman Jayaraman if (likely(size)) { 919b74652f3SRagothaman Jayaraman uint32_t aad_offset = 920b74652f3SRagothaman Jayaraman aad_len ? passthrough_len : 0; 921b74652f3SRagothaman Jayaraman 922b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 923b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 924b74652f3SRagothaman Jayaraman scatter_comp, 925b74652f3SRagothaman Jayaraman i, 926b74652f3SRagothaman Jayaraman fc_params->bufs, 927b74652f3SRagothaman Jayaraman &size); 928b74652f3SRagothaman Jayaraman } else { 929b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, 930b74652f3SRagothaman Jayaraman i, 931b74652f3SRagothaman Jayaraman fc_params->dst_iov, 932b74652f3SRagothaman Jayaraman 0, 933b74652f3SRagothaman Jayaraman &size, 934b74652f3SRagothaman Jayaraman aad_buf, 935b74652f3SRagothaman Jayaraman aad_offset); 936b74652f3SRagothaman Jayaraman } 937b74652f3SRagothaman Jayaraman if (unlikely(size)) { 938b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Insufficient buffer" 939b74652f3SRagothaman Jayaraman " space, size %d needed", 940b74652f3SRagothaman Jayaraman size); 941f39928e6SAnoob Joseph return; 942b74652f3SRagothaman Jayaraman } 943b74652f3SRagothaman Jayaraman } 944b74652f3SRagothaman Jayaraman } 945b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 946b74652f3SRagothaman Jayaraman s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 947b74652f3SRagothaman Jayaraman 948b74652f3SRagothaman Jayaraman size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 949b74652f3SRagothaman Jayaraman 950b74652f3SRagothaman Jayaraman /* This is DPTR len incase of SG mode */ 951426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 952b74652f3SRagothaman Jayaraman 953b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 954b74652f3SRagothaman Jayaraman m_dma += size; 955b74652f3SRagothaman Jayaraman 956b74652f3SRagothaman Jayaraman /* cpt alternate completion address saved earlier */ 957b74652f3SRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 958b74652f3SRagothaman Jayaraman *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 959b74652f3SRagothaman Jayaraman rptr_dma = c_dma - 8; 960b74652f3SRagothaman Jayaraman 961b74652f3SRagothaman Jayaraman req->ist.ei1 = dptr_dma; 962b74652f3SRagothaman Jayaraman req->ist.ei2 = rptr_dma; 963b74652f3SRagothaman Jayaraman } 964b74652f3SRagothaman Jayaraman 965b74652f3SRagothaman Jayaraman ctx_dma = fc_params->ctx_buf.dma_addr + 966b74652f3SRagothaman Jayaraman offsetof(struct cpt_ctx, fctx); 967b74652f3SRagothaman Jayaraman /* vq command w3 */ 968b74652f3SRagothaman Jayaraman vq_cmd_w3.u64 = 0; 969b74652f3SRagothaman Jayaraman vq_cmd_w3.s.grp = 0; 970b74652f3SRagothaman Jayaraman vq_cmd_w3.s.cptr = ctx_dma; 971b74652f3SRagothaman Jayaraman 972b74652f3SRagothaman Jayaraman /* 16 byte aligned cpt res address */ 973b74652f3SRagothaman Jayaraman req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 974b74652f3SRagothaman Jayaraman *req->completion_addr = COMPLETION_CODE_INIT; 975b74652f3SRagothaman Jayaraman req->comp_baddr = c_dma; 976b74652f3SRagothaman Jayaraman 977b74652f3SRagothaman Jayaraman /* Fill microcode part of instruction */ 978b74652f3SRagothaman Jayaraman req->ist.ei0 = vq_cmd_w0.u64; 979b74652f3SRagothaman Jayaraman req->ist.ei3 = vq_cmd_w3.u64; 980b74652f3SRagothaman Jayaraman 981b74652f3SRagothaman Jayaraman req->op = op; 982b74652f3SRagothaman Jayaraman 983b74652f3SRagothaman Jayaraman *prep_req = req; 984f39928e6SAnoob Joseph return; 985b74652f3SRagothaman Jayaraman } 986b74652f3SRagothaman Jayaraman 987f39928e6SAnoob Joseph static __rte_always_inline void 988177b41ceSRagothaman Jayaraman cpt_dec_hmac_prep(uint32_t flags, 989177b41ceSRagothaman Jayaraman uint64_t d_offs, 990177b41ceSRagothaman Jayaraman uint64_t d_lens, 991177b41ceSRagothaman Jayaraman fc_params_t *fc_params, 992177b41ceSRagothaman Jayaraman void *op, 993177b41ceSRagothaman Jayaraman void **prep_req) 994177b41ceSRagothaman Jayaraman { 995177b41ceSRagothaman Jayaraman uint32_t iv_offset = 0, size; 996177b41ceSRagothaman Jayaraman int32_t inputlen, outputlen, enc_dlen, auth_dlen; 997177b41ceSRagothaman Jayaraman struct cpt_ctx *cpt_ctx; 9988de5ede7SAnoob Joseph int32_t hash_type, mac_len; 999177b41ceSRagothaman Jayaraman uint8_t iv_len = 16; 1000177b41ceSRagothaman Jayaraman struct cpt_request_info *req; 1001177b41ceSRagothaman Jayaraman buf_ptr_t *meta_p, *aad_buf = NULL; 1002177b41ceSRagothaman Jayaraman uint32_t encr_offset, auth_offset; 1003177b41ceSRagothaman Jayaraman uint32_t encr_data_len, auth_data_len, aad_len = 0; 1004177b41ceSRagothaman Jayaraman uint32_t passthrough_len = 0; 1005177b41ceSRagothaman Jayaraman void *m_vaddr, *offset_vaddr; 1006177b41ceSRagothaman Jayaraman uint64_t m_dma, offset_dma, ctx_dma; 1007177b41ceSRagothaman Jayaraman opcode_info_t opcode; 1008177b41ceSRagothaman Jayaraman vq_cmd_word0_t vq_cmd_w0; 1009177b41ceSRagothaman Jayaraman vq_cmd_word3_t vq_cmd_w3; 1010177b41ceSRagothaman Jayaraman void *c_vaddr; 1011177b41ceSRagothaman Jayaraman uint64_t c_dma; 1012177b41ceSRagothaman Jayaraman 1013177b41ceSRagothaman Jayaraman meta_p = &fc_params->meta_buf; 1014177b41ceSRagothaman Jayaraman m_vaddr = meta_p->vaddr; 1015177b41ceSRagothaman Jayaraman m_dma = meta_p->dma_addr; 1016177b41ceSRagothaman Jayaraman 1017177b41ceSRagothaman Jayaraman encr_offset = ENCR_OFFSET(d_offs); 1018177b41ceSRagothaman Jayaraman auth_offset = AUTH_OFFSET(d_offs); 1019177b41ceSRagothaman Jayaraman encr_data_len = ENCR_DLEN(d_lens); 1020177b41ceSRagothaman Jayaraman auth_data_len = AUTH_DLEN(d_lens); 1021177b41ceSRagothaman Jayaraman 1022177b41ceSRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 1023177b41ceSRagothaman Jayaraman /* 1024177b41ceSRagothaman Jayaraman * We dont support both aad 1025177b41ceSRagothaman Jayaraman * and auth data separately 1026177b41ceSRagothaman Jayaraman */ 1027177b41ceSRagothaman Jayaraman auth_data_len = 0; 1028177b41ceSRagothaman Jayaraman auth_offset = 0; 1029177b41ceSRagothaman Jayaraman aad_len = fc_params->aad_buf.size; 1030177b41ceSRagothaman Jayaraman aad_buf = &fc_params->aad_buf; 1031177b41ceSRagothaman Jayaraman } 1032177b41ceSRagothaman Jayaraman 1033177b41ceSRagothaman Jayaraman cpt_ctx = fc_params->ctx_buf.vaddr; 1034177b41ceSRagothaman Jayaraman hash_type = cpt_ctx->hash_type; 1035177b41ceSRagothaman Jayaraman mac_len = cpt_ctx->mac_len; 1036177b41ceSRagothaman Jayaraman 1037177b41ceSRagothaman Jayaraman if (unlikely(!(flags & VALID_IV_BUF))) { 1038177b41ceSRagothaman Jayaraman iv_len = 0; 1039177b41ceSRagothaman Jayaraman iv_offset = ENCR_IV_OFFSET(d_offs); 1040177b41ceSRagothaman Jayaraman } 1041177b41ceSRagothaman Jayaraman 1042177b41ceSRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 1043177b41ceSRagothaman Jayaraman /* 1044177b41ceSRagothaman Jayaraman * When AAD is given, data above encr_offset is pass through 1045177b41ceSRagothaman Jayaraman * Since AAD is given as separate pointer and not as offset, 1046177b41ceSRagothaman Jayaraman * this is a special case as we need to fragment input data 1047177b41ceSRagothaman Jayaraman * into passthrough + encr_data and then insert AAD in between. 1048177b41ceSRagothaman Jayaraman */ 1049177b41ceSRagothaman Jayaraman if (hash_type != GMAC_TYPE) { 1050177b41ceSRagothaman Jayaraman passthrough_len = encr_offset; 1051177b41ceSRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 1052177b41ceSRagothaman Jayaraman encr_offset = passthrough_len + aad_len + iv_len; 1053177b41ceSRagothaman Jayaraman auth_data_len = aad_len + encr_data_len; 1054177b41ceSRagothaman Jayaraman } else { 1055177b41ceSRagothaman Jayaraman passthrough_len = 16 + aad_len; 1056177b41ceSRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 1057177b41ceSRagothaman Jayaraman auth_data_len = aad_len; 1058177b41ceSRagothaman Jayaraman } 1059177b41ceSRagothaman Jayaraman } else { 1060177b41ceSRagothaman Jayaraman encr_offset += iv_len; 1061177b41ceSRagothaman Jayaraman auth_offset += iv_len; 1062177b41ceSRagothaman Jayaraman } 1063177b41ceSRagothaman Jayaraman 1064177b41ceSRagothaman Jayaraman /* 1065177b41ceSRagothaman Jayaraman * Save initial space that followed app data for completion code & 1066177b41ceSRagothaman Jayaraman * alternate completion code to fall in same cache line as app data 1067177b41ceSRagothaman Jayaraman */ 1068177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 1069177b41ceSRagothaman Jayaraman m_dma += COMPLETION_CODE_SIZE; 1070177b41ceSRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 1071177b41ceSRagothaman Jayaraman (uint8_t *)m_vaddr; 1072177b41ceSRagothaman Jayaraman c_vaddr = (uint8_t *)m_vaddr + size; 1073177b41ceSRagothaman Jayaraman c_dma = m_dma + size; 1074177b41ceSRagothaman Jayaraman size += sizeof(cpt_res_s_t); 1075177b41ceSRagothaman Jayaraman 1076177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1077177b41ceSRagothaman Jayaraman m_dma += size; 1078177b41ceSRagothaman Jayaraman 1079177b41ceSRagothaman Jayaraman /* start cpt request info structure at 8 byte alignment */ 1080177b41ceSRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 1081177b41ceSRagothaman Jayaraman (uint8_t *)m_vaddr; 1082177b41ceSRagothaman Jayaraman 1083177b41ceSRagothaman Jayaraman req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 1084177b41ceSRagothaman Jayaraman 1085177b41ceSRagothaman Jayaraman size += sizeof(struct cpt_request_info); 1086177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1087177b41ceSRagothaman Jayaraman m_dma += size; 1088177b41ceSRagothaman Jayaraman 1089177b41ceSRagothaman Jayaraman /* Decryption */ 1090177b41ceSRagothaman Jayaraman opcode.s.major = CPT_MAJOR_OP_FC; 1091177b41ceSRagothaman Jayaraman opcode.s.minor = 1; 1092177b41ceSRagothaman Jayaraman 10930058f305SAnkur Dwivedi if (hash_type == GMAC_TYPE) { 10940058f305SAnkur Dwivedi encr_offset = 0; 10950058f305SAnkur Dwivedi encr_data_len = 0; 10960058f305SAnkur Dwivedi } 10970058f305SAnkur Dwivedi 1098177b41ceSRagothaman Jayaraman enc_dlen = encr_offset + encr_data_len; 1099177b41ceSRagothaman Jayaraman auth_dlen = auth_offset + auth_data_len; 1100177b41ceSRagothaman Jayaraman 1101177b41ceSRagothaman Jayaraman if (auth_dlen > enc_dlen) { 1102177b41ceSRagothaman Jayaraman inputlen = auth_dlen + mac_len; 1103177b41ceSRagothaman Jayaraman outputlen = auth_dlen; 1104177b41ceSRagothaman Jayaraman } else { 1105177b41ceSRagothaman Jayaraman inputlen = enc_dlen + mac_len; 1106177b41ceSRagothaman Jayaraman outputlen = enc_dlen; 1107177b41ceSRagothaman Jayaraman } 1108177b41ceSRagothaman Jayaraman 1109177b41ceSRagothaman Jayaraman vq_cmd_w0.u64 = 0; 1110426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 1111426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 1112177b41ceSRagothaman Jayaraman 1113177b41ceSRagothaman Jayaraman /* 1114177b41ceSRagothaman Jayaraman * In 83XX since we have a limitation of 1115177b41ceSRagothaman Jayaraman * IV & Offset control word not part of instruction 1116177b41ceSRagothaman Jayaraman * and need to be part of Data Buffer, we check if 1117177b41ceSRagothaman Jayaraman * head room is there and then only do the Direct mode processing 1118177b41ceSRagothaman Jayaraman */ 1119177b41ceSRagothaman Jayaraman if (likely((flags & SINGLE_BUF_INPLACE) && 1120177b41ceSRagothaman Jayaraman (flags & SINGLE_BUF_HEADTAILROOM))) { 1121177b41ceSRagothaman Jayaraman void *dm_vaddr = fc_params->bufs[0].vaddr; 1122177b41ceSRagothaman Jayaraman uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 1123177b41ceSRagothaman Jayaraman /* 1124177b41ceSRagothaman Jayaraman * This flag indicates that there is 24 bytes head room and 1125177b41ceSRagothaman Jayaraman * 8 bytes tail room available, so that we get to do 1126177b41ceSRagothaman Jayaraman * DIRECT MODE with limitation 1127177b41ceSRagothaman Jayaraman */ 1128177b41ceSRagothaman Jayaraman 1129177b41ceSRagothaman Jayaraman offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 1130177b41ceSRagothaman Jayaraman offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 1131177b41ceSRagothaman Jayaraman req->ist.ei1 = offset_dma; 1132177b41ceSRagothaman Jayaraman 1133177b41ceSRagothaman Jayaraman /* RPTR should just exclude offset control word */ 1134177b41ceSRagothaman Jayaraman req->ist.ei2 = dm_dma_addr - iv_len; 1135177b41ceSRagothaman Jayaraman 1136177b41ceSRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr + 1137177b41ceSRagothaman Jayaraman outputlen - iv_len); 1138177b41ceSRagothaman Jayaraman /* since this is decryption, 1139177b41ceSRagothaman Jayaraman * don't touch the content of 1140177b41ceSRagothaman Jayaraman * alternate ccode space as it contains 1141177b41ceSRagothaman Jayaraman * hmac. 1142177b41ceSRagothaman Jayaraman */ 1143177b41ceSRagothaman Jayaraman 1144426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 1145177b41ceSRagothaman Jayaraman 1146426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 1147177b41ceSRagothaman Jayaraman 1148177b41ceSRagothaman Jayaraman if (likely(iv_len)) { 1149177b41ceSRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1150177b41ceSRagothaman Jayaraman OFF_CTRL_LEN); 1151177b41ceSRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 1152177b41ceSRagothaman Jayaraman dest[0] = src[0]; 1153177b41ceSRagothaman Jayaraman dest[1] = src[1]; 1154177b41ceSRagothaman Jayaraman } 1155177b41ceSRagothaman Jayaraman 1156177b41ceSRagothaman Jayaraman *(uint64_t *)offset_vaddr = 1157177b41ceSRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1158177b41ceSRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 1159177b41ceSRagothaman Jayaraman ((uint64_t)auth_offset)); 1160177b41ceSRagothaman Jayaraman 1161177b41ceSRagothaman Jayaraman } else { 1162177b41ceSRagothaman Jayaraman uint64_t dptr_dma, rptr_dma; 1163177b41ceSRagothaman Jayaraman uint32_t g_size_bytes, s_size_bytes; 1164177b41ceSRagothaman Jayaraman sg_comp_t *gather_comp; 1165177b41ceSRagothaman Jayaraman sg_comp_t *scatter_comp; 1166177b41ceSRagothaman Jayaraman uint8_t *in_buffer; 1167177b41ceSRagothaman Jayaraman uint8_t i = 0; 1168177b41ceSRagothaman Jayaraman 1169177b41ceSRagothaman Jayaraman /* This falls under strict SG mode */ 1170177b41ceSRagothaman Jayaraman offset_vaddr = m_vaddr; 1171177b41ceSRagothaman Jayaraman offset_dma = m_dma; 1172177b41ceSRagothaman Jayaraman size = OFF_CTRL_LEN + iv_len; 1173177b41ceSRagothaman Jayaraman 1174177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1175177b41ceSRagothaman Jayaraman m_dma += size; 1176177b41ceSRagothaman Jayaraman 1177177b41ceSRagothaman Jayaraman opcode.s.major |= CPT_DMA_MODE; 1178177b41ceSRagothaman Jayaraman 1179426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 1180177b41ceSRagothaman Jayaraman 1181177b41ceSRagothaman Jayaraman if (likely(iv_len)) { 1182177b41ceSRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1183177b41ceSRagothaman Jayaraman OFF_CTRL_LEN); 1184177b41ceSRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 1185177b41ceSRagothaman Jayaraman dest[0] = src[0]; 1186177b41ceSRagothaman Jayaraman dest[1] = src[1]; 1187177b41ceSRagothaman Jayaraman } 1188177b41ceSRagothaman Jayaraman 1189177b41ceSRagothaman Jayaraman *(uint64_t *)offset_vaddr = 1190177b41ceSRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1191177b41ceSRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 1192177b41ceSRagothaman Jayaraman ((uint64_t)auth_offset)); 1193177b41ceSRagothaman Jayaraman 1194177b41ceSRagothaman Jayaraman /* DPTR has SG list */ 1195177b41ceSRagothaman Jayaraman in_buffer = m_vaddr; 1196177b41ceSRagothaman Jayaraman dptr_dma = m_dma; 1197177b41ceSRagothaman Jayaraman 1198177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[0] = 0; 1199177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[1] = 0; 1200177b41ceSRagothaman Jayaraman 1201177b41ceSRagothaman Jayaraman /* TODO Add error check if space will be sufficient */ 1202177b41ceSRagothaman Jayaraman gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 1203177b41ceSRagothaman Jayaraman 1204177b41ceSRagothaman Jayaraman /* 1205177b41ceSRagothaman Jayaraman * Input Gather List 1206177b41ceSRagothaman Jayaraman */ 1207177b41ceSRagothaman Jayaraman i = 0; 1208177b41ceSRagothaman Jayaraman 1209177b41ceSRagothaman Jayaraman /* Offset control word that includes iv */ 1210177b41ceSRagothaman Jayaraman i = fill_sg_comp(gather_comp, i, offset_dma, 1211177b41ceSRagothaman Jayaraman OFF_CTRL_LEN + iv_len); 1212177b41ceSRagothaman Jayaraman 1213177b41ceSRagothaman Jayaraman /* Add input data */ 1214177b41ceSRagothaman Jayaraman if (flags & VALID_MAC_BUF) { 1215177b41ceSRagothaman Jayaraman size = inputlen - iv_len - mac_len; 1216177b41ceSRagothaman Jayaraman if (size) { 1217177b41ceSRagothaman Jayaraman /* input data only */ 1218177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1219177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 1220177b41ceSRagothaman Jayaraman gather_comp, i, 1221177b41ceSRagothaman Jayaraman fc_params->bufs, 1222177b41ceSRagothaman Jayaraman &size); 1223177b41ceSRagothaman Jayaraman } else { 1224177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1225177b41ceSRagothaman Jayaraman passthrough_len : 0; 1226177b41ceSRagothaman Jayaraman 1227177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov(gather_comp, 1228177b41ceSRagothaman Jayaraman i, 1229177b41ceSRagothaman Jayaraman fc_params->src_iov, 1230177b41ceSRagothaman Jayaraman 0, &size, 1231177b41ceSRagothaman Jayaraman aad_buf, 1232177b41ceSRagothaman Jayaraman aad_offset); 1233177b41ceSRagothaman Jayaraman } 1234f39928e6SAnoob Joseph if (unlikely(size)) { 1235f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 1236f39928e6SAnoob Joseph " space, size %d needed", 1237f39928e6SAnoob Joseph size); 1238f39928e6SAnoob Joseph return; 1239f39928e6SAnoob Joseph } 1240177b41ceSRagothaman Jayaraman } 1241177b41ceSRagothaman Jayaraman 1242177b41ceSRagothaman Jayaraman /* mac data */ 1243177b41ceSRagothaman Jayaraman if (mac_len) { 1244177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf(gather_comp, i, 1245177b41ceSRagothaman Jayaraman &fc_params->mac_buf); 1246177b41ceSRagothaman Jayaraman } 1247177b41ceSRagothaman Jayaraman } else { 1248177b41ceSRagothaman Jayaraman /* input data + mac */ 1249177b41ceSRagothaman Jayaraman size = inputlen - iv_len; 1250177b41ceSRagothaman Jayaraman if (size) { 1251177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1252177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 1253177b41ceSRagothaman Jayaraman gather_comp, i, 1254177b41ceSRagothaman Jayaraman fc_params->bufs, 1255177b41ceSRagothaman Jayaraman &size); 1256177b41ceSRagothaman Jayaraman } else { 1257177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1258177b41ceSRagothaman Jayaraman passthrough_len : 0; 1259177b41ceSRagothaman Jayaraman 1260f39928e6SAnoob Joseph if (unlikely(!fc_params->src_iov)) { 1261f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Bad input args"); 1262f39928e6SAnoob Joseph return; 1263f39928e6SAnoob Joseph } 1264177b41ceSRagothaman Jayaraman 1265177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov( 1266177b41ceSRagothaman Jayaraman gather_comp, i, 1267177b41ceSRagothaman Jayaraman fc_params->src_iov, 1268177b41ceSRagothaman Jayaraman 0, &size, 1269177b41ceSRagothaman Jayaraman aad_buf, 1270177b41ceSRagothaman Jayaraman aad_offset); 1271177b41ceSRagothaman Jayaraman } 1272177b41ceSRagothaman Jayaraman 1273f39928e6SAnoob Joseph if (unlikely(size)) { 1274f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 1275f39928e6SAnoob Joseph " space, size %d needed", 1276f39928e6SAnoob Joseph size); 1277f39928e6SAnoob Joseph return; 1278f39928e6SAnoob Joseph } 1279177b41ceSRagothaman Jayaraman } 1280177b41ceSRagothaman Jayaraman } 1281177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 1282177b41ceSRagothaman Jayaraman g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1283177b41ceSRagothaman Jayaraman 1284177b41ceSRagothaman Jayaraman /* 1285177b41ceSRagothaman Jayaraman * Output Scatter List 1286177b41ceSRagothaman Jayaraman */ 1287177b41ceSRagothaman Jayaraman 1288177b41ceSRagothaman Jayaraman i = 0; 1289177b41ceSRagothaman Jayaraman scatter_comp = 1290177b41ceSRagothaman Jayaraman (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 1291177b41ceSRagothaman Jayaraman 1292177b41ceSRagothaman Jayaraman /* Add iv */ 1293177b41ceSRagothaman Jayaraman if (iv_len) { 1294177b41ceSRagothaman Jayaraman i = fill_sg_comp(scatter_comp, i, 1295177b41ceSRagothaman Jayaraman offset_dma + OFF_CTRL_LEN, 1296177b41ceSRagothaman Jayaraman iv_len); 1297177b41ceSRagothaman Jayaraman } 1298177b41ceSRagothaman Jayaraman 1299177b41ceSRagothaman Jayaraman /* Add output data */ 1300177b41ceSRagothaman Jayaraman size = outputlen - iv_len; 1301177b41ceSRagothaman Jayaraman if (size) { 1302177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1303177b41ceSRagothaman Jayaraman /* handle single buffer here */ 1304177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min(scatter_comp, i, 1305177b41ceSRagothaman Jayaraman fc_params->bufs, 1306177b41ceSRagothaman Jayaraman &size); 1307177b41ceSRagothaman Jayaraman } else { 1308177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1309177b41ceSRagothaman Jayaraman passthrough_len : 0; 1310177b41ceSRagothaman Jayaraman 1311f39928e6SAnoob Joseph if (unlikely(!fc_params->dst_iov)) { 1312f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Bad input args"); 1313f39928e6SAnoob Joseph return; 1314f39928e6SAnoob Joseph } 1315177b41ceSRagothaman Jayaraman 1316177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, i, 1317177b41ceSRagothaman Jayaraman fc_params->dst_iov, 0, 1318177b41ceSRagothaman Jayaraman &size, aad_buf, 1319177b41ceSRagothaman Jayaraman aad_offset); 1320177b41ceSRagothaman Jayaraman } 1321177b41ceSRagothaman Jayaraman 1322f39928e6SAnoob Joseph if (unlikely(size)) { 1323f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1324f39928e6SAnoob Joseph " size %d needed", size); 1325f39928e6SAnoob Joseph return; 1326f39928e6SAnoob Joseph } 1327177b41ceSRagothaman Jayaraman } 1328177b41ceSRagothaman Jayaraman 1329177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 1330177b41ceSRagothaman Jayaraman s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1331177b41ceSRagothaman Jayaraman 1332177b41ceSRagothaman Jayaraman size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 1333177b41ceSRagothaman Jayaraman 1334177b41ceSRagothaman Jayaraman /* This is DPTR len incase of SG mode */ 1335426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 1336177b41ceSRagothaman Jayaraman 1337177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1338177b41ceSRagothaman Jayaraman m_dma += size; 1339177b41ceSRagothaman Jayaraman 1340177b41ceSRagothaman Jayaraman /* cpt alternate completion address saved earlier */ 1341177b41ceSRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 1342177b41ceSRagothaman Jayaraman *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 1343177b41ceSRagothaman Jayaraman rptr_dma = c_dma - 8; 1344177b41ceSRagothaman Jayaraman size += COMPLETION_CODE_SIZE; 1345177b41ceSRagothaman Jayaraman 1346177b41ceSRagothaman Jayaraman req->ist.ei1 = dptr_dma; 1347177b41ceSRagothaman Jayaraman req->ist.ei2 = rptr_dma; 1348177b41ceSRagothaman Jayaraman } 1349177b41ceSRagothaman Jayaraman 1350177b41ceSRagothaman Jayaraman ctx_dma = fc_params->ctx_buf.dma_addr + 1351177b41ceSRagothaman Jayaraman offsetof(struct cpt_ctx, fctx); 1352177b41ceSRagothaman Jayaraman /* vq command w3 */ 1353177b41ceSRagothaman Jayaraman vq_cmd_w3.u64 = 0; 1354177b41ceSRagothaman Jayaraman vq_cmd_w3.s.grp = 0; 1355177b41ceSRagothaman Jayaraman vq_cmd_w3.s.cptr = ctx_dma; 1356177b41ceSRagothaman Jayaraman 1357177b41ceSRagothaman Jayaraman /* 16 byte aligned cpt res address */ 1358177b41ceSRagothaman Jayaraman req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1359177b41ceSRagothaman Jayaraman *req->completion_addr = COMPLETION_CODE_INIT; 1360177b41ceSRagothaman Jayaraman req->comp_baddr = c_dma; 1361177b41ceSRagothaman Jayaraman 1362177b41ceSRagothaman Jayaraman /* Fill microcode part of instruction */ 1363177b41ceSRagothaman Jayaraman req->ist.ei0 = vq_cmd_w0.u64; 1364177b41ceSRagothaman Jayaraman req->ist.ei3 = vq_cmd_w3.u64; 1365177b41ceSRagothaman Jayaraman 1366177b41ceSRagothaman Jayaraman req->op = op; 1367177b41ceSRagothaman Jayaraman 1368177b41ceSRagothaman Jayaraman *prep_req = req; 1369f39928e6SAnoob Joseph return; 1370177b41ceSRagothaman Jayaraman } 1371177b41ceSRagothaman Jayaraman 1372f39928e6SAnoob Joseph static __rte_always_inline void 137300d92c66SSrisivasubramanian S cpt_zuc_snow3g_enc_prep(uint32_t req_flags, 137400d92c66SSrisivasubramanian S uint64_t d_offs, 137500d92c66SSrisivasubramanian S uint64_t d_lens, 137600d92c66SSrisivasubramanian S fc_params_t *params, 137700d92c66SSrisivasubramanian S void *op, 137800d92c66SSrisivasubramanian S void **prep_req) 137900d92c66SSrisivasubramanian S { 138000d92c66SSrisivasubramanian S uint32_t size; 138100d92c66SSrisivasubramanian S int32_t inputlen, outputlen; 138200d92c66SSrisivasubramanian S struct cpt_ctx *cpt_ctx; 138300d92c66SSrisivasubramanian S uint32_t mac_len = 0; 138400d92c66SSrisivasubramanian S uint8_t snow3g, j; 138500d92c66SSrisivasubramanian S struct cpt_request_info *req; 138600d92c66SSrisivasubramanian S buf_ptr_t *buf_p; 138700d92c66SSrisivasubramanian S uint32_t encr_offset = 0, auth_offset = 0; 138800d92c66SSrisivasubramanian S uint32_t encr_data_len = 0, auth_data_len = 0; 13898de5ede7SAnoob Joseph int flags, iv_len = 16; 139000d92c66SSrisivasubramanian S void *m_vaddr, *c_vaddr; 139100d92c66SSrisivasubramanian S uint64_t m_dma, c_dma, offset_ctrl; 139200d92c66SSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 139300d92c66SSrisivasubramanian S uint32_t *iv_s, iv[4]; 139400d92c66SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 139500d92c66SSrisivasubramanian S vq_cmd_word3_t vq_cmd_w3; 139600d92c66SSrisivasubramanian S opcode_info_t opcode; 139700d92c66SSrisivasubramanian S 139800d92c66SSrisivasubramanian S buf_p = ¶ms->meta_buf; 139900d92c66SSrisivasubramanian S m_vaddr = buf_p->vaddr; 140000d92c66SSrisivasubramanian S m_dma = buf_p->dma_addr; 140100d92c66SSrisivasubramanian S 140200d92c66SSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 140300d92c66SSrisivasubramanian S flags = cpt_ctx->zsk_flags; 140400d92c66SSrisivasubramanian S mac_len = cpt_ctx->mac_len; 140500d92c66SSrisivasubramanian S snow3g = cpt_ctx->snow3g; 140600d92c66SSrisivasubramanian S 140700d92c66SSrisivasubramanian S /* 140800d92c66SSrisivasubramanian S * Save initial space that followed app data for completion code & 140900d92c66SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 141000d92c66SSrisivasubramanian S */ 141100d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 141200d92c66SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 141300d92c66SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 141400d92c66SSrisivasubramanian S (uint8_t *)m_vaddr; 141500d92c66SSrisivasubramanian S 141600d92c66SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 141700d92c66SSrisivasubramanian S c_dma = m_dma + size; 141800d92c66SSrisivasubramanian S size += sizeof(cpt_res_s_t); 141900d92c66SSrisivasubramanian S 142000d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 142100d92c66SSrisivasubramanian S m_dma += size; 142200d92c66SSrisivasubramanian S 142300d92c66SSrisivasubramanian S /* Reserve memory for cpt request info */ 142400d92c66SSrisivasubramanian S req = m_vaddr; 142500d92c66SSrisivasubramanian S 142600d92c66SSrisivasubramanian S size = sizeof(struct cpt_request_info); 142700d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 142800d92c66SSrisivasubramanian S m_dma += size; 142900d92c66SSrisivasubramanian S 143000d92c66SSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G; 143100d92c66SSrisivasubramanian S 143200d92c66SSrisivasubramanian S /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1433131966f8SAnkur Dwivedi 1434131966f8SAnkur Dwivedi opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 143500d92c66SSrisivasubramanian S (0 << 3) | (flags & 0x7)); 143600d92c66SSrisivasubramanian S 143700d92c66SSrisivasubramanian S if (flags == 0x1) { 143800d92c66SSrisivasubramanian S /* 143900d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 144000d92c66SSrisivasubramanian S * TODO: Rounding off 144100d92c66SSrisivasubramanian S */ 144200d92c66SSrisivasubramanian S auth_data_len = AUTH_DLEN(d_lens); 144300d92c66SSrisivasubramanian S 144400d92c66SSrisivasubramanian S /* EIA3 or UIA2 */ 144500d92c66SSrisivasubramanian S auth_offset = AUTH_OFFSET(d_offs); 144600d92c66SSrisivasubramanian S auth_offset = auth_offset / 8; 144700d92c66SSrisivasubramanian S 144800d92c66SSrisivasubramanian S /* consider iv len */ 144900d92c66SSrisivasubramanian S auth_offset += iv_len; 145000d92c66SSrisivasubramanian S 145100d92c66SSrisivasubramanian S inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 145200d92c66SSrisivasubramanian S outputlen = mac_len; 145300d92c66SSrisivasubramanian S 145400d92c66SSrisivasubramanian S offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset); 145500d92c66SSrisivasubramanian S 145600d92c66SSrisivasubramanian S } else { 145700d92c66SSrisivasubramanian S /* EEA3 or UEA2 */ 145800d92c66SSrisivasubramanian S /* 145900d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 146000d92c66SSrisivasubramanian S * TODO: Rounding off 146100d92c66SSrisivasubramanian S */ 146200d92c66SSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 146300d92c66SSrisivasubramanian S 146400d92c66SSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs); 146500d92c66SSrisivasubramanian S encr_offset = encr_offset / 8; 146600d92c66SSrisivasubramanian S /* consider iv len */ 146700d92c66SSrisivasubramanian S encr_offset += iv_len; 146800d92c66SSrisivasubramanian S 146900d92c66SSrisivasubramanian S inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 147000d92c66SSrisivasubramanian S outputlen = inputlen; 147100d92c66SSrisivasubramanian S 147200d92c66SSrisivasubramanian S /* iv offset is 0 */ 147300d92c66SSrisivasubramanian S offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 147400d92c66SSrisivasubramanian S } 147500d92c66SSrisivasubramanian S 147600d92c66SSrisivasubramanian S /* IV */ 147700d92c66SSrisivasubramanian S iv_s = (flags == 0x1) ? params->auth_iv_buf : 147800d92c66SSrisivasubramanian S params->iv_buf; 147900d92c66SSrisivasubramanian S 148000d92c66SSrisivasubramanian S if (snow3g) { 148100d92c66SSrisivasubramanian S /* 148200d92c66SSrisivasubramanian S * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 148300d92c66SSrisivasubramanian S * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 148400d92c66SSrisivasubramanian S */ 148500d92c66SSrisivasubramanian S 148600d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 148700d92c66SSrisivasubramanian S iv[j] = iv_s[3 - j]; 148800d92c66SSrisivasubramanian S } else { 148900d92c66SSrisivasubramanian S /* ZUC doesn't need a swap */ 149000d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 149100d92c66SSrisivasubramanian S iv[j] = iv_s[j]; 149200d92c66SSrisivasubramanian S } 149300d92c66SSrisivasubramanian S 149400d92c66SSrisivasubramanian S /* 149500d92c66SSrisivasubramanian S * GP op header, lengths are expected in bits. 149600d92c66SSrisivasubramanian S */ 149700d92c66SSrisivasubramanian S vq_cmd_w0.u64 = 0; 1498426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 1499426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 150000d92c66SSrisivasubramanian S 150100d92c66SSrisivasubramanian S /* 150200d92c66SSrisivasubramanian S * In 83XX since we have a limitation of 150300d92c66SSrisivasubramanian S * IV & Offset control word not part of instruction 150400d92c66SSrisivasubramanian S * and need to be part of Data Buffer, we check if 150500d92c66SSrisivasubramanian S * head room is there and then only do the Direct mode processing 150600d92c66SSrisivasubramanian S */ 150700d92c66SSrisivasubramanian S if (likely((req_flags & SINGLE_BUF_INPLACE) && 150800d92c66SSrisivasubramanian S (req_flags & SINGLE_BUF_HEADTAILROOM))) { 150900d92c66SSrisivasubramanian S void *dm_vaddr = params->bufs[0].vaddr; 151000d92c66SSrisivasubramanian S uint64_t dm_dma_addr = params->bufs[0].dma_addr; 151100d92c66SSrisivasubramanian S /* 151200d92c66SSrisivasubramanian S * This flag indicates that there is 24 bytes head room and 151300d92c66SSrisivasubramanian S * 8 bytes tail room available, so that we get to do 151400d92c66SSrisivasubramanian S * DIRECT MODE with limitation 151500d92c66SSrisivasubramanian S */ 151600d92c66SSrisivasubramanian S 151700d92c66SSrisivasubramanian S offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 151800d92c66SSrisivasubramanian S OFF_CTRL_LEN - iv_len); 151900d92c66SSrisivasubramanian S offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 152000d92c66SSrisivasubramanian S 152100d92c66SSrisivasubramanian S /* DPTR */ 152200d92c66SSrisivasubramanian S req->ist.ei1 = offset_dma; 152300d92c66SSrisivasubramanian S /* RPTR should just exclude offset control word */ 152400d92c66SSrisivasubramanian S req->ist.ei2 = dm_dma_addr - iv_len; 152500d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 152600d92c66SSrisivasubramanian S + outputlen - iv_len); 152700d92c66SSrisivasubramanian S 1528426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 152900d92c66SSrisivasubramanian S 1530426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 153100d92c66SSrisivasubramanian S 153200d92c66SSrisivasubramanian S if (likely(iv_len)) { 153300d92c66SSrisivasubramanian S uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 153400d92c66SSrisivasubramanian S + OFF_CTRL_LEN); 153500d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 153600d92c66SSrisivasubramanian S } 153700d92c66SSrisivasubramanian S 153800d92c66SSrisivasubramanian S *offset_vaddr = offset_ctrl; 153900d92c66SSrisivasubramanian S } else { 154000d92c66SSrisivasubramanian S uint32_t i, g_size_bytes, s_size_bytes; 154100d92c66SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 154200d92c66SSrisivasubramanian S sg_comp_t *gather_comp; 154300d92c66SSrisivasubramanian S sg_comp_t *scatter_comp; 154400d92c66SSrisivasubramanian S uint8_t *in_buffer; 154500d92c66SSrisivasubramanian S uint32_t *iv_d; 154600d92c66SSrisivasubramanian S 154700d92c66SSrisivasubramanian S /* save space for iv */ 154800d92c66SSrisivasubramanian S offset_vaddr = m_vaddr; 154900d92c66SSrisivasubramanian S offset_dma = m_dma; 155000d92c66SSrisivasubramanian S 155100d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 155200d92c66SSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 155300d92c66SSrisivasubramanian S 155400d92c66SSrisivasubramanian S opcode.s.major |= CPT_DMA_MODE; 155500d92c66SSrisivasubramanian S 1556426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 155700d92c66SSrisivasubramanian S 155800d92c66SSrisivasubramanian S /* DPTR has SG list */ 155900d92c66SSrisivasubramanian S in_buffer = m_vaddr; 156000d92c66SSrisivasubramanian S dptr_dma = m_dma; 156100d92c66SSrisivasubramanian S 156200d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 156300d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 156400d92c66SSrisivasubramanian S 156500d92c66SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 156600d92c66SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 156700d92c66SSrisivasubramanian S 156800d92c66SSrisivasubramanian S /* 156900d92c66SSrisivasubramanian S * Input Gather List 157000d92c66SSrisivasubramanian S */ 157100d92c66SSrisivasubramanian S i = 0; 157200d92c66SSrisivasubramanian S 157300d92c66SSrisivasubramanian S /* Offset control word followed by iv */ 157400d92c66SSrisivasubramanian S 157500d92c66SSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, 157600d92c66SSrisivasubramanian S OFF_CTRL_LEN + iv_len); 157700d92c66SSrisivasubramanian S 157800d92c66SSrisivasubramanian S /* iv offset is 0 */ 157900d92c66SSrisivasubramanian S *offset_vaddr = offset_ctrl; 158000d92c66SSrisivasubramanian S 158100d92c66SSrisivasubramanian S iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 158200d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 158300d92c66SSrisivasubramanian S 158400d92c66SSrisivasubramanian S /* input data */ 158500d92c66SSrisivasubramanian S size = inputlen - iv_len; 158600d92c66SSrisivasubramanian S if (size) { 158700d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 158800d92c66SSrisivasubramanian S params->src_iov, 158900d92c66SSrisivasubramanian S 0, &size, NULL, 0); 1590f39928e6SAnoob Joseph if (unlikely(size)) { 1591f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1592f39928e6SAnoob Joseph " size %d needed", size); 1593f39928e6SAnoob Joseph return; 1594f39928e6SAnoob Joseph } 159500d92c66SSrisivasubramanian S } 159600d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 159700d92c66SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 159800d92c66SSrisivasubramanian S 159900d92c66SSrisivasubramanian S /* 160000d92c66SSrisivasubramanian S * Output Scatter List 160100d92c66SSrisivasubramanian S */ 160200d92c66SSrisivasubramanian S 160300d92c66SSrisivasubramanian S i = 0; 160400d92c66SSrisivasubramanian S scatter_comp = 160500d92c66SSrisivasubramanian S (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 160600d92c66SSrisivasubramanian S 160700d92c66SSrisivasubramanian S if (flags == 0x1) { 160800d92c66SSrisivasubramanian S /* IV in SLIST only for EEA3 & UEA2 */ 160900d92c66SSrisivasubramanian S iv_len = 0; 161000d92c66SSrisivasubramanian S } 161100d92c66SSrisivasubramanian S 161200d92c66SSrisivasubramanian S if (iv_len) { 161300d92c66SSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 161400d92c66SSrisivasubramanian S offset_dma + OFF_CTRL_LEN, iv_len); 161500d92c66SSrisivasubramanian S } 161600d92c66SSrisivasubramanian S 161700d92c66SSrisivasubramanian S /* Add output data */ 161800d92c66SSrisivasubramanian S if (req_flags & VALID_MAC_BUF) { 161900d92c66SSrisivasubramanian S size = outputlen - iv_len - mac_len; 162000d92c66SSrisivasubramanian S if (size) { 162100d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 162200d92c66SSrisivasubramanian S params->dst_iov, 0, 162300d92c66SSrisivasubramanian S &size, NULL, 0); 162400d92c66SSrisivasubramanian S 1625f39928e6SAnoob Joseph if (unlikely(size)) { 1626f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1627f39928e6SAnoob Joseph " size %d needed", size); 1628f39928e6SAnoob Joseph return; 1629f39928e6SAnoob Joseph } 163000d92c66SSrisivasubramanian S } 163100d92c66SSrisivasubramanian S 163200d92c66SSrisivasubramanian S /* mac data */ 163300d92c66SSrisivasubramanian S if (mac_len) { 163400d92c66SSrisivasubramanian S i = fill_sg_comp_from_buf(scatter_comp, i, 163500d92c66SSrisivasubramanian S ¶ms->mac_buf); 163600d92c66SSrisivasubramanian S } 163700d92c66SSrisivasubramanian S } else { 163800d92c66SSrisivasubramanian S /* Output including mac */ 163900d92c66SSrisivasubramanian S size = outputlen - iv_len; 164000d92c66SSrisivasubramanian S if (size) { 164100d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 164200d92c66SSrisivasubramanian S params->dst_iov, 0, 164300d92c66SSrisivasubramanian S &size, NULL, 0); 164400d92c66SSrisivasubramanian S 1645f39928e6SAnoob Joseph if (unlikely(size)) { 1646f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1647f39928e6SAnoob Joseph " size %d needed", size); 1648f39928e6SAnoob Joseph return; 1649f39928e6SAnoob Joseph } 165000d92c66SSrisivasubramanian S } 165100d92c66SSrisivasubramanian S } 165200d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 165300d92c66SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 165400d92c66SSrisivasubramanian S 165500d92c66SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 165600d92c66SSrisivasubramanian S 165700d92c66SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 1658426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 165900d92c66SSrisivasubramanian S 166000d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 166100d92c66SSrisivasubramanian S m_dma += size; 166200d92c66SSrisivasubramanian S 166300d92c66SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 166400d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 166500d92c66SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 166600d92c66SSrisivasubramanian S rptr_dma = c_dma - 8; 166700d92c66SSrisivasubramanian S 166800d92c66SSrisivasubramanian S req->ist.ei1 = dptr_dma; 166900d92c66SSrisivasubramanian S req->ist.ei2 = rptr_dma; 167000d92c66SSrisivasubramanian S } 167100d92c66SSrisivasubramanian S 167200d92c66SSrisivasubramanian S /* vq command w3 */ 167300d92c66SSrisivasubramanian S vq_cmd_w3.u64 = 0; 167400d92c66SSrisivasubramanian S vq_cmd_w3.s.grp = 0; 167500d92c66SSrisivasubramanian S vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 167600d92c66SSrisivasubramanian S offsetof(struct cpt_ctx, zs_ctx); 167700d92c66SSrisivasubramanian S 167800d92c66SSrisivasubramanian S /* 16 byte aligned cpt res address */ 167900d92c66SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 168000d92c66SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 168100d92c66SSrisivasubramanian S req->comp_baddr = c_dma; 168200d92c66SSrisivasubramanian S 168300d92c66SSrisivasubramanian S /* Fill microcode part of instruction */ 168400d92c66SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 168500d92c66SSrisivasubramanian S req->ist.ei3 = vq_cmd_w3.u64; 168600d92c66SSrisivasubramanian S 168700d92c66SSrisivasubramanian S req->op = op; 168800d92c66SSrisivasubramanian S 168900d92c66SSrisivasubramanian S *prep_req = req; 1690f39928e6SAnoob Joseph return; 169100d92c66SSrisivasubramanian S } 169200d92c66SSrisivasubramanian S 1693f39928e6SAnoob Joseph static __rte_always_inline void 169400d92c66SSrisivasubramanian S cpt_zuc_snow3g_dec_prep(uint32_t req_flags, 169500d92c66SSrisivasubramanian S uint64_t d_offs, 169600d92c66SSrisivasubramanian S uint64_t d_lens, 169700d92c66SSrisivasubramanian S fc_params_t *params, 169800d92c66SSrisivasubramanian S void *op, 169900d92c66SSrisivasubramanian S void **prep_req) 170000d92c66SSrisivasubramanian S { 170100d92c66SSrisivasubramanian S uint32_t size; 170200d92c66SSrisivasubramanian S int32_t inputlen = 0, outputlen; 170300d92c66SSrisivasubramanian S struct cpt_ctx *cpt_ctx; 170400d92c66SSrisivasubramanian S uint8_t snow3g, iv_len = 16; 170500d92c66SSrisivasubramanian S struct cpt_request_info *req; 170600d92c66SSrisivasubramanian S buf_ptr_t *buf_p; 170700d92c66SSrisivasubramanian S uint32_t encr_offset; 170800d92c66SSrisivasubramanian S uint32_t encr_data_len; 17098de5ede7SAnoob Joseph int flags; 171000d92c66SSrisivasubramanian S void *m_vaddr, *c_vaddr; 171100d92c66SSrisivasubramanian S uint64_t m_dma, c_dma; 171200d92c66SSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 171300d92c66SSrisivasubramanian S uint32_t *iv_s, iv[4], j; 171400d92c66SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 171500d92c66SSrisivasubramanian S vq_cmd_word3_t vq_cmd_w3; 171600d92c66SSrisivasubramanian S opcode_info_t opcode; 171700d92c66SSrisivasubramanian S 171800d92c66SSrisivasubramanian S buf_p = ¶ms->meta_buf; 171900d92c66SSrisivasubramanian S m_vaddr = buf_p->vaddr; 172000d92c66SSrisivasubramanian S m_dma = buf_p->dma_addr; 172100d92c66SSrisivasubramanian S 172200d92c66SSrisivasubramanian S /* 172300d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 172400d92c66SSrisivasubramanian S * TODO: Rounding off 172500d92c66SSrisivasubramanian S */ 172600d92c66SSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 172700d92c66SSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 172800d92c66SSrisivasubramanian S 172900d92c66SSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 173000d92c66SSrisivasubramanian S flags = cpt_ctx->zsk_flags; 173100d92c66SSrisivasubramanian S snow3g = cpt_ctx->snow3g; 173200d92c66SSrisivasubramanian S /* 173300d92c66SSrisivasubramanian S * Save initial space that followed app data for completion code & 173400d92c66SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 173500d92c66SSrisivasubramanian S */ 173600d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 173700d92c66SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 173800d92c66SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 173900d92c66SSrisivasubramanian S (uint8_t *)m_vaddr; 174000d92c66SSrisivasubramanian S 174100d92c66SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 174200d92c66SSrisivasubramanian S c_dma = m_dma + size; 174300d92c66SSrisivasubramanian S size += sizeof(cpt_res_s_t); 174400d92c66SSrisivasubramanian S 174500d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 174600d92c66SSrisivasubramanian S m_dma += size; 174700d92c66SSrisivasubramanian S 174800d92c66SSrisivasubramanian S /* Reserve memory for cpt request info */ 174900d92c66SSrisivasubramanian S req = m_vaddr; 175000d92c66SSrisivasubramanian S 175100d92c66SSrisivasubramanian S size = sizeof(struct cpt_request_info); 175200d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 175300d92c66SSrisivasubramanian S m_dma += size; 175400d92c66SSrisivasubramanian S 175500d92c66SSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G; 175600d92c66SSrisivasubramanian S 175700d92c66SSrisivasubramanian S /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1758131966f8SAnkur Dwivedi 1759131966f8SAnkur Dwivedi opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 176000d92c66SSrisivasubramanian S (0 << 3) | (flags & 0x7)); 176100d92c66SSrisivasubramanian S 176200d92c66SSrisivasubramanian S /* consider iv len */ 176300d92c66SSrisivasubramanian S encr_offset += iv_len; 176400d92c66SSrisivasubramanian S 176500d92c66SSrisivasubramanian S inputlen = encr_offset + 176600d92c66SSrisivasubramanian S (RTE_ALIGN(encr_data_len, 8) / 8); 176700d92c66SSrisivasubramanian S outputlen = inputlen; 176800d92c66SSrisivasubramanian S 176900d92c66SSrisivasubramanian S /* IV */ 177000d92c66SSrisivasubramanian S iv_s = params->iv_buf; 177100d92c66SSrisivasubramanian S if (snow3g) { 177200d92c66SSrisivasubramanian S /* 177300d92c66SSrisivasubramanian S * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 177400d92c66SSrisivasubramanian S * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 177500d92c66SSrisivasubramanian S */ 177600d92c66SSrisivasubramanian S 177700d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 177800d92c66SSrisivasubramanian S iv[j] = iv_s[3 - j]; 177900d92c66SSrisivasubramanian S } else { 178000d92c66SSrisivasubramanian S /* ZUC doesn't need a swap */ 178100d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 178200d92c66SSrisivasubramanian S iv[j] = iv_s[j]; 178300d92c66SSrisivasubramanian S } 178400d92c66SSrisivasubramanian S 178500d92c66SSrisivasubramanian S /* 178600d92c66SSrisivasubramanian S * GP op header, lengths are expected in bits. 178700d92c66SSrisivasubramanian S */ 178800d92c66SSrisivasubramanian S vq_cmd_w0.u64 = 0; 1789426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 179000d92c66SSrisivasubramanian S 179100d92c66SSrisivasubramanian S /* 179200d92c66SSrisivasubramanian S * In 83XX since we have a limitation of 179300d92c66SSrisivasubramanian S * IV & Offset control word not part of instruction 179400d92c66SSrisivasubramanian S * and need to be part of Data Buffer, we check if 179500d92c66SSrisivasubramanian S * head room is there and then only do the Direct mode processing 179600d92c66SSrisivasubramanian S */ 179700d92c66SSrisivasubramanian S if (likely((req_flags & SINGLE_BUF_INPLACE) && 179800d92c66SSrisivasubramanian S (req_flags & SINGLE_BUF_HEADTAILROOM))) { 179900d92c66SSrisivasubramanian S void *dm_vaddr = params->bufs[0].vaddr; 180000d92c66SSrisivasubramanian S uint64_t dm_dma_addr = params->bufs[0].dma_addr; 180100d92c66SSrisivasubramanian S /* 180200d92c66SSrisivasubramanian S * This flag indicates that there is 24 bytes head room and 180300d92c66SSrisivasubramanian S * 8 bytes tail room available, so that we get to do 180400d92c66SSrisivasubramanian S * DIRECT MODE with limitation 180500d92c66SSrisivasubramanian S */ 180600d92c66SSrisivasubramanian S 180700d92c66SSrisivasubramanian S offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 180800d92c66SSrisivasubramanian S OFF_CTRL_LEN - iv_len); 180900d92c66SSrisivasubramanian S offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 181000d92c66SSrisivasubramanian S 181100d92c66SSrisivasubramanian S /* DPTR */ 181200d92c66SSrisivasubramanian S req->ist.ei1 = offset_dma; 181300d92c66SSrisivasubramanian S /* RPTR should just exclude offset control word */ 181400d92c66SSrisivasubramanian S req->ist.ei2 = dm_dma_addr - iv_len; 181500d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 181600d92c66SSrisivasubramanian S + outputlen - iv_len); 181700d92c66SSrisivasubramanian S 1818426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 181900d92c66SSrisivasubramanian S 1820426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 182100d92c66SSrisivasubramanian S 182200d92c66SSrisivasubramanian S if (likely(iv_len)) { 182300d92c66SSrisivasubramanian S uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 182400d92c66SSrisivasubramanian S + OFF_CTRL_LEN); 182500d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 182600d92c66SSrisivasubramanian S } 182700d92c66SSrisivasubramanian S 182800d92c66SSrisivasubramanian S /* iv offset is 0 */ 182900d92c66SSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 183000d92c66SSrisivasubramanian S } else { 183100d92c66SSrisivasubramanian S uint32_t i, g_size_bytes, s_size_bytes; 183200d92c66SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 183300d92c66SSrisivasubramanian S sg_comp_t *gather_comp; 183400d92c66SSrisivasubramanian S sg_comp_t *scatter_comp; 183500d92c66SSrisivasubramanian S uint8_t *in_buffer; 183600d92c66SSrisivasubramanian S uint32_t *iv_d; 183700d92c66SSrisivasubramanian S 183800d92c66SSrisivasubramanian S /* save space for offset and iv... */ 183900d92c66SSrisivasubramanian S offset_vaddr = m_vaddr; 184000d92c66SSrisivasubramanian S offset_dma = m_dma; 184100d92c66SSrisivasubramanian S 184200d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 184300d92c66SSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 184400d92c66SSrisivasubramanian S 184500d92c66SSrisivasubramanian S opcode.s.major |= CPT_DMA_MODE; 184600d92c66SSrisivasubramanian S 1847426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 184800d92c66SSrisivasubramanian S 184900d92c66SSrisivasubramanian S /* DPTR has SG list */ 185000d92c66SSrisivasubramanian S in_buffer = m_vaddr; 185100d92c66SSrisivasubramanian S dptr_dma = m_dma; 185200d92c66SSrisivasubramanian S 185300d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 185400d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 185500d92c66SSrisivasubramanian S 185600d92c66SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 185700d92c66SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 185800d92c66SSrisivasubramanian S 185900d92c66SSrisivasubramanian S /* 186000d92c66SSrisivasubramanian S * Input Gather List 186100d92c66SSrisivasubramanian S */ 186200d92c66SSrisivasubramanian S i = 0; 186300d92c66SSrisivasubramanian S 186400d92c66SSrisivasubramanian S /* Offset control word */ 186500d92c66SSrisivasubramanian S 186600d92c66SSrisivasubramanian S /* iv offset is 0 */ 186700d92c66SSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 186800d92c66SSrisivasubramanian S 186900d92c66SSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, 187000d92c66SSrisivasubramanian S OFF_CTRL_LEN + iv_len); 187100d92c66SSrisivasubramanian S 187200d92c66SSrisivasubramanian S iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 187300d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 187400d92c66SSrisivasubramanian S 187500d92c66SSrisivasubramanian S /* Add input data */ 187600d92c66SSrisivasubramanian S size = inputlen - iv_len; 187700d92c66SSrisivasubramanian S if (size) { 187800d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 187900d92c66SSrisivasubramanian S params->src_iov, 188000d92c66SSrisivasubramanian S 0, &size, NULL, 0); 1881f39928e6SAnoob Joseph if (unlikely(size)) { 1882f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1883f39928e6SAnoob Joseph " size %d needed", size); 1884f39928e6SAnoob Joseph return; 1885f39928e6SAnoob Joseph } 188600d92c66SSrisivasubramanian S } 188700d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 188800d92c66SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 188900d92c66SSrisivasubramanian S 189000d92c66SSrisivasubramanian S /* 189100d92c66SSrisivasubramanian S * Output Scatter List 189200d92c66SSrisivasubramanian S */ 189300d92c66SSrisivasubramanian S 189400d92c66SSrisivasubramanian S i = 0; 189500d92c66SSrisivasubramanian S scatter_comp = 189600d92c66SSrisivasubramanian S (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 189700d92c66SSrisivasubramanian S 189800d92c66SSrisivasubramanian S /* IV */ 189900d92c66SSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 190000d92c66SSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 190100d92c66SSrisivasubramanian S iv_len); 190200d92c66SSrisivasubramanian S 190300d92c66SSrisivasubramanian S /* Add output data */ 190400d92c66SSrisivasubramanian S size = outputlen - iv_len; 190500d92c66SSrisivasubramanian S if (size) { 190600d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 190700d92c66SSrisivasubramanian S params->dst_iov, 0, 190800d92c66SSrisivasubramanian S &size, NULL, 0); 190900d92c66SSrisivasubramanian S 1910f39928e6SAnoob Joseph if (unlikely(size)) { 1911f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1912f39928e6SAnoob Joseph " size %d needed", size); 1913f39928e6SAnoob Joseph return; 1914f39928e6SAnoob Joseph } 191500d92c66SSrisivasubramanian S } 191600d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 191700d92c66SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 191800d92c66SSrisivasubramanian S 191900d92c66SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 192000d92c66SSrisivasubramanian S 192100d92c66SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 1922426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 192300d92c66SSrisivasubramanian S 192400d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 192500d92c66SSrisivasubramanian S m_dma += size; 192600d92c66SSrisivasubramanian S 192700d92c66SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 192800d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 192900d92c66SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 193000d92c66SSrisivasubramanian S rptr_dma = c_dma - 8; 193100d92c66SSrisivasubramanian S 193200d92c66SSrisivasubramanian S req->ist.ei1 = dptr_dma; 193300d92c66SSrisivasubramanian S req->ist.ei2 = rptr_dma; 193400d92c66SSrisivasubramanian S } 193500d92c66SSrisivasubramanian S 193600d92c66SSrisivasubramanian S /* vq command w3 */ 193700d92c66SSrisivasubramanian S vq_cmd_w3.u64 = 0; 193800d92c66SSrisivasubramanian S vq_cmd_w3.s.grp = 0; 193900d92c66SSrisivasubramanian S vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 194000d92c66SSrisivasubramanian S offsetof(struct cpt_ctx, zs_ctx); 194100d92c66SSrisivasubramanian S 194200d92c66SSrisivasubramanian S /* 16 byte aligned cpt res address */ 194300d92c66SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 194400d92c66SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 194500d92c66SSrisivasubramanian S req->comp_baddr = c_dma; 194600d92c66SSrisivasubramanian S 194700d92c66SSrisivasubramanian S /* Fill microcode part of instruction */ 194800d92c66SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 194900d92c66SSrisivasubramanian S req->ist.ei3 = vq_cmd_w3.u64; 195000d92c66SSrisivasubramanian S 195100d92c66SSrisivasubramanian S req->op = op; 195200d92c66SSrisivasubramanian S 195300d92c66SSrisivasubramanian S *prep_req = req; 1954f39928e6SAnoob Joseph return; 195500d92c66SSrisivasubramanian S } 195600d92c66SSrisivasubramanian S 1957f39928e6SAnoob Joseph static __rte_always_inline void 1958da39e3ecSSrisivasubramanian S cpt_kasumi_enc_prep(uint32_t req_flags, 1959da39e3ecSSrisivasubramanian S uint64_t d_offs, 1960da39e3ecSSrisivasubramanian S uint64_t d_lens, 1961da39e3ecSSrisivasubramanian S fc_params_t *params, 1962da39e3ecSSrisivasubramanian S void *op, 1963da39e3ecSSrisivasubramanian S void **prep_req) 1964da39e3ecSSrisivasubramanian S { 1965da39e3ecSSrisivasubramanian S uint32_t size; 1966da39e3ecSSrisivasubramanian S int32_t inputlen = 0, outputlen = 0; 1967da39e3ecSSrisivasubramanian S struct cpt_ctx *cpt_ctx; 1968da39e3ecSSrisivasubramanian S uint32_t mac_len = 0; 1969da39e3ecSSrisivasubramanian S uint8_t i = 0; 1970da39e3ecSSrisivasubramanian S struct cpt_request_info *req; 1971da39e3ecSSrisivasubramanian S buf_ptr_t *buf_p; 1972da39e3ecSSrisivasubramanian S uint32_t encr_offset, auth_offset; 1973da39e3ecSSrisivasubramanian S uint32_t encr_data_len, auth_data_len; 19748de5ede7SAnoob Joseph int flags; 1975da39e3ecSSrisivasubramanian S uint8_t *iv_s, *iv_d, iv_len = 8; 1976da39e3ecSSrisivasubramanian S uint8_t dir = 0; 1977da39e3ecSSrisivasubramanian S void *m_vaddr, *c_vaddr; 1978da39e3ecSSrisivasubramanian S uint64_t m_dma, c_dma; 1979da39e3ecSSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 1980da39e3ecSSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 1981da39e3ecSSrisivasubramanian S vq_cmd_word3_t vq_cmd_w3; 1982da39e3ecSSrisivasubramanian S opcode_info_t opcode; 1983da39e3ecSSrisivasubramanian S uint8_t *in_buffer; 1984da39e3ecSSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 1985da39e3ecSSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 1986da39e3ecSSrisivasubramanian S sg_comp_t *gather_comp; 1987da39e3ecSSrisivasubramanian S sg_comp_t *scatter_comp; 1988da39e3ecSSrisivasubramanian S 1989da39e3ecSSrisivasubramanian S buf_p = ¶ms->meta_buf; 1990da39e3ecSSrisivasubramanian S m_vaddr = buf_p->vaddr; 1991da39e3ecSSrisivasubramanian S m_dma = buf_p->dma_addr; 1992da39e3ecSSrisivasubramanian S 1993da39e3ecSSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 1994da39e3ecSSrisivasubramanian S auth_offset = AUTH_OFFSET(d_offs) / 8; 1995da39e3ecSSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 1996da39e3ecSSrisivasubramanian S auth_data_len = AUTH_DLEN(d_lens); 1997da39e3ecSSrisivasubramanian S 1998da39e3ecSSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 1999da39e3ecSSrisivasubramanian S flags = cpt_ctx->zsk_flags; 2000da39e3ecSSrisivasubramanian S mac_len = cpt_ctx->mac_len; 2001da39e3ecSSrisivasubramanian S 2002da39e3ecSSrisivasubramanian S if (flags == 0x0) 2003da39e3ecSSrisivasubramanian S iv_s = params->iv_buf; 2004da39e3ecSSrisivasubramanian S else 2005da39e3ecSSrisivasubramanian S iv_s = params->auth_iv_buf; 2006da39e3ecSSrisivasubramanian S 2007da39e3ecSSrisivasubramanian S dir = iv_s[8] & 0x1; 2008da39e3ecSSrisivasubramanian S 2009da39e3ecSSrisivasubramanian S /* 2010da39e3ecSSrisivasubramanian S * Save initial space that followed app data for completion code & 2011da39e3ecSSrisivasubramanian S * alternate completion code to fall in same cache line as app data 2012da39e3ecSSrisivasubramanian S */ 2013da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2014da39e3ecSSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 2015da39e3ecSSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2016da39e3ecSSrisivasubramanian S (uint8_t *)m_vaddr; 2017da39e3ecSSrisivasubramanian S 2018da39e3ecSSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 2019da39e3ecSSrisivasubramanian S c_dma = m_dma + size; 2020da39e3ecSSrisivasubramanian S size += sizeof(cpt_res_s_t); 2021da39e3ecSSrisivasubramanian S 2022da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2023da39e3ecSSrisivasubramanian S m_dma += size; 2024da39e3ecSSrisivasubramanian S 2025da39e3ecSSrisivasubramanian S /* Reserve memory for cpt request info */ 2026da39e3ecSSrisivasubramanian S req = m_vaddr; 2027da39e3ecSSrisivasubramanian S 2028da39e3ecSSrisivasubramanian S size = sizeof(struct cpt_request_info); 2029da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2030da39e3ecSSrisivasubramanian S m_dma += size; 2031da39e3ecSSrisivasubramanian S 2032da39e3ecSSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2033da39e3ecSSrisivasubramanian S 2034da39e3ecSSrisivasubramanian S /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2035da39e3ecSSrisivasubramanian S opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2036da39e3ecSSrisivasubramanian S (dir << 4) | (0 << 3) | (flags & 0x7)); 2037da39e3ecSSrisivasubramanian S 2038da39e3ecSSrisivasubramanian S /* 2039da39e3ecSSrisivasubramanian S * GP op header, lengths are expected in bits. 2040da39e3ecSSrisivasubramanian S */ 2041da39e3ecSSrisivasubramanian S vq_cmd_w0.u64 = 0; 2042426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 2043426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 2044426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 2045da39e3ecSSrisivasubramanian S 2046da39e3ecSSrisivasubramanian S /* consider iv len */ 2047da39e3ecSSrisivasubramanian S if (flags == 0x0) { 2048da39e3ecSSrisivasubramanian S encr_offset += iv_len; 2049da39e3ecSSrisivasubramanian S auth_offset += iv_len; 2050da39e3ecSSrisivasubramanian S } 2051da39e3ecSSrisivasubramanian S 2052da39e3ecSSrisivasubramanian S /* save space for offset ctrl and iv */ 2053da39e3ecSSrisivasubramanian S offset_vaddr = m_vaddr; 2054da39e3ecSSrisivasubramanian S offset_dma = m_dma; 2055da39e3ecSSrisivasubramanian S 2056da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2057da39e3ecSSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 2058da39e3ecSSrisivasubramanian S 2059da39e3ecSSrisivasubramanian S /* DPTR has SG list */ 2060da39e3ecSSrisivasubramanian S in_buffer = m_vaddr; 2061da39e3ecSSrisivasubramanian S dptr_dma = m_dma; 2062da39e3ecSSrisivasubramanian S 2063da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 2064da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 2065da39e3ecSSrisivasubramanian S 2066da39e3ecSSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 2067da39e3ecSSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2068da39e3ecSSrisivasubramanian S 2069da39e3ecSSrisivasubramanian S /* 2070da39e3ecSSrisivasubramanian S * Input Gather List 2071da39e3ecSSrisivasubramanian S */ 2072da39e3ecSSrisivasubramanian S i = 0; 2073da39e3ecSSrisivasubramanian S 2074da39e3ecSSrisivasubramanian S /* Offset control word followed by iv */ 2075da39e3ecSSrisivasubramanian S 2076da39e3ecSSrisivasubramanian S if (flags == 0x0) { 2077da39e3ecSSrisivasubramanian S inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 2078da39e3ecSSrisivasubramanian S outputlen = inputlen; 2079da39e3ecSSrisivasubramanian S /* iv offset is 0 */ 2080da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 2081da39e3ecSSrisivasubramanian S } else { 2082da39e3ecSSrisivasubramanian S inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 2083da39e3ecSSrisivasubramanian S outputlen = mac_len; 2084da39e3ecSSrisivasubramanian S /* iv offset is 0 */ 2085da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)auth_offset); 2086da39e3ecSSrisivasubramanian S } 2087da39e3ecSSrisivasubramanian S 2088da39e3ecSSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2089da39e3ecSSrisivasubramanian S 2090da39e3ecSSrisivasubramanian S /* IV */ 2091da39e3ecSSrisivasubramanian S iv_d = (uint8_t *)offset_vaddr + OFF_CTRL_LEN; 2092da39e3ecSSrisivasubramanian S memcpy(iv_d, iv_s, iv_len); 2093da39e3ecSSrisivasubramanian S 2094da39e3ecSSrisivasubramanian S /* input data */ 2095da39e3ecSSrisivasubramanian S size = inputlen - iv_len; 2096da39e3ecSSrisivasubramanian S if (size) { 2097da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 2098da39e3ecSSrisivasubramanian S params->src_iov, 0, 2099da39e3ecSSrisivasubramanian S &size, NULL, 0); 2100da39e3ecSSrisivasubramanian S 2101f39928e6SAnoob Joseph if (unlikely(size)) { 2102f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2103f39928e6SAnoob Joseph " size %d needed", size); 2104f39928e6SAnoob Joseph return; 2105f39928e6SAnoob Joseph } 2106da39e3ecSSrisivasubramanian S } 2107da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2108da39e3ecSSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2109da39e3ecSSrisivasubramanian S 2110da39e3ecSSrisivasubramanian S /* 2111da39e3ecSSrisivasubramanian S * Output Scatter List 2112da39e3ecSSrisivasubramanian S */ 2113da39e3ecSSrisivasubramanian S 2114da39e3ecSSrisivasubramanian S i = 0; 2115da39e3ecSSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2116da39e3ecSSrisivasubramanian S 2117da39e3ecSSrisivasubramanian S if (flags == 0x1) { 2118da39e3ecSSrisivasubramanian S /* IV in SLIST only for F8 */ 2119da39e3ecSSrisivasubramanian S iv_len = 0; 2120da39e3ecSSrisivasubramanian S } 2121da39e3ecSSrisivasubramanian S 2122da39e3ecSSrisivasubramanian S /* IV */ 2123da39e3ecSSrisivasubramanian S if (iv_len) { 2124da39e3ecSSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 2125da39e3ecSSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 2126da39e3ecSSrisivasubramanian S iv_len); 2127da39e3ecSSrisivasubramanian S } 2128da39e3ecSSrisivasubramanian S 2129da39e3ecSSrisivasubramanian S /* Add output data */ 2130da39e3ecSSrisivasubramanian S if (req_flags & VALID_MAC_BUF) { 2131da39e3ecSSrisivasubramanian S size = outputlen - iv_len - mac_len; 2132da39e3ecSSrisivasubramanian S if (size) { 2133da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2134da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2135da39e3ecSSrisivasubramanian S &size, NULL, 0); 2136da39e3ecSSrisivasubramanian S 2137f39928e6SAnoob Joseph if (unlikely(size)) { 2138f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2139f39928e6SAnoob Joseph " size %d needed", size); 2140f39928e6SAnoob Joseph return; 2141f39928e6SAnoob Joseph } 2142da39e3ecSSrisivasubramanian S } 2143da39e3ecSSrisivasubramanian S 2144da39e3ecSSrisivasubramanian S /* mac data */ 2145da39e3ecSSrisivasubramanian S if (mac_len) { 2146da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_buf(scatter_comp, i, 2147da39e3ecSSrisivasubramanian S ¶ms->mac_buf); 2148da39e3ecSSrisivasubramanian S } 2149da39e3ecSSrisivasubramanian S } else { 2150da39e3ecSSrisivasubramanian S /* Output including mac */ 2151da39e3ecSSrisivasubramanian S size = outputlen - iv_len; 2152da39e3ecSSrisivasubramanian S if (size) { 2153da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2154da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2155da39e3ecSSrisivasubramanian S &size, NULL, 0); 2156da39e3ecSSrisivasubramanian S 2157f39928e6SAnoob Joseph if (unlikely(size)) { 2158f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2159f39928e6SAnoob Joseph " size %d needed", size); 2160f39928e6SAnoob Joseph return; 2161f39928e6SAnoob Joseph } 2162da39e3ecSSrisivasubramanian S } 2163da39e3ecSSrisivasubramanian S } 2164da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2165da39e3ecSSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2166da39e3ecSSrisivasubramanian S 2167da39e3ecSSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2168da39e3ecSSrisivasubramanian S 2169da39e3ecSSrisivasubramanian S /* This is DPTR len incase of SG mode */ 2170426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 2171da39e3ecSSrisivasubramanian S 2172da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2173da39e3ecSSrisivasubramanian S m_dma += size; 2174da39e3ecSSrisivasubramanian S 2175da39e3ecSSrisivasubramanian S /* cpt alternate completion address saved earlier */ 2176da39e3ecSSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2177da39e3ecSSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2178da39e3ecSSrisivasubramanian S rptr_dma = c_dma - 8; 2179da39e3ecSSrisivasubramanian S 2180da39e3ecSSrisivasubramanian S req->ist.ei1 = dptr_dma; 2181da39e3ecSSrisivasubramanian S req->ist.ei2 = rptr_dma; 2182da39e3ecSSrisivasubramanian S 2183da39e3ecSSrisivasubramanian S /* vq command w3 */ 2184da39e3ecSSrisivasubramanian S vq_cmd_w3.u64 = 0; 2185da39e3ecSSrisivasubramanian S vq_cmd_w3.s.grp = 0; 2186da39e3ecSSrisivasubramanian S vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 2187da39e3ecSSrisivasubramanian S offsetof(struct cpt_ctx, k_ctx); 2188da39e3ecSSrisivasubramanian S 2189da39e3ecSSrisivasubramanian S /* 16 byte aligned cpt res address */ 2190da39e3ecSSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2191da39e3ecSSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 2192da39e3ecSSrisivasubramanian S req->comp_baddr = c_dma; 2193da39e3ecSSrisivasubramanian S 2194da39e3ecSSrisivasubramanian S /* Fill microcode part of instruction */ 2195da39e3ecSSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 2196da39e3ecSSrisivasubramanian S req->ist.ei3 = vq_cmd_w3.u64; 2197da39e3ecSSrisivasubramanian S 2198da39e3ecSSrisivasubramanian S req->op = op; 2199da39e3ecSSrisivasubramanian S 2200da39e3ecSSrisivasubramanian S *prep_req = req; 2201f39928e6SAnoob Joseph return; 2202da39e3ecSSrisivasubramanian S } 2203da39e3ecSSrisivasubramanian S 2204f39928e6SAnoob Joseph static __rte_always_inline void 2205da39e3ecSSrisivasubramanian S cpt_kasumi_dec_prep(uint64_t d_offs, 2206da39e3ecSSrisivasubramanian S uint64_t d_lens, 2207da39e3ecSSrisivasubramanian S fc_params_t *params, 2208da39e3ecSSrisivasubramanian S void *op, 2209da39e3ecSSrisivasubramanian S void **prep_req) 2210da39e3ecSSrisivasubramanian S { 2211da39e3ecSSrisivasubramanian S uint32_t size; 2212da39e3ecSSrisivasubramanian S int32_t inputlen = 0, outputlen; 2213da39e3ecSSrisivasubramanian S struct cpt_ctx *cpt_ctx; 2214da39e3ecSSrisivasubramanian S uint8_t i = 0, iv_len = 8; 2215da39e3ecSSrisivasubramanian S struct cpt_request_info *req; 2216da39e3ecSSrisivasubramanian S buf_ptr_t *buf_p; 2217da39e3ecSSrisivasubramanian S uint32_t encr_offset; 2218da39e3ecSSrisivasubramanian S uint32_t encr_data_len; 22198de5ede7SAnoob Joseph int flags; 2220da39e3ecSSrisivasubramanian S uint8_t dir = 0; 2221da39e3ecSSrisivasubramanian S void *m_vaddr, *c_vaddr; 2222da39e3ecSSrisivasubramanian S uint64_t m_dma, c_dma; 2223da39e3ecSSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 2224da39e3ecSSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 2225da39e3ecSSrisivasubramanian S vq_cmd_word3_t vq_cmd_w3; 2226da39e3ecSSrisivasubramanian S opcode_info_t opcode; 2227da39e3ecSSrisivasubramanian S uint8_t *in_buffer; 2228da39e3ecSSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 2229da39e3ecSSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 2230da39e3ecSSrisivasubramanian S sg_comp_t *gather_comp; 2231da39e3ecSSrisivasubramanian S sg_comp_t *scatter_comp; 2232da39e3ecSSrisivasubramanian S 2233da39e3ecSSrisivasubramanian S buf_p = ¶ms->meta_buf; 2234da39e3ecSSrisivasubramanian S m_vaddr = buf_p->vaddr; 2235da39e3ecSSrisivasubramanian S m_dma = buf_p->dma_addr; 2236da39e3ecSSrisivasubramanian S 2237da39e3ecSSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 2238da39e3ecSSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 2239da39e3ecSSrisivasubramanian S 2240da39e3ecSSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 2241da39e3ecSSrisivasubramanian S flags = cpt_ctx->zsk_flags; 2242da39e3ecSSrisivasubramanian S /* 2243da39e3ecSSrisivasubramanian S * Save initial space that followed app data for completion code & 2244da39e3ecSSrisivasubramanian S * alternate completion code to fall in same cache line as app data 2245da39e3ecSSrisivasubramanian S */ 2246da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2247da39e3ecSSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 2248da39e3ecSSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2249da39e3ecSSrisivasubramanian S (uint8_t *)m_vaddr; 2250da39e3ecSSrisivasubramanian S 2251da39e3ecSSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 2252da39e3ecSSrisivasubramanian S c_dma = m_dma + size; 2253da39e3ecSSrisivasubramanian S size += sizeof(cpt_res_s_t); 2254da39e3ecSSrisivasubramanian S 2255da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2256da39e3ecSSrisivasubramanian S m_dma += size; 2257da39e3ecSSrisivasubramanian S 2258da39e3ecSSrisivasubramanian S /* Reserve memory for cpt request info */ 2259da39e3ecSSrisivasubramanian S req = m_vaddr; 2260da39e3ecSSrisivasubramanian S 2261da39e3ecSSrisivasubramanian S size = sizeof(struct cpt_request_info); 2262da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2263da39e3ecSSrisivasubramanian S m_dma += size; 2264da39e3ecSSrisivasubramanian S 2265da39e3ecSSrisivasubramanian S opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2266da39e3ecSSrisivasubramanian S 2267da39e3ecSSrisivasubramanian S /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2268da39e3ecSSrisivasubramanian S opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2269da39e3ecSSrisivasubramanian S (dir << 4) | (0 << 3) | (flags & 0x7)); 2270da39e3ecSSrisivasubramanian S 2271da39e3ecSSrisivasubramanian S /* 2272da39e3ecSSrisivasubramanian S * GP op header, lengths are expected in bits. 2273da39e3ecSSrisivasubramanian S */ 2274da39e3ecSSrisivasubramanian S vq_cmd_w0.u64 = 0; 2275426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 2276426af86bSAnoob Joseph vq_cmd_w0.s.opcode = opcode.flags; 2277da39e3ecSSrisivasubramanian S 2278da39e3ecSSrisivasubramanian S /* consider iv len */ 2279da39e3ecSSrisivasubramanian S encr_offset += iv_len; 2280da39e3ecSSrisivasubramanian S 2281da39e3ecSSrisivasubramanian S inputlen = iv_len + (RTE_ALIGN(encr_data_len, 8) / 8); 2282da39e3ecSSrisivasubramanian S outputlen = inputlen; 2283da39e3ecSSrisivasubramanian S 2284da39e3ecSSrisivasubramanian S /* save space for offset ctrl & iv */ 2285da39e3ecSSrisivasubramanian S offset_vaddr = m_vaddr; 2286da39e3ecSSrisivasubramanian S offset_dma = m_dma; 2287da39e3ecSSrisivasubramanian S 2288da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2289da39e3ecSSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 2290da39e3ecSSrisivasubramanian S 2291da39e3ecSSrisivasubramanian S /* DPTR has SG list */ 2292da39e3ecSSrisivasubramanian S in_buffer = m_vaddr; 2293da39e3ecSSrisivasubramanian S dptr_dma = m_dma; 2294da39e3ecSSrisivasubramanian S 2295da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 2296da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 2297da39e3ecSSrisivasubramanian S 2298da39e3ecSSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 2299da39e3ecSSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2300da39e3ecSSrisivasubramanian S 2301da39e3ecSSrisivasubramanian S /* 2302da39e3ecSSrisivasubramanian S * Input Gather List 2303da39e3ecSSrisivasubramanian S */ 2304da39e3ecSSrisivasubramanian S i = 0; 2305da39e3ecSSrisivasubramanian S 2306da39e3ecSSrisivasubramanian S /* Offset control word followed by iv */ 2307da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 2308da39e3ecSSrisivasubramanian S 2309da39e3ecSSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2310da39e3ecSSrisivasubramanian S 2311da39e3ecSSrisivasubramanian S /* IV */ 2312da39e3ecSSrisivasubramanian S memcpy((uint8_t *)offset_vaddr + OFF_CTRL_LEN, 2313da39e3ecSSrisivasubramanian S params->iv_buf, iv_len); 2314da39e3ecSSrisivasubramanian S 2315da39e3ecSSrisivasubramanian S /* Add input data */ 2316da39e3ecSSrisivasubramanian S size = inputlen - iv_len; 2317da39e3ecSSrisivasubramanian S if (size) { 2318da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 2319da39e3ecSSrisivasubramanian S params->src_iov, 2320da39e3ecSSrisivasubramanian S 0, &size, NULL, 0); 2321f39928e6SAnoob Joseph if (unlikely(size)) { 2322f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2323f39928e6SAnoob Joseph " size %d needed", size); 2324f39928e6SAnoob Joseph return; 2325f39928e6SAnoob Joseph } 2326da39e3ecSSrisivasubramanian S } 2327da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2328da39e3ecSSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2329da39e3ecSSrisivasubramanian S 2330da39e3ecSSrisivasubramanian S /* 2331da39e3ecSSrisivasubramanian S * Output Scatter List 2332da39e3ecSSrisivasubramanian S */ 2333da39e3ecSSrisivasubramanian S 2334da39e3ecSSrisivasubramanian S i = 0; 2335da39e3ecSSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2336da39e3ecSSrisivasubramanian S 2337da39e3ecSSrisivasubramanian S /* IV */ 2338da39e3ecSSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 2339da39e3ecSSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 2340da39e3ecSSrisivasubramanian S iv_len); 2341da39e3ecSSrisivasubramanian S 2342da39e3ecSSrisivasubramanian S /* Add output data */ 2343da39e3ecSSrisivasubramanian S size = outputlen - iv_len; 2344da39e3ecSSrisivasubramanian S if (size) { 2345da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2346da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2347da39e3ecSSrisivasubramanian S &size, NULL, 0); 2348f39928e6SAnoob Joseph if (unlikely(size)) { 2349f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2350f39928e6SAnoob Joseph " size %d needed", size); 2351f39928e6SAnoob Joseph return; 2352f39928e6SAnoob Joseph } 2353da39e3ecSSrisivasubramanian S } 2354da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2355da39e3ecSSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2356da39e3ecSSrisivasubramanian S 2357da39e3ecSSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2358da39e3ecSSrisivasubramanian S 2359da39e3ecSSrisivasubramanian S /* This is DPTR len incase of SG mode */ 2360426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 2361da39e3ecSSrisivasubramanian S 2362da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2363da39e3ecSSrisivasubramanian S m_dma += size; 2364da39e3ecSSrisivasubramanian S 2365da39e3ecSSrisivasubramanian S /* cpt alternate completion address saved earlier */ 2366da39e3ecSSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2367da39e3ecSSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2368da39e3ecSSrisivasubramanian S rptr_dma = c_dma - 8; 2369da39e3ecSSrisivasubramanian S 2370da39e3ecSSrisivasubramanian S req->ist.ei1 = dptr_dma; 2371da39e3ecSSrisivasubramanian S req->ist.ei2 = rptr_dma; 2372da39e3ecSSrisivasubramanian S 2373da39e3ecSSrisivasubramanian S /* vq command w3 */ 2374da39e3ecSSrisivasubramanian S vq_cmd_w3.u64 = 0; 2375da39e3ecSSrisivasubramanian S vq_cmd_w3.s.grp = 0; 2376da39e3ecSSrisivasubramanian S vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 2377da39e3ecSSrisivasubramanian S offsetof(struct cpt_ctx, k_ctx); 2378da39e3ecSSrisivasubramanian S 2379da39e3ecSSrisivasubramanian S /* 16 byte aligned cpt res address */ 2380da39e3ecSSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2381da39e3ecSSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 2382da39e3ecSSrisivasubramanian S req->comp_baddr = c_dma; 2383da39e3ecSSrisivasubramanian S 2384da39e3ecSSrisivasubramanian S /* Fill microcode part of instruction */ 2385da39e3ecSSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 2386da39e3ecSSrisivasubramanian S req->ist.ei3 = vq_cmd_w3.u64; 2387da39e3ecSSrisivasubramanian S 2388da39e3ecSSrisivasubramanian S req->op = op; 2389da39e3ecSSrisivasubramanian S 2390da39e3ecSSrisivasubramanian S *prep_req = req; 2391f39928e6SAnoob Joseph return; 2392da39e3ecSSrisivasubramanian S } 2393da39e3ecSSrisivasubramanian S 2394177b41ceSRagothaman Jayaraman static __rte_always_inline void * 2395177b41ceSRagothaman Jayaraman cpt_fc_dec_hmac_prep(uint32_t flags, 2396177b41ceSRagothaman Jayaraman uint64_t d_offs, 2397177b41ceSRagothaman Jayaraman uint64_t d_lens, 2398177b41ceSRagothaman Jayaraman fc_params_t *fc_params, 2399f39928e6SAnoob Joseph void *op) 2400177b41ceSRagothaman Jayaraman { 2401177b41ceSRagothaman Jayaraman struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2402177b41ceSRagothaman Jayaraman uint8_t fc_type; 2403177b41ceSRagothaman Jayaraman void *prep_req = NULL; 2404177b41ceSRagothaman Jayaraman 2405177b41ceSRagothaman Jayaraman fc_type = ctx->fc_type; 2406177b41ceSRagothaman Jayaraman 2407177b41ceSRagothaman Jayaraman if (likely(fc_type == FC_GEN)) { 2408f39928e6SAnoob Joseph cpt_dec_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2409da39e3ecSSrisivasubramanian S &prep_req); 2410f39928e6SAnoob Joseph } else if (fc_type == ZUC_SNOW3G) { 2411f39928e6SAnoob Joseph cpt_zuc_snow3g_dec_prep(flags, d_offs, d_lens, fc_params, op, 2412f39928e6SAnoob Joseph &prep_req); 2413f39928e6SAnoob Joseph } else if (fc_type == KASUMI) { 2414f39928e6SAnoob Joseph cpt_kasumi_dec_prep(d_offs, d_lens, fc_params, op, &prep_req); 2415f39928e6SAnoob Joseph } 2416f39928e6SAnoob Joseph 2417177b41ceSRagothaman Jayaraman /* 2418177b41ceSRagothaman Jayaraman * For AUTH_ONLY case, 2419177b41ceSRagothaman Jayaraman * MC only supports digest generation and verification 2420177b41ceSRagothaman Jayaraman * should be done in software by memcmp() 2421177b41ceSRagothaman Jayaraman */ 2422177b41ceSRagothaman Jayaraman 2423177b41ceSRagothaman Jayaraman return prep_req; 2424177b41ceSRagothaman Jayaraman } 2425177b41ceSRagothaman Jayaraman 2426e3866e73SThomas Monjalon static __rte_always_inline void *__rte_hot 2427b74652f3SRagothaman Jayaraman cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens, 2428f39928e6SAnoob Joseph fc_params_t *fc_params, void *op) 2429b74652f3SRagothaman Jayaraman { 2430b74652f3SRagothaman Jayaraman struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2431b74652f3SRagothaman Jayaraman uint8_t fc_type; 2432b74652f3SRagothaman Jayaraman void *prep_req = NULL; 2433b74652f3SRagothaman Jayaraman 2434b74652f3SRagothaman Jayaraman fc_type = ctx->fc_type; 2435b74652f3SRagothaman Jayaraman 2436b74652f3SRagothaman Jayaraman /* Common api for rest of the ops */ 2437b74652f3SRagothaman Jayaraman if (likely(fc_type == FC_GEN)) { 2438f39928e6SAnoob Joseph cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2439351fbee2SSrisivasubramanian S &prep_req); 2440f39928e6SAnoob Joseph } else if (fc_type == ZUC_SNOW3G) { 2441f39928e6SAnoob Joseph cpt_zuc_snow3g_enc_prep(flags, d_offs, d_lens, fc_params, op, 2442f39928e6SAnoob Joseph &prep_req); 2443f39928e6SAnoob Joseph } else if (fc_type == KASUMI) { 2444f39928e6SAnoob Joseph cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, op, 2445f39928e6SAnoob Joseph &prep_req); 2446f39928e6SAnoob Joseph } else if (fc_type == HASH_HMAC) { 2447f39928e6SAnoob Joseph cpt_digest_gen_prep(flags, d_lens, fc_params, op, &prep_req); 2448b74652f3SRagothaman Jayaraman } 2449b74652f3SRagothaman Jayaraman 2450b74652f3SRagothaman Jayaraman return prep_req; 2451b74652f3SRagothaman Jayaraman } 2452b74652f3SRagothaman Jayaraman 24536cc54096SNithin Dabilpuram static __rte_always_inline int 2454186b14d6SFan Zhang cpt_fc_auth_set_key(void *ctx, auth_type_t type, const uint8_t *key, 24556cc54096SNithin Dabilpuram uint16_t key_len, uint16_t mac_len) 24566cc54096SNithin Dabilpuram { 24576cc54096SNithin Dabilpuram struct cpt_ctx *cpt_ctx = ctx; 24586cc54096SNithin Dabilpuram mc_fc_context_t *fctx = &cpt_ctx->fctx; 24596cc54096SNithin Dabilpuram 24606cc54096SNithin Dabilpuram if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) { 24616cc54096SNithin Dabilpuram uint32_t keyx[4]; 24626cc54096SNithin Dabilpuram 24636cc54096SNithin Dabilpuram if (key_len != 16) 24646cc54096SNithin Dabilpuram return -1; 24656cc54096SNithin Dabilpuram /* No support for AEAD yet */ 24666cc54096SNithin Dabilpuram if (cpt_ctx->enc_cipher) 24676cc54096SNithin Dabilpuram return -1; 24686cc54096SNithin Dabilpuram /* For ZUC/SNOW3G/Kasumi */ 24696cc54096SNithin Dabilpuram switch (type) { 24706cc54096SNithin Dabilpuram case SNOW3G_UIA2: 24716cc54096SNithin Dabilpuram cpt_ctx->snow3g = 1; 24726cc54096SNithin Dabilpuram gen_key_snow3g(key, keyx); 24736cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); 24746cc54096SNithin Dabilpuram cpt_ctx->fc_type = ZUC_SNOW3G; 24756cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 24766cc54096SNithin Dabilpuram break; 24776cc54096SNithin Dabilpuram case ZUC_EIA3: 24786cc54096SNithin Dabilpuram cpt_ctx->snow3g = 0; 24796cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); 24806cc54096SNithin Dabilpuram memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); 24816cc54096SNithin Dabilpuram cpt_ctx->fc_type = ZUC_SNOW3G; 24826cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 24836cc54096SNithin Dabilpuram break; 24846cc54096SNithin Dabilpuram case KASUMI_F9_ECB: 24856cc54096SNithin Dabilpuram /* Kasumi ECB mode */ 24866cc54096SNithin Dabilpuram cpt_ctx->k_ecb = 1; 24876cc54096SNithin Dabilpuram memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 24886cc54096SNithin Dabilpuram cpt_ctx->fc_type = KASUMI; 24896cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 24906cc54096SNithin Dabilpuram break; 24916cc54096SNithin Dabilpuram case KASUMI_F9_CBC: 24926cc54096SNithin Dabilpuram memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 24936cc54096SNithin Dabilpuram cpt_ctx->fc_type = KASUMI; 24946cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 24956cc54096SNithin Dabilpuram break; 24966cc54096SNithin Dabilpuram default: 24976cc54096SNithin Dabilpuram return -1; 24986cc54096SNithin Dabilpuram } 24996cc54096SNithin Dabilpuram cpt_ctx->mac_len = 4; 25006cc54096SNithin Dabilpuram cpt_ctx->hash_type = type; 25016cc54096SNithin Dabilpuram return 0; 25026cc54096SNithin Dabilpuram } 25036cc54096SNithin Dabilpuram 25046cc54096SNithin Dabilpuram if (!(cpt_ctx->fc_type == FC_GEN && !type)) { 25056cc54096SNithin Dabilpuram if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher) 25066cc54096SNithin Dabilpuram cpt_ctx->fc_type = HASH_HMAC; 25076cc54096SNithin Dabilpuram } 25086cc54096SNithin Dabilpuram 25092839a8abSSucharitha Sarananaga if (cpt_ctx->fc_type == FC_GEN && key_len > 64) 25102839a8abSSucharitha Sarananaga return -1; 25112839a8abSSucharitha Sarananaga 25126cc54096SNithin Dabilpuram /* For GMAC auth, cipher must be NULL */ 25136cc54096SNithin Dabilpuram if (type == GMAC_TYPE) 2514c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = 0; 25156cc54096SNithin Dabilpuram 2516c3d0bc45SAnoob Joseph fctx->enc.hash_type = cpt_ctx->hash_type = type; 2517c3d0bc45SAnoob Joseph fctx->enc.mac_len = cpt_ctx->mac_len = mac_len; 25186cc54096SNithin Dabilpuram 25196cc54096SNithin Dabilpuram if (key_len) { 25206cc54096SNithin Dabilpuram cpt_ctx->hmac = 1; 25216cc54096SNithin Dabilpuram memset(cpt_ctx->auth_key, 0, sizeof(cpt_ctx->auth_key)); 25226cc54096SNithin Dabilpuram memcpy(cpt_ctx->auth_key, key, key_len); 25236cc54096SNithin Dabilpuram cpt_ctx->auth_key_len = key_len; 25246cc54096SNithin Dabilpuram memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 25256cc54096SNithin Dabilpuram memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad)); 25262839a8abSSucharitha Sarananaga 25272839a8abSSucharitha Sarananaga if (key_len <= 64) 25286cc54096SNithin Dabilpuram memcpy(fctx->hmac.opad, key, key_len); 2529c3d0bc45SAnoob Joseph fctx->enc.auth_input_type = 1; 25306cc54096SNithin Dabilpuram } 25316cc54096SNithin Dabilpuram return 0; 25326cc54096SNithin Dabilpuram } 25336cc54096SNithin Dabilpuram 25346cc54096SNithin Dabilpuram static __rte_always_inline int 25356cc54096SNithin Dabilpuram fill_sess_aead(struct rte_crypto_sym_xform *xform, 25366cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 25376cc54096SNithin Dabilpuram { 25386cc54096SNithin Dabilpuram struct rte_crypto_aead_xform *aead_form; 25396cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 25406cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 25416cc54096SNithin Dabilpuram uint32_t cipher_key_len = 0; 25428de5ede7SAnoob Joseph uint8_t aes_gcm = 0; 25436cc54096SNithin Dabilpuram aead_form = &xform->aead; 25448de5ede7SAnoob Joseph void *ctx = SESS_PRIV(sess); 25456cc54096SNithin Dabilpuram 2546*cb7842f2STejasree Kondoj if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { 25476cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 25486cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_GENERATE; 2549*cb7842f2STejasree Kondoj } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) { 25506cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 25516cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_VERIFY; 25526cc54096SNithin Dabilpuram } else { 2553*cb7842f2STejasree Kondoj CPT_LOG_DP_ERR("Unknown aead operation\n"); 25546cc54096SNithin Dabilpuram return -1; 25556cc54096SNithin Dabilpuram } 25566cc54096SNithin Dabilpuram switch (aead_form->algo) { 25576cc54096SNithin Dabilpuram case RTE_CRYPTO_AEAD_AES_GCM: 25586cc54096SNithin Dabilpuram enc_type = AES_GCM; 25596cc54096SNithin Dabilpuram cipher_key_len = 16; 25606cc54096SNithin Dabilpuram aes_gcm = 1; 25616cc54096SNithin Dabilpuram break; 25626cc54096SNithin Dabilpuram case RTE_CRYPTO_AEAD_AES_CCM: 25636cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 25646cc54096SNithin Dabilpuram aead_form->algo); 25656cc54096SNithin Dabilpuram return -1; 2566*cb7842f2STejasree Kondoj case RTE_CRYPTO_AEAD_CHACHA20_POLY1305: 2567*cb7842f2STejasree Kondoj enc_type = CHACHA20; 2568*cb7842f2STejasree Kondoj auth_type = POLY1305; 2569*cb7842f2STejasree Kondoj cipher_key_len = 32; 2570*cb7842f2STejasree Kondoj sess->chacha_poly = 1; 2571*cb7842f2STejasree Kondoj break; 25726cc54096SNithin Dabilpuram default: 25736cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 25746cc54096SNithin Dabilpuram aead_form->algo); 25756cc54096SNithin Dabilpuram return -1; 25766cc54096SNithin Dabilpuram } 25776cc54096SNithin Dabilpuram if (aead_form->key.length < cipher_key_len) { 25786cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 25796cc54096SNithin Dabilpuram (unsigned int long)aead_form->key.length); 25806cc54096SNithin Dabilpuram return -1; 25816cc54096SNithin Dabilpuram } 25828de5ede7SAnoob Joseph sess->zsk_flag = 0; 25836cc54096SNithin Dabilpuram sess->aes_gcm = aes_gcm; 25846cc54096SNithin Dabilpuram sess->mac_len = aead_form->digest_length; 25856cc54096SNithin Dabilpuram sess->iv_offset = aead_form->iv.offset; 25866cc54096SNithin Dabilpuram sess->iv_length = aead_form->iv.length; 25876cc54096SNithin Dabilpuram sess->aad_length = aead_form->aad_length; 25886cc54096SNithin Dabilpuram 2589e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data, 2590e40175c5SArchana Muniganti aead_form->key.length, NULL))) 2591e40175c5SArchana Muniganti return -1; 25926cc54096SNithin Dabilpuram 2593e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2594e40175c5SArchana Muniganti aead_form->digest_length))) 2595e40175c5SArchana Muniganti return -1; 25966cc54096SNithin Dabilpuram 25976cc54096SNithin Dabilpuram return 0; 25986cc54096SNithin Dabilpuram } 25996cc54096SNithin Dabilpuram 26006cc54096SNithin Dabilpuram static __rte_always_inline int 26016cc54096SNithin Dabilpuram fill_sess_cipher(struct rte_crypto_sym_xform *xform, 26026cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 26036cc54096SNithin Dabilpuram { 26046cc54096SNithin Dabilpuram struct rte_crypto_cipher_xform *c_form; 26056cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 26066cc54096SNithin Dabilpuram uint32_t cipher_key_len = 0; 26078de5ede7SAnoob Joseph uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0; 26086cc54096SNithin Dabilpuram 26096cc54096SNithin Dabilpuram c_form = &xform->cipher; 26106cc54096SNithin Dabilpuram 26116cc54096SNithin Dabilpuram if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 26126cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 26136cc54096SNithin Dabilpuram else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) 26146cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 26156cc54096SNithin Dabilpuram else { 26166cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Unknown cipher operation\n"); 26176cc54096SNithin Dabilpuram return -1; 26186cc54096SNithin Dabilpuram } 26196cc54096SNithin Dabilpuram 26206cc54096SNithin Dabilpuram switch (c_form->algo) { 26216cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_CBC: 26226cc54096SNithin Dabilpuram enc_type = AES_CBC; 26236cc54096SNithin Dabilpuram cipher_key_len = 16; 26246cc54096SNithin Dabilpuram break; 26256cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_CBC: 26266cc54096SNithin Dabilpuram enc_type = DES3_CBC; 26276cc54096SNithin Dabilpuram cipher_key_len = 24; 26286cc54096SNithin Dabilpuram break; 26296cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_DES_CBC: 26306cc54096SNithin Dabilpuram /* DES is implemented using 3DES in hardware */ 26316cc54096SNithin Dabilpuram enc_type = DES3_CBC; 26326cc54096SNithin Dabilpuram cipher_key_len = 8; 26336cc54096SNithin Dabilpuram break; 26346cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_CTR: 26356cc54096SNithin Dabilpuram enc_type = AES_CTR; 26366cc54096SNithin Dabilpuram cipher_key_len = 16; 26376cc54096SNithin Dabilpuram aes_ctr = 1; 26386cc54096SNithin Dabilpuram break; 26396cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_NULL: 26406cc54096SNithin Dabilpuram enc_type = 0; 26416cc54096SNithin Dabilpuram is_null = 1; 26426cc54096SNithin Dabilpuram break; 26436cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_KASUMI_F8: 26446cc54096SNithin Dabilpuram enc_type = KASUMI_F8_ECB; 26456cc54096SNithin Dabilpuram cipher_key_len = 16; 26466cc54096SNithin Dabilpuram zsk_flag = K_F8; 26476cc54096SNithin Dabilpuram break; 26486cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: 26496cc54096SNithin Dabilpuram enc_type = SNOW3G_UEA2; 26506cc54096SNithin Dabilpuram cipher_key_len = 16; 26516cc54096SNithin Dabilpuram zsk_flag = ZS_EA; 26526cc54096SNithin Dabilpuram break; 26536cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_ZUC_EEA3: 26546cc54096SNithin Dabilpuram enc_type = ZUC_EEA3; 26556cc54096SNithin Dabilpuram cipher_key_len = 16; 26566cc54096SNithin Dabilpuram zsk_flag = ZS_EA; 26576cc54096SNithin Dabilpuram break; 26586cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_XTS: 26596cc54096SNithin Dabilpuram enc_type = AES_XTS; 26606cc54096SNithin Dabilpuram cipher_key_len = 16; 26616cc54096SNithin Dabilpuram break; 26626cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_ECB: 26636cc54096SNithin Dabilpuram enc_type = DES3_ECB; 26646cc54096SNithin Dabilpuram cipher_key_len = 24; 26656cc54096SNithin Dabilpuram break; 26666cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_ECB: 26676cc54096SNithin Dabilpuram enc_type = AES_ECB; 26686cc54096SNithin Dabilpuram cipher_key_len = 16; 26696cc54096SNithin Dabilpuram break; 26706cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_CTR: 26716cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_F8: 26726cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_ARC4: 26736cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 26746cc54096SNithin Dabilpuram c_form->algo); 26756cc54096SNithin Dabilpuram return -1; 26766cc54096SNithin Dabilpuram default: 26776cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 26786cc54096SNithin Dabilpuram c_form->algo); 26796cc54096SNithin Dabilpuram return -1; 26806cc54096SNithin Dabilpuram } 26816cc54096SNithin Dabilpuram 26826cc54096SNithin Dabilpuram if (c_form->key.length < cipher_key_len) { 26836cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 26846cc54096SNithin Dabilpuram (unsigned long) c_form->key.length); 26856cc54096SNithin Dabilpuram return -1; 26866cc54096SNithin Dabilpuram } 26876cc54096SNithin Dabilpuram 26886cc54096SNithin Dabilpuram sess->zsk_flag = zsk_flag; 26898de5ede7SAnoob Joseph sess->aes_gcm = 0; 26906cc54096SNithin Dabilpuram sess->aes_ctr = aes_ctr; 26916cc54096SNithin Dabilpuram sess->iv_offset = c_form->iv.offset; 26926cc54096SNithin Dabilpuram sess->iv_length = c_form->iv.length; 26936cc54096SNithin Dabilpuram sess->is_null = is_null; 26946cc54096SNithin Dabilpuram 2695e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type, 2696e40175c5SArchana Muniganti c_form->key.data, c_form->key.length, NULL))) 2697e40175c5SArchana Muniganti return -1; 26986cc54096SNithin Dabilpuram 26996cc54096SNithin Dabilpuram return 0; 27006cc54096SNithin Dabilpuram } 27016cc54096SNithin Dabilpuram 27026cc54096SNithin Dabilpuram static __rte_always_inline int 27036cc54096SNithin Dabilpuram fill_sess_auth(struct rte_crypto_sym_xform *xform, 27046cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 27056cc54096SNithin Dabilpuram { 27066cc54096SNithin Dabilpuram struct rte_crypto_auth_xform *a_form; 27076cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 27086cc54096SNithin Dabilpuram uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0; 27096cc54096SNithin Dabilpuram 27106cc54096SNithin Dabilpuram a_form = &xform->auth; 27116cc54096SNithin Dabilpuram 27126cc54096SNithin Dabilpuram if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 27136cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_VERIFY; 27146cc54096SNithin Dabilpuram else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 27156cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_GENERATE; 27166cc54096SNithin Dabilpuram else { 27176cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Unknown auth operation"); 27186cc54096SNithin Dabilpuram return -1; 27196cc54096SNithin Dabilpuram } 27206cc54096SNithin Dabilpuram 27216cc54096SNithin Dabilpuram switch (a_form->algo) { 27226cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA1_HMAC: 27236cc54096SNithin Dabilpuram /* Fall through */ 27246cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA1: 27256cc54096SNithin Dabilpuram auth_type = SHA1_TYPE; 27266cc54096SNithin Dabilpuram break; 27276cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA256_HMAC: 27286cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA256: 27296cc54096SNithin Dabilpuram auth_type = SHA2_SHA256; 27306cc54096SNithin Dabilpuram break; 27316cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA512_HMAC: 27326cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA512: 27336cc54096SNithin Dabilpuram auth_type = SHA2_SHA512; 27346cc54096SNithin Dabilpuram break; 27356cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_GMAC: 27366cc54096SNithin Dabilpuram auth_type = GMAC_TYPE; 27376cc54096SNithin Dabilpuram aes_gcm = 1; 27386cc54096SNithin Dabilpuram break; 27396cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA224_HMAC: 27406cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA224: 27416cc54096SNithin Dabilpuram auth_type = SHA2_SHA224; 27426cc54096SNithin Dabilpuram break; 27436cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA384_HMAC: 27446cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA384: 27456cc54096SNithin Dabilpuram auth_type = SHA2_SHA384; 27466cc54096SNithin Dabilpuram break; 27476cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_MD5_HMAC: 27486cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_MD5: 27496cc54096SNithin Dabilpuram auth_type = MD5_TYPE; 27506cc54096SNithin Dabilpuram break; 27516cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_KASUMI_F9: 27526cc54096SNithin Dabilpuram auth_type = KASUMI_F9_ECB; 27536cc54096SNithin Dabilpuram /* 27546cc54096SNithin Dabilpuram * Indicate that direction needs to be taken out 27556cc54096SNithin Dabilpuram * from end of src 27566cc54096SNithin Dabilpuram */ 27576cc54096SNithin Dabilpuram zsk_flag = K_F9; 27586cc54096SNithin Dabilpuram break; 27596cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SNOW3G_UIA2: 27606cc54096SNithin Dabilpuram auth_type = SNOW3G_UIA2; 27616cc54096SNithin Dabilpuram zsk_flag = ZS_IA; 27626cc54096SNithin Dabilpuram break; 27636cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_ZUC_EIA3: 27646cc54096SNithin Dabilpuram auth_type = ZUC_EIA3; 27656cc54096SNithin Dabilpuram zsk_flag = ZS_IA; 27666cc54096SNithin Dabilpuram break; 27676cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_NULL: 27686cc54096SNithin Dabilpuram auth_type = 0; 27696cc54096SNithin Dabilpuram is_null = 1; 27706cc54096SNithin Dabilpuram break; 27716cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 27726cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_CMAC: 27736cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_CBC_MAC: 27746cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u", 27756cc54096SNithin Dabilpuram a_form->algo); 27768de5ede7SAnoob Joseph return -1; 27776cc54096SNithin Dabilpuram default: 27786cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified", 27796cc54096SNithin Dabilpuram a_form->algo); 27808de5ede7SAnoob Joseph return -1; 27816cc54096SNithin Dabilpuram } 27826cc54096SNithin Dabilpuram 27836cc54096SNithin Dabilpuram sess->zsk_flag = zsk_flag; 27846cc54096SNithin Dabilpuram sess->aes_gcm = aes_gcm; 27856cc54096SNithin Dabilpuram sess->mac_len = a_form->digest_length; 27866cc54096SNithin Dabilpuram sess->is_null = is_null; 27876cc54096SNithin Dabilpuram if (zsk_flag) { 27886cc54096SNithin Dabilpuram sess->auth_iv_offset = a_form->iv.offset; 27896cc54096SNithin Dabilpuram sess->auth_iv_length = a_form->iv.length; 27906cc54096SNithin Dabilpuram } 2791e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type, 2792e40175c5SArchana Muniganti a_form->key.data, a_form->key.length, 2793e40175c5SArchana Muniganti a_form->digest_length))) 2794e40175c5SArchana Muniganti return -1; 27956cc54096SNithin Dabilpuram 27966cc54096SNithin Dabilpuram return 0; 27976cc54096SNithin Dabilpuram } 27986cc54096SNithin Dabilpuram 27996cc54096SNithin Dabilpuram static __rte_always_inline int 28006cc54096SNithin Dabilpuram fill_sess_gmac(struct rte_crypto_sym_xform *xform, 28016cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 28026cc54096SNithin Dabilpuram { 28036cc54096SNithin Dabilpuram struct rte_crypto_auth_xform *a_form; 28046cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 28056cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 28068de5ede7SAnoob Joseph void *ctx = SESS_PRIV(sess); 28076cc54096SNithin Dabilpuram 28086cc54096SNithin Dabilpuram a_form = &xform->auth; 28096cc54096SNithin Dabilpuram 28106cc54096SNithin Dabilpuram if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 28116cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_ENCODE; 28126cc54096SNithin Dabilpuram else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 28136cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_DECODE; 28146cc54096SNithin Dabilpuram else { 28156cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Unknown auth operation"); 28166cc54096SNithin Dabilpuram return -1; 28176cc54096SNithin Dabilpuram } 28186cc54096SNithin Dabilpuram 28196cc54096SNithin Dabilpuram switch (a_form->algo) { 28206cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_GMAC: 28216cc54096SNithin Dabilpuram enc_type = AES_GCM; 28226cc54096SNithin Dabilpuram auth_type = GMAC_TYPE; 28236cc54096SNithin Dabilpuram break; 28246cc54096SNithin Dabilpuram default: 28256cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 28266cc54096SNithin Dabilpuram a_form->algo); 28276cc54096SNithin Dabilpuram return -1; 28286cc54096SNithin Dabilpuram } 28296cc54096SNithin Dabilpuram 28308de5ede7SAnoob Joseph sess->zsk_flag = 0; 28318de5ede7SAnoob Joseph sess->aes_gcm = 0; 28326cc54096SNithin Dabilpuram sess->is_gmac = 1; 28336cc54096SNithin Dabilpuram sess->iv_offset = a_form->iv.offset; 28346cc54096SNithin Dabilpuram sess->iv_length = a_form->iv.length; 28356cc54096SNithin Dabilpuram sess->mac_len = a_form->digest_length; 28366cc54096SNithin Dabilpuram 2837e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data, 2838e40175c5SArchana Muniganti a_form->key.length, NULL))) 2839e40175c5SArchana Muniganti return -1; 2840e40175c5SArchana Muniganti 2841e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2842e40175c5SArchana Muniganti a_form->digest_length))) 2843e40175c5SArchana Muniganti return -1; 28446cc54096SNithin Dabilpuram 28456cc54096SNithin Dabilpuram return 0; 28466cc54096SNithin Dabilpuram } 28476cc54096SNithin Dabilpuram 2848b74652f3SRagothaman Jayaraman static __rte_always_inline void * 2849b74652f3SRagothaman Jayaraman alloc_op_meta(struct rte_mbuf *m_src, 2850b74652f3SRagothaman Jayaraman buf_ptr_t *buf, 2851b74652f3SRagothaman Jayaraman int32_t len, 2852b74652f3SRagothaman Jayaraman struct rte_mempool *cpt_meta_pool) 2853b74652f3SRagothaman Jayaraman { 2854b74652f3SRagothaman Jayaraman uint8_t *mdata; 2855b74652f3SRagothaman Jayaraman 2856b74652f3SRagothaman Jayaraman #ifndef CPT_ALWAYS_USE_SEPARATE_BUF 2857b74652f3SRagothaman Jayaraman if (likely(m_src && (m_src->nb_segs == 1))) { 2858b74652f3SRagothaman Jayaraman int32_t tailroom; 2859b74652f3SRagothaman Jayaraman phys_addr_t mphys; 2860b74652f3SRagothaman Jayaraman 2861b74652f3SRagothaman Jayaraman /* Check if tailroom is sufficient to hold meta data */ 2862b74652f3SRagothaman Jayaraman tailroom = rte_pktmbuf_tailroom(m_src); 2863b74652f3SRagothaman Jayaraman if (likely(tailroom > len + 8)) { 2864b74652f3SRagothaman Jayaraman mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len; 2865b74652f3SRagothaman Jayaraman mphys = m_src->buf_physaddr + m_src->buf_len; 2866b74652f3SRagothaman Jayaraman mdata -= len; 2867b74652f3SRagothaman Jayaraman mphys -= len; 2868b74652f3SRagothaman Jayaraman buf->vaddr = mdata; 2869b74652f3SRagothaman Jayaraman buf->dma_addr = mphys; 2870b74652f3SRagothaman Jayaraman buf->size = len; 2871b74652f3SRagothaman Jayaraman /* Indicate that this is a mbuf allocated mdata */ 2872b74652f3SRagothaman Jayaraman mdata = (uint8_t *)((uint64_t)mdata | 1ull); 2873b74652f3SRagothaman Jayaraman return mdata; 2874b74652f3SRagothaman Jayaraman } 2875b74652f3SRagothaman Jayaraman } 2876b74652f3SRagothaman Jayaraman #else 2877b74652f3SRagothaman Jayaraman RTE_SET_USED(m_src); 2878b74652f3SRagothaman Jayaraman #endif 2879b74652f3SRagothaman Jayaraman 2880b74652f3SRagothaman Jayaraman if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0)) 2881b74652f3SRagothaman Jayaraman return NULL; 2882b74652f3SRagothaman Jayaraman 2883b74652f3SRagothaman Jayaraman buf->vaddr = mdata; 2884b74652f3SRagothaman Jayaraman buf->dma_addr = rte_mempool_virt2iova(mdata); 2885b74652f3SRagothaman Jayaraman buf->size = len; 2886b74652f3SRagothaman Jayaraman 2887b74652f3SRagothaman Jayaraman return mdata; 2888b74652f3SRagothaman Jayaraman } 2889b74652f3SRagothaman Jayaraman 2890b74652f3SRagothaman Jayaraman /** 2891b74652f3SRagothaman Jayaraman * cpt_free_metabuf - free metabuf to mempool. 2892b74652f3SRagothaman Jayaraman * @param instance: pointer to instance. 2893b74652f3SRagothaman Jayaraman * @param objp: pointer to the metabuf. 2894b74652f3SRagothaman Jayaraman */ 2895b74652f3SRagothaman Jayaraman static __rte_always_inline void 2896b74652f3SRagothaman Jayaraman free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool) 2897b74652f3SRagothaman Jayaraman { 2898b74652f3SRagothaman Jayaraman bool nofree = ((uintptr_t)mdata & 1ull); 2899b74652f3SRagothaman Jayaraman 2900b74652f3SRagothaman Jayaraman if (likely(nofree)) 2901b74652f3SRagothaman Jayaraman return; 2902b74652f3SRagothaman Jayaraman rte_mempool_put(cpt_meta_pool, mdata); 2903b74652f3SRagothaman Jayaraman } 2904b74652f3SRagothaman Jayaraman 2905b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 2906b74652f3SRagothaman Jayaraman prepare_iov_from_pkt(struct rte_mbuf *pkt, 2907b74652f3SRagothaman Jayaraman iov_ptr_t *iovec, uint32_t start_offset) 2908b74652f3SRagothaman Jayaraman { 2909b74652f3SRagothaman Jayaraman uint16_t index = 0; 2910b74652f3SRagothaman Jayaraman void *seg_data = NULL; 2911b74652f3SRagothaman Jayaraman phys_addr_t seg_phys; 2912b74652f3SRagothaman Jayaraman int32_t seg_size = 0; 2913b74652f3SRagothaman Jayaraman 2914b74652f3SRagothaman Jayaraman if (!pkt) { 2915b74652f3SRagothaman Jayaraman iovec->buf_cnt = 0; 2916b74652f3SRagothaman Jayaraman return 0; 2917b74652f3SRagothaman Jayaraman } 2918b74652f3SRagothaman Jayaraman 2919b74652f3SRagothaman Jayaraman if (!start_offset) { 2920b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 2921b74652f3SRagothaman Jayaraman seg_phys = rte_pktmbuf_mtophys(pkt); 2922b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 2923b74652f3SRagothaman Jayaraman } else { 2924b74652f3SRagothaman Jayaraman while (start_offset >= pkt->data_len) { 2925b74652f3SRagothaman Jayaraman start_offset -= pkt->data_len; 2926b74652f3SRagothaman Jayaraman pkt = pkt->next; 2927b74652f3SRagothaman Jayaraman } 2928b74652f3SRagothaman Jayaraman 2929b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset); 2930b74652f3SRagothaman Jayaraman seg_phys = rte_pktmbuf_mtophys_offset(pkt, start_offset); 2931b74652f3SRagothaman Jayaraman seg_size = pkt->data_len - start_offset; 2932b74652f3SRagothaman Jayaraman if (!seg_size) 2933b74652f3SRagothaman Jayaraman return 1; 2934b74652f3SRagothaman Jayaraman } 2935b74652f3SRagothaman Jayaraman 2936b74652f3SRagothaman Jayaraman /* first seg */ 2937b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 2938b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 2939b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 2940b74652f3SRagothaman Jayaraman index++; 2941b74652f3SRagothaman Jayaraman pkt = pkt->next; 2942b74652f3SRagothaman Jayaraman 2943b74652f3SRagothaman Jayaraman while (unlikely(pkt != NULL)) { 2944b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 2945b74652f3SRagothaman Jayaraman seg_phys = rte_pktmbuf_mtophys(pkt); 2946b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 2947b74652f3SRagothaman Jayaraman if (!seg_size) 2948b74652f3SRagothaman Jayaraman break; 2949b74652f3SRagothaman Jayaraman 2950b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 2951b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 2952b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 2953b74652f3SRagothaman Jayaraman 2954b74652f3SRagothaman Jayaraman index++; 2955b74652f3SRagothaman Jayaraman 2956b74652f3SRagothaman Jayaraman pkt = pkt->next; 2957b74652f3SRagothaman Jayaraman } 2958b74652f3SRagothaman Jayaraman 2959b74652f3SRagothaman Jayaraman iovec->buf_cnt = index; 2960b74652f3SRagothaman Jayaraman return 0; 2961b74652f3SRagothaman Jayaraman } 2962b74652f3SRagothaman Jayaraman 2963b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 2964b74652f3SRagothaman Jayaraman prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt, 2965b74652f3SRagothaman Jayaraman fc_params_t *param, 2966b74652f3SRagothaman Jayaraman uint32_t *flags) 2967b74652f3SRagothaman Jayaraman { 2968b74652f3SRagothaman Jayaraman uint16_t index = 0; 2969b74652f3SRagothaman Jayaraman void *seg_data = NULL; 2970b74652f3SRagothaman Jayaraman phys_addr_t seg_phys; 2971b74652f3SRagothaman Jayaraman uint32_t seg_size = 0; 2972b74652f3SRagothaman Jayaraman iov_ptr_t *iovec; 2973b74652f3SRagothaman Jayaraman 2974b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 2975b74652f3SRagothaman Jayaraman seg_phys = rte_pktmbuf_mtophys(pkt); 2976b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 2977b74652f3SRagothaman Jayaraman 2978b74652f3SRagothaman Jayaraman /* first seg */ 2979b74652f3SRagothaman Jayaraman if (likely(!pkt->next)) { 2980b74652f3SRagothaman Jayaraman uint32_t headroom, tailroom; 2981b74652f3SRagothaman Jayaraman 2982b74652f3SRagothaman Jayaraman *flags |= SINGLE_BUF_INPLACE; 2983b74652f3SRagothaman Jayaraman headroom = rte_pktmbuf_headroom(pkt); 2984b74652f3SRagothaman Jayaraman tailroom = rte_pktmbuf_tailroom(pkt); 2985b74652f3SRagothaman Jayaraman if (likely((headroom >= 24) && 2986b74652f3SRagothaman Jayaraman (tailroom >= 8))) { 2987b74652f3SRagothaman Jayaraman /* In 83XX this is prerequivisit for Direct mode */ 2988b74652f3SRagothaman Jayaraman *flags |= SINGLE_BUF_HEADTAILROOM; 2989b74652f3SRagothaman Jayaraman } 2990b74652f3SRagothaman Jayaraman param->bufs[0].vaddr = seg_data; 2991b74652f3SRagothaman Jayaraman param->bufs[0].dma_addr = seg_phys; 2992b74652f3SRagothaman Jayaraman param->bufs[0].size = seg_size; 2993b74652f3SRagothaman Jayaraman return 0; 2994b74652f3SRagothaman Jayaraman } 2995b74652f3SRagothaman Jayaraman iovec = param->src_iov; 2996b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 2997b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 2998b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 2999b74652f3SRagothaman Jayaraman index++; 3000b74652f3SRagothaman Jayaraman pkt = pkt->next; 3001b74652f3SRagothaman Jayaraman 3002b74652f3SRagothaman Jayaraman while (unlikely(pkt != NULL)) { 3003b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 3004b74652f3SRagothaman Jayaraman seg_phys = rte_pktmbuf_mtophys(pkt); 3005b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 3006b74652f3SRagothaman Jayaraman 3007b74652f3SRagothaman Jayaraman if (!seg_size) 3008b74652f3SRagothaman Jayaraman break; 3009b74652f3SRagothaman Jayaraman 3010b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 3011b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 3012b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 3013b74652f3SRagothaman Jayaraman 3014b74652f3SRagothaman Jayaraman index++; 3015b74652f3SRagothaman Jayaraman 3016b74652f3SRagothaman Jayaraman pkt = pkt->next; 3017b74652f3SRagothaman Jayaraman } 3018b74652f3SRagothaman Jayaraman 3019b74652f3SRagothaman Jayaraman iovec->buf_cnt = index; 3020b74652f3SRagothaman Jayaraman return 0; 3021b74652f3SRagothaman Jayaraman } 3022b74652f3SRagothaman Jayaraman 3023f39928e6SAnoob Joseph static __rte_always_inline int 3024b74652f3SRagothaman Jayaraman fill_fc_params(struct rte_crypto_op *cop, 3025b74652f3SRagothaman Jayaraman struct cpt_sess_misc *sess_misc, 3026ec54bc9dSAnoob Joseph struct cpt_qp_meta_info *m_info, 3027b74652f3SRagothaman Jayaraman void **mdata_ptr, 3028f39928e6SAnoob Joseph void **prep_req) 3029b74652f3SRagothaman Jayaraman { 3030b74652f3SRagothaman Jayaraman uint32_t space = 0; 3031b74652f3SRagothaman Jayaraman struct rte_crypto_sym_op *sym_op = cop->sym; 3032f39928e6SAnoob Joseph void *mdata = NULL; 3033b74652f3SRagothaman Jayaraman uintptr_t *op; 3034b74652f3SRagothaman Jayaraman uint32_t mc_hash_off; 3035b74652f3SRagothaman Jayaraman uint32_t flags = 0; 3036b74652f3SRagothaman Jayaraman uint64_t d_offs, d_lens; 3037b74652f3SRagothaman Jayaraman struct rte_mbuf *m_src, *m_dst; 3038b74652f3SRagothaman Jayaraman uint8_t cpt_op = sess_misc->cpt_op; 3039b74652f3SRagothaman Jayaraman #ifdef CPT_ALWAYS_USE_SG_MODE 3040b74652f3SRagothaman Jayaraman uint8_t inplace = 0; 3041b74652f3SRagothaman Jayaraman #else 3042b74652f3SRagothaman Jayaraman uint8_t inplace = 1; 3043b74652f3SRagothaman Jayaraman #endif 3044b74652f3SRagothaman Jayaraman fc_params_t fc_params; 3045b74652f3SRagothaman Jayaraman char src[SRC_IOV_SIZE]; 3046b74652f3SRagothaman Jayaraman char dst[SRC_IOV_SIZE]; 3047b74652f3SRagothaman Jayaraman uint32_t iv_buf[4]; 3048f39928e6SAnoob Joseph int ret; 3049b74652f3SRagothaman Jayaraman 3050b74652f3SRagothaman Jayaraman if (likely(sess_misc->iv_length)) { 3051b74652f3SRagothaman Jayaraman flags |= VALID_IV_BUF; 3052b74652f3SRagothaman Jayaraman fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, 3053b74652f3SRagothaman Jayaraman uint8_t *, sess_misc->iv_offset); 3054b74652f3SRagothaman Jayaraman if (sess_misc->aes_ctr && 3055b74652f3SRagothaman Jayaraman unlikely(sess_misc->iv_length != 16)) { 3056b74652f3SRagothaman Jayaraman memcpy((uint8_t *)iv_buf, 3057b74652f3SRagothaman Jayaraman rte_crypto_op_ctod_offset(cop, 3058b74652f3SRagothaman Jayaraman uint8_t *, sess_misc->iv_offset), 12); 3059b74652f3SRagothaman Jayaraman iv_buf[3] = rte_cpu_to_be_32(0x1); 3060b74652f3SRagothaman Jayaraman fc_params.iv_buf = iv_buf; 3061b74652f3SRagothaman Jayaraman } 3062b74652f3SRagothaman Jayaraman } 3063b74652f3SRagothaman Jayaraman 30648de5ede7SAnoob Joseph if (sess_misc->zsk_flag) { 3065b74652f3SRagothaman Jayaraman fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3066b74652f3SRagothaman Jayaraman uint8_t *, 3067b74652f3SRagothaman Jayaraman sess_misc->auth_iv_offset); 30688de5ede7SAnoob Joseph if (sess_misc->zsk_flag != ZS_EA) 3069b74652f3SRagothaman Jayaraman inplace = 0; 3070b74652f3SRagothaman Jayaraman } 3071b74652f3SRagothaman Jayaraman m_src = sym_op->m_src; 3072b74652f3SRagothaman Jayaraman m_dst = sym_op->m_dst; 3073b74652f3SRagothaman Jayaraman 3074*cb7842f2STejasree Kondoj if (sess_misc->aes_gcm || sess_misc->chacha_poly) { 3075b74652f3SRagothaman Jayaraman uint8_t *salt; 3076b74652f3SRagothaman Jayaraman uint8_t *aad_data; 3077b74652f3SRagothaman Jayaraman uint16_t aad_len; 3078b74652f3SRagothaman Jayaraman 3079b74652f3SRagothaman Jayaraman d_offs = sym_op->aead.data.offset; 3080b74652f3SRagothaman Jayaraman d_lens = sym_op->aead.data.length; 3081b74652f3SRagothaman Jayaraman mc_hash_off = sym_op->aead.data.offset + 3082b74652f3SRagothaman Jayaraman sym_op->aead.data.length; 3083b74652f3SRagothaman Jayaraman 3084b74652f3SRagothaman Jayaraman aad_data = sym_op->aead.aad.data; 3085b74652f3SRagothaman Jayaraman aad_len = sess_misc->aad_length; 3086b74652f3SRagothaman Jayaraman if (likely((aad_data + aad_len) == 3087b74652f3SRagothaman Jayaraman rte_pktmbuf_mtod_offset(m_src, 3088b74652f3SRagothaman Jayaraman uint8_t *, 3089b74652f3SRagothaman Jayaraman sym_op->aead.data.offset))) { 3090b74652f3SRagothaman Jayaraman d_offs = (d_offs - aad_len) | (d_offs << 16); 3091b74652f3SRagothaman Jayaraman d_lens = (d_lens + aad_len) | (d_lens << 32); 3092b74652f3SRagothaman Jayaraman } else { 3093b74652f3SRagothaman Jayaraman fc_params.aad_buf.vaddr = sym_op->aead.aad.data; 3094b74652f3SRagothaman Jayaraman fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr; 3095b74652f3SRagothaman Jayaraman fc_params.aad_buf.size = aad_len; 3096b74652f3SRagothaman Jayaraman flags |= VALID_AAD_BUF; 3097b74652f3SRagothaman Jayaraman inplace = 0; 3098b74652f3SRagothaman Jayaraman d_offs = d_offs << 16; 3099b74652f3SRagothaman Jayaraman d_lens = d_lens << 32; 3100b74652f3SRagothaman Jayaraman } 3101b74652f3SRagothaman Jayaraman 3102b74652f3SRagothaman Jayaraman salt = fc_params.iv_buf; 3103b74652f3SRagothaman Jayaraman if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3104b74652f3SRagothaman Jayaraman cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3105b74652f3SRagothaman Jayaraman sess_misc->salt = *(uint32_t *)salt; 3106b74652f3SRagothaman Jayaraman } 3107b74652f3SRagothaman Jayaraman fc_params.iv_buf = salt + 4; 31088de5ede7SAnoob Joseph if (likely(sess_misc->mac_len)) { 3109b74652f3SRagothaman Jayaraman struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst : 3110b74652f3SRagothaman Jayaraman m_src; 3111b74652f3SRagothaman Jayaraman 3112b74652f3SRagothaman Jayaraman if (!m) 3113b74652f3SRagothaman Jayaraman m = m_src; 3114b74652f3SRagothaman Jayaraman 3115b74652f3SRagothaman Jayaraman /* hmac immediately following data is best case */ 3116b74652f3SRagothaman Jayaraman if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + 3117b74652f3SRagothaman Jayaraman mc_hash_off != 3118b74652f3SRagothaman Jayaraman (uint8_t *)sym_op->aead.digest.data)) { 3119b74652f3SRagothaman Jayaraman flags |= VALID_MAC_BUF; 3120b74652f3SRagothaman Jayaraman fc_params.mac_buf.size = sess_misc->mac_len; 3121b74652f3SRagothaman Jayaraman fc_params.mac_buf.vaddr = 3122b74652f3SRagothaman Jayaraman sym_op->aead.digest.data; 3123b74652f3SRagothaman Jayaraman fc_params.mac_buf.dma_addr = 3124b74652f3SRagothaman Jayaraman sym_op->aead.digest.phys_addr; 3125b74652f3SRagothaman Jayaraman inplace = 0; 3126b74652f3SRagothaman Jayaraman } 3127b74652f3SRagothaman Jayaraman } 3128b74652f3SRagothaman Jayaraman } else { 3129b74652f3SRagothaman Jayaraman d_offs = sym_op->cipher.data.offset; 3130b74652f3SRagothaman Jayaraman d_lens = sym_op->cipher.data.length; 3131b74652f3SRagothaman Jayaraman mc_hash_off = sym_op->cipher.data.offset + 3132b74652f3SRagothaman Jayaraman sym_op->cipher.data.length; 3133b74652f3SRagothaman Jayaraman d_offs = (d_offs << 16) | sym_op->auth.data.offset; 3134b74652f3SRagothaman Jayaraman d_lens = (d_lens << 32) | sym_op->auth.data.length; 3135b74652f3SRagothaman Jayaraman 3136b74652f3SRagothaman Jayaraman if (mc_hash_off < (sym_op->auth.data.offset + 3137b74652f3SRagothaman Jayaraman sym_op->auth.data.length)){ 3138b74652f3SRagothaman Jayaraman mc_hash_off = (sym_op->auth.data.offset + 3139b74652f3SRagothaman Jayaraman sym_op->auth.data.length); 3140b74652f3SRagothaman Jayaraman } 3141b74652f3SRagothaman Jayaraman /* for gmac, salt should be updated like in gcm */ 3142b74652f3SRagothaman Jayaraman if (unlikely(sess_misc->is_gmac)) { 3143b74652f3SRagothaman Jayaraman uint8_t *salt; 3144b74652f3SRagothaman Jayaraman salt = fc_params.iv_buf; 3145b74652f3SRagothaman Jayaraman if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3146b74652f3SRagothaman Jayaraman cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3147b74652f3SRagothaman Jayaraman sess_misc->salt = *(uint32_t *)salt; 3148b74652f3SRagothaman Jayaraman } 3149b74652f3SRagothaman Jayaraman fc_params.iv_buf = salt + 4; 3150b74652f3SRagothaman Jayaraman } 31518de5ede7SAnoob Joseph if (likely(sess_misc->mac_len)) { 3152b74652f3SRagothaman Jayaraman struct rte_mbuf *m; 3153b74652f3SRagothaman Jayaraman 3154b74652f3SRagothaman Jayaraman m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src; 3155b74652f3SRagothaman Jayaraman if (!m) 3156b74652f3SRagothaman Jayaraman m = m_src; 3157b74652f3SRagothaman Jayaraman 3158b74652f3SRagothaman Jayaraman /* hmac immediately following data is best case */ 3159b74652f3SRagothaman Jayaraman if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + 3160b74652f3SRagothaman Jayaraman mc_hash_off != 3161b74652f3SRagothaman Jayaraman (uint8_t *)sym_op->auth.digest.data)) { 3162b74652f3SRagothaman Jayaraman flags |= VALID_MAC_BUF; 3163b74652f3SRagothaman Jayaraman fc_params.mac_buf.size = 3164b74652f3SRagothaman Jayaraman sess_misc->mac_len; 3165b74652f3SRagothaman Jayaraman fc_params.mac_buf.vaddr = 3166b74652f3SRagothaman Jayaraman sym_op->auth.digest.data; 3167b74652f3SRagothaman Jayaraman fc_params.mac_buf.dma_addr = 3168b74652f3SRagothaman Jayaraman sym_op->auth.digest.phys_addr; 3169b74652f3SRagothaman Jayaraman inplace = 0; 3170b74652f3SRagothaman Jayaraman } 3171b74652f3SRagothaman Jayaraman } 3172b74652f3SRagothaman Jayaraman } 3173b74652f3SRagothaman Jayaraman fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc); 3174b74652f3SRagothaman Jayaraman fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr; 3175b74652f3SRagothaman Jayaraman 3176b74652f3SRagothaman Jayaraman if (unlikely(sess_misc->is_null || sess_misc->cpt_op == CPT_OP_DECODE)) 3177b74652f3SRagothaman Jayaraman inplace = 0; 3178b74652f3SRagothaman Jayaraman 3179b74652f3SRagothaman Jayaraman if (likely(!m_dst && inplace)) { 3180b74652f3SRagothaman Jayaraman /* Case of single buffer without AAD buf or 3181b74652f3SRagothaman Jayaraman * separate mac buf in place and 3182b74652f3SRagothaman Jayaraman * not air crypto 3183b74652f3SRagothaman Jayaraman */ 3184b74652f3SRagothaman Jayaraman fc_params.dst_iov = fc_params.src_iov = (void *)src; 3185b74652f3SRagothaman Jayaraman 3186b74652f3SRagothaman Jayaraman if (unlikely(prepare_iov_from_pkt_inplace(m_src, 3187b74652f3SRagothaman Jayaraman &fc_params, 3188b74652f3SRagothaman Jayaraman &flags))) { 3189b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare inplace src iov failed"); 3190f39928e6SAnoob Joseph ret = -EINVAL; 3191f39928e6SAnoob Joseph goto err_exit; 3192b74652f3SRagothaman Jayaraman } 3193b74652f3SRagothaman Jayaraman 3194b74652f3SRagothaman Jayaraman } else { 3195b74652f3SRagothaman Jayaraman /* Out of place processing */ 3196b74652f3SRagothaman Jayaraman fc_params.src_iov = (void *)src; 3197b74652f3SRagothaman Jayaraman fc_params.dst_iov = (void *)dst; 3198b74652f3SRagothaman Jayaraman 3199b74652f3SRagothaman Jayaraman /* Store SG I/O in the api for reuse */ 3200b74652f3SRagothaman Jayaraman if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) { 3201b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare src iov failed"); 3202f39928e6SAnoob Joseph ret = -EINVAL; 3203f39928e6SAnoob Joseph goto err_exit; 3204b74652f3SRagothaman Jayaraman } 3205b74652f3SRagothaman Jayaraman 3206b74652f3SRagothaman Jayaraman if (unlikely(m_dst != NULL)) { 3207b74652f3SRagothaman Jayaraman uint32_t pkt_len; 3208b74652f3SRagothaman Jayaraman 3209b74652f3SRagothaman Jayaraman /* Try to make room as much as src has */ 3210b74652f3SRagothaman Jayaraman pkt_len = rte_pktmbuf_pkt_len(m_dst); 3211b74652f3SRagothaman Jayaraman 3212b74652f3SRagothaman Jayaraman if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) { 3213b74652f3SRagothaman Jayaraman pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len; 3214b74652f3SRagothaman Jayaraman if (!rte_pktmbuf_append(m_dst, pkt_len)) { 3215b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Not enough space in " 3216b74652f3SRagothaman Jayaraman "m_dst %p, need %u" 3217b74652f3SRagothaman Jayaraman " more", 3218b74652f3SRagothaman Jayaraman m_dst, pkt_len); 3219f39928e6SAnoob Joseph ret = -EINVAL; 3220f39928e6SAnoob Joseph goto err_exit; 3221b74652f3SRagothaman Jayaraman } 3222b74652f3SRagothaman Jayaraman } 3223b74652f3SRagothaman Jayaraman 3224b74652f3SRagothaman Jayaraman if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) { 3225b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare dst iov failed for " 3226b74652f3SRagothaman Jayaraman "m_dst %p", m_dst); 3227f39928e6SAnoob Joseph ret = -EINVAL; 3228f39928e6SAnoob Joseph goto err_exit; 3229b74652f3SRagothaman Jayaraman } 3230b74652f3SRagothaman Jayaraman } else { 3231b74652f3SRagothaman Jayaraman fc_params.dst_iov = (void *)src; 3232b74652f3SRagothaman Jayaraman } 3233b74652f3SRagothaman Jayaraman } 3234b74652f3SRagothaman Jayaraman 3235b74652f3SRagothaman Jayaraman if (likely(flags & SINGLE_BUF_HEADTAILROOM)) 3236ec54bc9dSAnoob Joseph mdata = alloc_op_meta(m_src, &fc_params.meta_buf, 3237ec54bc9dSAnoob Joseph m_info->lb_mlen, m_info->pool); 3238b74652f3SRagothaman Jayaraman else 3239ec54bc9dSAnoob Joseph mdata = alloc_op_meta(NULL, &fc_params.meta_buf, 3240ec54bc9dSAnoob Joseph m_info->sg_mlen, m_info->pool); 3241b74652f3SRagothaman Jayaraman 3242b74652f3SRagothaman Jayaraman if (unlikely(mdata == NULL)) { 3243b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Error allocating meta buffer for request"); 3244f39928e6SAnoob Joseph ret = -ENOMEM; 3245f39928e6SAnoob Joseph goto err_exit; 3246b74652f3SRagothaman Jayaraman } 3247b74652f3SRagothaman Jayaraman 3248b74652f3SRagothaman Jayaraman op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull); 3249b74652f3SRagothaman Jayaraman op[0] = (uintptr_t)mdata; 3250b74652f3SRagothaman Jayaraman op[1] = (uintptr_t)cop; 3251b74652f3SRagothaman Jayaraman op[2] = op[3] = 0; /* Used to indicate auth verify */ 3252b74652f3SRagothaman Jayaraman space += 4 * sizeof(uint64_t); 3253b74652f3SRagothaman Jayaraman 3254b74652f3SRagothaman Jayaraman fc_params.meta_buf.vaddr = (uint8_t *)op + space; 3255b74652f3SRagothaman Jayaraman fc_params.meta_buf.dma_addr += space; 3256b74652f3SRagothaman Jayaraman fc_params.meta_buf.size -= space; 3257b74652f3SRagothaman Jayaraman 3258b74652f3SRagothaman Jayaraman /* Finally prepare the instruction */ 3259b74652f3SRagothaman Jayaraman if (cpt_op & CPT_OP_ENCODE) 3260f39928e6SAnoob Joseph *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, 3261f39928e6SAnoob Joseph &fc_params, op); 3262177b41ceSRagothaman Jayaraman else 3263f39928e6SAnoob Joseph *prep_req = cpt_fc_dec_hmac_prep(flags, d_offs, d_lens, 3264f39928e6SAnoob Joseph &fc_params, op); 3265b74652f3SRagothaman Jayaraman 3266f39928e6SAnoob Joseph if (unlikely(*prep_req == NULL)) { 3267f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Preparing request failed due to bad input arg"); 3268f39928e6SAnoob Joseph ret = -EINVAL; 3269f39928e6SAnoob Joseph goto free_mdata_and_exit; 3270f39928e6SAnoob Joseph } 3271f39928e6SAnoob Joseph 3272b74652f3SRagothaman Jayaraman *mdata_ptr = mdata; 3273f39928e6SAnoob Joseph 3274f39928e6SAnoob Joseph return 0; 3275f39928e6SAnoob Joseph 3276f39928e6SAnoob Joseph free_mdata_and_exit: 3277ec54bc9dSAnoob Joseph free_op_meta(mdata, m_info->pool); 3278f39928e6SAnoob Joseph err_exit: 3279f39928e6SAnoob Joseph return ret; 3280b74652f3SRagothaman Jayaraman } 3281b74652f3SRagothaman Jayaraman 328289f1a8d6STejasree Kondoj static __rte_always_inline void 328389f1a8d6STejasree Kondoj compl_auth_verify(struct rte_crypto_op *op, 328489f1a8d6STejasree Kondoj uint8_t *gen_mac, 328589f1a8d6STejasree Kondoj uint64_t mac_len) 328689f1a8d6STejasree Kondoj { 328789f1a8d6STejasree Kondoj uint8_t *mac; 328889f1a8d6STejasree Kondoj struct rte_crypto_sym_op *sym_op = op->sym; 328989f1a8d6STejasree Kondoj 329089f1a8d6STejasree Kondoj if (sym_op->auth.digest.data) 329189f1a8d6STejasree Kondoj mac = sym_op->auth.digest.data; 329289f1a8d6STejasree Kondoj else 329389f1a8d6STejasree Kondoj mac = rte_pktmbuf_mtod_offset(sym_op->m_src, 329489f1a8d6STejasree Kondoj uint8_t *, 329589f1a8d6STejasree Kondoj sym_op->auth.data.length + 329689f1a8d6STejasree Kondoj sym_op->auth.data.offset); 329789f1a8d6STejasree Kondoj if (!mac) { 329889f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_ERROR; 329989f1a8d6STejasree Kondoj return; 330089f1a8d6STejasree Kondoj } 330189f1a8d6STejasree Kondoj 330289f1a8d6STejasree Kondoj if (memcmp(mac, gen_mac, mac_len)) 330389f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; 330489f1a8d6STejasree Kondoj else 330589f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 330689f1a8d6STejasree Kondoj } 330789f1a8d6STejasree Kondoj 3308351fbee2SSrisivasubramanian S static __rte_always_inline void 3309351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(uint8_t *src, 3310351fbee2SSrisivasubramanian S uint32_t counter_num_bytes, 3311351fbee2SSrisivasubramanian S uint32_t *addr_length_in_bits, 3312351fbee2SSrisivasubramanian S uint8_t *addr_direction) 3313351fbee2SSrisivasubramanian S { 3314351fbee2SSrisivasubramanian S uint8_t found = 0; 3315f9494b67SAnkur Dwivedi uint32_t pos; 3316f9494b67SAnkur Dwivedi uint8_t last_byte; 3317351fbee2SSrisivasubramanian S while (!found && counter_num_bytes > 0) { 3318351fbee2SSrisivasubramanian S counter_num_bytes--; 3319351fbee2SSrisivasubramanian S if (src[counter_num_bytes] == 0x00) 3320351fbee2SSrisivasubramanian S continue; 3321f9494b67SAnkur Dwivedi pos = rte_bsf32(src[counter_num_bytes]); 3322f9494b67SAnkur Dwivedi if (pos == 7) { 3323f9494b67SAnkur Dwivedi if (likely(counter_num_bytes > 0)) { 3324f9494b67SAnkur Dwivedi last_byte = src[counter_num_bytes - 1]; 3325f9494b67SAnkur Dwivedi *addr_direction = last_byte & 0x1; 3326f9494b67SAnkur Dwivedi *addr_length_in_bits = counter_num_bytes * 8 3327f9494b67SAnkur Dwivedi - 1; 3328f9494b67SAnkur Dwivedi } 3329351fbee2SSrisivasubramanian S } else { 3330f9494b67SAnkur Dwivedi last_byte = src[counter_num_bytes]; 3331f9494b67SAnkur Dwivedi *addr_direction = (last_byte >> (pos + 1)) & 0x1; 3332f9494b67SAnkur Dwivedi *addr_length_in_bits = counter_num_bytes * 8 3333f9494b67SAnkur Dwivedi + (8 - (pos + 2)); 3334f9494b67SAnkur Dwivedi } 3335351fbee2SSrisivasubramanian S found = 1; 3336351fbee2SSrisivasubramanian S } 3337351fbee2SSrisivasubramanian S } 3338351fbee2SSrisivasubramanian S 3339351fbee2SSrisivasubramanian S /* 3340351fbee2SSrisivasubramanian S * This handles all auth only except AES_GMAC 3341351fbee2SSrisivasubramanian S */ 3342f39928e6SAnoob Joseph static __rte_always_inline int 3343351fbee2SSrisivasubramanian S fill_digest_params(struct rte_crypto_op *cop, 3344351fbee2SSrisivasubramanian S struct cpt_sess_misc *sess, 3345ec54bc9dSAnoob Joseph struct cpt_qp_meta_info *m_info, 3346351fbee2SSrisivasubramanian S void **mdata_ptr, 3347f39928e6SAnoob Joseph void **prep_req) 3348351fbee2SSrisivasubramanian S { 3349351fbee2SSrisivasubramanian S uint32_t space = 0; 3350351fbee2SSrisivasubramanian S struct rte_crypto_sym_op *sym_op = cop->sym; 3351351fbee2SSrisivasubramanian S void *mdata; 3352351fbee2SSrisivasubramanian S phys_addr_t mphys; 3353351fbee2SSrisivasubramanian S uint64_t *op; 3354351fbee2SSrisivasubramanian S uint32_t auth_range_off; 3355351fbee2SSrisivasubramanian S uint32_t flags = 0; 3356351fbee2SSrisivasubramanian S uint64_t d_offs = 0, d_lens; 3357351fbee2SSrisivasubramanian S struct rte_mbuf *m_src, *m_dst; 3358351fbee2SSrisivasubramanian S uint16_t auth_op = sess->cpt_op & CPT_OP_AUTH_MASK; 3359351fbee2SSrisivasubramanian S uint16_t mac_len = sess->mac_len; 3360351fbee2SSrisivasubramanian S fc_params_t params; 3361351fbee2SSrisivasubramanian S char src[SRC_IOV_SIZE]; 3362351fbee2SSrisivasubramanian S uint8_t iv_buf[16]; 3363f39928e6SAnoob Joseph int ret; 3364f39928e6SAnoob Joseph 3365351fbee2SSrisivasubramanian S memset(¶ms, 0, sizeof(fc_params_t)); 3366351fbee2SSrisivasubramanian S 3367351fbee2SSrisivasubramanian S m_src = sym_op->m_src; 3368351fbee2SSrisivasubramanian S 3369351fbee2SSrisivasubramanian S /* For just digest lets force mempool alloc */ 3370ec54bc9dSAnoob Joseph mdata = alloc_op_meta(NULL, ¶ms.meta_buf, m_info->sg_mlen, 3371ec54bc9dSAnoob Joseph m_info->pool); 3372351fbee2SSrisivasubramanian S if (mdata == NULL) { 3373f39928e6SAnoob Joseph ret = -ENOMEM; 3374f39928e6SAnoob Joseph goto err_exit; 3375351fbee2SSrisivasubramanian S } 3376351fbee2SSrisivasubramanian S 3377351fbee2SSrisivasubramanian S mphys = params.meta_buf.dma_addr; 3378351fbee2SSrisivasubramanian S 3379351fbee2SSrisivasubramanian S op = mdata; 3380351fbee2SSrisivasubramanian S op[0] = (uintptr_t)mdata; 3381351fbee2SSrisivasubramanian S op[1] = (uintptr_t)cop; 3382351fbee2SSrisivasubramanian S op[2] = op[3] = 0; /* Used to indicate auth verify */ 3383351fbee2SSrisivasubramanian S space += 4 * sizeof(uint64_t); 3384351fbee2SSrisivasubramanian S 3385351fbee2SSrisivasubramanian S auth_range_off = sym_op->auth.data.offset; 3386351fbee2SSrisivasubramanian S 3387351fbee2SSrisivasubramanian S flags = VALID_MAC_BUF; 3388351fbee2SSrisivasubramanian S params.src_iov = (void *)src; 33898de5ede7SAnoob Joseph if (unlikely(sess->zsk_flag)) { 3390351fbee2SSrisivasubramanian S /* 3391351fbee2SSrisivasubramanian S * Since for Zuc, Kasumi, Snow3g offsets are in bits 3392351fbee2SSrisivasubramanian S * we will send pass through even for auth only case, 3393351fbee2SSrisivasubramanian S * let MC handle it 3394351fbee2SSrisivasubramanian S */ 3395351fbee2SSrisivasubramanian S d_offs = auth_range_off; 3396351fbee2SSrisivasubramanian S auth_range_off = 0; 3397351fbee2SSrisivasubramanian S params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3398351fbee2SSrisivasubramanian S uint8_t *, sess->auth_iv_offset); 33998de5ede7SAnoob Joseph if (sess->zsk_flag == K_F9) { 3400351fbee2SSrisivasubramanian S uint32_t length_in_bits, num_bytes; 3401351fbee2SSrisivasubramanian S uint8_t *src, direction = 0; 3402351fbee2SSrisivasubramanian S 3403351fbee2SSrisivasubramanian S memcpy(iv_buf, rte_pktmbuf_mtod(cop->sym->m_src, 3404351fbee2SSrisivasubramanian S uint8_t *), 8); 3405351fbee2SSrisivasubramanian S /* 3406351fbee2SSrisivasubramanian S * This is kasumi f9, take direction from 3407351fbee2SSrisivasubramanian S * source buffer 3408351fbee2SSrisivasubramanian S */ 3409351fbee2SSrisivasubramanian S length_in_bits = cop->sym->auth.data.length; 3410351fbee2SSrisivasubramanian S num_bytes = (length_in_bits >> 3); 3411351fbee2SSrisivasubramanian S src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *); 3412351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(src, 34138de5ede7SAnoob Joseph num_bytes, 3414351fbee2SSrisivasubramanian S &length_in_bits, 3415351fbee2SSrisivasubramanian S &direction); 3416351fbee2SSrisivasubramanian S length_in_bits -= 64; 3417351fbee2SSrisivasubramanian S cop->sym->auth.data.offset += 64; 3418351fbee2SSrisivasubramanian S d_offs = cop->sym->auth.data.offset; 3419351fbee2SSrisivasubramanian S auth_range_off = d_offs / 8; 3420351fbee2SSrisivasubramanian S cop->sym->auth.data.length = length_in_bits; 3421351fbee2SSrisivasubramanian S 3422351fbee2SSrisivasubramanian S /* Store it at end of auth iv */ 3423351fbee2SSrisivasubramanian S iv_buf[8] = direction; 3424351fbee2SSrisivasubramanian S params.auth_iv_buf = iv_buf; 3425351fbee2SSrisivasubramanian S } 3426351fbee2SSrisivasubramanian S } 3427351fbee2SSrisivasubramanian S 3428351fbee2SSrisivasubramanian S d_lens = sym_op->auth.data.length; 3429351fbee2SSrisivasubramanian S 3430351fbee2SSrisivasubramanian S params.ctx_buf.vaddr = SESS_PRIV(sess); 3431351fbee2SSrisivasubramanian S params.ctx_buf.dma_addr = sess->ctx_dma_addr; 3432351fbee2SSrisivasubramanian S 3433351fbee2SSrisivasubramanian S if (auth_op == CPT_OP_AUTH_GENERATE) { 3434351fbee2SSrisivasubramanian S if (sym_op->auth.digest.data) { 3435351fbee2SSrisivasubramanian S /* 3436351fbee2SSrisivasubramanian S * Digest to be generated 3437351fbee2SSrisivasubramanian S * in separate buffer 3438351fbee2SSrisivasubramanian S */ 3439351fbee2SSrisivasubramanian S params.mac_buf.size = 3440351fbee2SSrisivasubramanian S sess->mac_len; 3441351fbee2SSrisivasubramanian S params.mac_buf.vaddr = 3442351fbee2SSrisivasubramanian S sym_op->auth.digest.data; 3443351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = 3444351fbee2SSrisivasubramanian S sym_op->auth.digest.phys_addr; 3445351fbee2SSrisivasubramanian S } else { 3446351fbee2SSrisivasubramanian S uint32_t off = sym_op->auth.data.offset + 3447351fbee2SSrisivasubramanian S sym_op->auth.data.length; 3448351fbee2SSrisivasubramanian S int32_t dlen, space; 3449351fbee2SSrisivasubramanian S 3450351fbee2SSrisivasubramanian S m_dst = sym_op->m_dst ? 3451351fbee2SSrisivasubramanian S sym_op->m_dst : sym_op->m_src; 3452351fbee2SSrisivasubramanian S dlen = rte_pktmbuf_pkt_len(m_dst); 3453351fbee2SSrisivasubramanian S 3454351fbee2SSrisivasubramanian S space = off + mac_len - dlen; 3455351fbee2SSrisivasubramanian S if (space > 0) 3456351fbee2SSrisivasubramanian S if (!rte_pktmbuf_append(m_dst, space)) { 3457351fbee2SSrisivasubramanian S CPT_LOG_DP_ERR("Failed to extend " 3458351fbee2SSrisivasubramanian S "mbuf by %uB", space); 3459f39928e6SAnoob Joseph ret = -EINVAL; 3460f39928e6SAnoob Joseph goto free_mdata_and_exit; 3461351fbee2SSrisivasubramanian S } 3462351fbee2SSrisivasubramanian S 3463351fbee2SSrisivasubramanian S params.mac_buf.vaddr = 3464351fbee2SSrisivasubramanian S rte_pktmbuf_mtod_offset(m_dst, void *, off); 3465351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = 3466351fbee2SSrisivasubramanian S rte_pktmbuf_mtophys_offset(m_dst, off); 3467351fbee2SSrisivasubramanian S params.mac_buf.size = mac_len; 3468351fbee2SSrisivasubramanian S } 3469351fbee2SSrisivasubramanian S } else { 3470351fbee2SSrisivasubramanian S /* Need space for storing generated mac */ 3471351fbee2SSrisivasubramanian S params.mac_buf.vaddr = (uint8_t *)mdata + space; 3472351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = mphys + space; 3473351fbee2SSrisivasubramanian S params.mac_buf.size = mac_len; 3474351fbee2SSrisivasubramanian S space += RTE_ALIGN_CEIL(mac_len, 8); 3475351fbee2SSrisivasubramanian S op[2] = (uintptr_t)params.mac_buf.vaddr; 3476351fbee2SSrisivasubramanian S op[3] = mac_len; 3477351fbee2SSrisivasubramanian S } 3478351fbee2SSrisivasubramanian S 3479351fbee2SSrisivasubramanian S params.meta_buf.vaddr = (uint8_t *)mdata + space; 3480351fbee2SSrisivasubramanian S params.meta_buf.dma_addr = mphys + space; 3481351fbee2SSrisivasubramanian S params.meta_buf.size -= space; 3482351fbee2SSrisivasubramanian S 3483351fbee2SSrisivasubramanian S /* Out of place processing */ 3484351fbee2SSrisivasubramanian S params.src_iov = (void *)src; 3485351fbee2SSrisivasubramanian S 3486351fbee2SSrisivasubramanian S /*Store SG I/O in the api for reuse */ 3487351fbee2SSrisivasubramanian S if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off)) { 3488351fbee2SSrisivasubramanian S CPT_LOG_DP_ERR("Prepare src iov failed"); 3489f39928e6SAnoob Joseph ret = -EINVAL; 3490f39928e6SAnoob Joseph goto free_mdata_and_exit; 3491351fbee2SSrisivasubramanian S } 3492351fbee2SSrisivasubramanian S 3493f39928e6SAnoob Joseph *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, ¶ms, op); 3494f39928e6SAnoob Joseph if (unlikely(*prep_req == NULL)) { 3495f39928e6SAnoob Joseph ret = -EINVAL; 3496f39928e6SAnoob Joseph goto free_mdata_and_exit; 3497f39928e6SAnoob Joseph } 3498f39928e6SAnoob Joseph 3499351fbee2SSrisivasubramanian S *mdata_ptr = mdata; 3500f39928e6SAnoob Joseph 3501f39928e6SAnoob Joseph return 0; 3502f39928e6SAnoob Joseph 3503f39928e6SAnoob Joseph free_mdata_and_exit: 3504ec54bc9dSAnoob Joseph free_op_meta(mdata, m_info->pool); 3505f39928e6SAnoob Joseph err_exit: 3506f39928e6SAnoob Joseph return ret; 3507351fbee2SSrisivasubramanian S } 3508351fbee2SSrisivasubramanian S 350943d01767SNithin Dabilpuram #endif /*_CPT_UCODE_H_ */ 3510