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 387293bae1SArchana Muniganti static __rte_always_inline int 397293bae1SArchana Muniganti cpt_mac_len_verify(struct rte_crypto_auth_xform *auth) 407293bae1SArchana Muniganti { 417293bae1SArchana Muniganti uint16_t mac_len = auth->digest_length; 427293bae1SArchana Muniganti int ret; 437293bae1SArchana Muniganti 448d8afdecSTejasree Kondoj if ((auth->algo != RTE_CRYPTO_AUTH_NULL) && (mac_len == 0)) 458d8afdecSTejasree Kondoj return -1; 468d8afdecSTejasree Kondoj 477293bae1SArchana Muniganti switch (auth->algo) { 487293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_MD5: 497293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_MD5_HMAC: 508d8afdecSTejasree Kondoj ret = (mac_len <= 16) ? 0 : -1; 517293bae1SArchana Muniganti break; 527293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA1: 537293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA1_HMAC: 548d8afdecSTejasree Kondoj ret = (mac_len <= 20) ? 0 : -1; 557293bae1SArchana Muniganti break; 567293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA224: 577293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA224_HMAC: 588d8afdecSTejasree Kondoj ret = (mac_len <= 28) ? 0 : -1; 597293bae1SArchana Muniganti break; 607293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA256: 617293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA256_HMAC: 628d8afdecSTejasree Kondoj ret = (mac_len <= 32) ? 0 : -1; 637293bae1SArchana Muniganti break; 647293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA384: 657293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA384_HMAC: 668d8afdecSTejasree Kondoj ret = (mac_len <= 48) ? 0 : -1; 677293bae1SArchana Muniganti break; 687293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA512: 697293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_SHA512_HMAC: 708d8afdecSTejasree Kondoj ret = (mac_len <= 64) ? 0 : -1; 717293bae1SArchana Muniganti break; 727293bae1SArchana Muniganti case RTE_CRYPTO_AUTH_NULL: 737293bae1SArchana Muniganti ret = 0; 747293bae1SArchana Muniganti break; 757293bae1SArchana Muniganti default: 767293bae1SArchana Muniganti ret = -1; 777293bae1SArchana Muniganti } 787293bae1SArchana Muniganti 797293bae1SArchana Muniganti return ret; 807293bae1SArchana Muniganti } 817293bae1SArchana Muniganti 82b74652f3SRagothaman Jayaraman static __rte_always_inline void 836045c06aSArchana Muniganti cpt_fc_salt_update(struct cpt_ctx *cpt_ctx, 84b74652f3SRagothaman Jayaraman uint8_t *salt) 85b74652f3SRagothaman Jayaraman { 866045c06aSArchana Muniganti mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx; 876045c06aSArchana Muniganti memcpy(fctx->enc.encr_iv, salt, 4); 88b74652f3SRagothaman Jayaraman } 89b74652f3SRagothaman Jayaraman 906cc54096SNithin Dabilpuram static __rte_always_inline int 916cc54096SNithin Dabilpuram cpt_fc_ciph_validate_key_aes(uint16_t key_len) 926cc54096SNithin Dabilpuram { 936cc54096SNithin Dabilpuram switch (key_len) { 94b67ecf3eSArchana Muniganti case 16: 95b67ecf3eSArchana Muniganti case 24: 96b67ecf3eSArchana Muniganti case 32: 976cc54096SNithin Dabilpuram return 0; 986cc54096SNithin Dabilpuram default: 996cc54096SNithin Dabilpuram return -1; 1006cc54096SNithin Dabilpuram } 1016cc54096SNithin Dabilpuram } 1026cc54096SNithin Dabilpuram 1036cc54096SNithin Dabilpuram static __rte_always_inline int 1048de5ede7SAnoob Joseph cpt_fc_ciph_set_type(cipher_type_t type, struct cpt_ctx *ctx, uint16_t key_len) 1056cc54096SNithin Dabilpuram { 1066cc54096SNithin Dabilpuram int fc_type = 0; 1076cc54096SNithin Dabilpuram switch (type) { 1086cc54096SNithin Dabilpuram case PASSTHROUGH: 1096cc54096SNithin Dabilpuram fc_type = FC_GEN; 1106cc54096SNithin Dabilpuram break; 1116cc54096SNithin Dabilpuram case DES3_CBC: 1126cc54096SNithin Dabilpuram case DES3_ECB: 1136cc54096SNithin Dabilpuram fc_type = FC_GEN; 1146cc54096SNithin Dabilpuram break; 1156cc54096SNithin Dabilpuram case AES_CBC: 1166cc54096SNithin Dabilpuram case AES_ECB: 1176cc54096SNithin Dabilpuram case AES_CFB: 1186cc54096SNithin Dabilpuram case AES_CTR: 1196cc54096SNithin Dabilpuram case AES_GCM: 1206cc54096SNithin Dabilpuram if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 1216cc54096SNithin Dabilpuram return -1; 1226cc54096SNithin Dabilpuram fc_type = FC_GEN; 1236cc54096SNithin Dabilpuram break; 124cb7842f2STejasree Kondoj case CHACHA20: 125cb7842f2STejasree Kondoj fc_type = FC_GEN; 126cb7842f2STejasree Kondoj break; 1276cc54096SNithin Dabilpuram case AES_XTS: 1286cc54096SNithin Dabilpuram key_len = key_len / 2; 129b67ecf3eSArchana Muniganti if (unlikely(key_len == 24)) { 1306cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid AES key len for XTS"); 1316cc54096SNithin Dabilpuram return -1; 1326cc54096SNithin Dabilpuram } 1336cc54096SNithin Dabilpuram if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 1346cc54096SNithin Dabilpuram return -1; 1356cc54096SNithin Dabilpuram fc_type = FC_GEN; 1366cc54096SNithin Dabilpuram break; 1376cc54096SNithin Dabilpuram case ZUC_EEA3: 1386cc54096SNithin Dabilpuram case SNOW3G_UEA2: 1396cc54096SNithin Dabilpuram if (unlikely(key_len != 16)) 1406cc54096SNithin Dabilpuram return -1; 1416cc54096SNithin Dabilpuram /* No support for AEAD yet */ 1428de5ede7SAnoob Joseph if (unlikely(ctx->hash_type)) 1436cc54096SNithin Dabilpuram return -1; 1446cc54096SNithin Dabilpuram fc_type = ZUC_SNOW3G; 1456cc54096SNithin Dabilpuram break; 1466cc54096SNithin Dabilpuram case KASUMI_F8_CBC: 1476cc54096SNithin Dabilpuram case KASUMI_F8_ECB: 1486cc54096SNithin Dabilpuram if (unlikely(key_len != 16)) 1496cc54096SNithin Dabilpuram return -1; 1506cc54096SNithin Dabilpuram /* No support for AEAD yet */ 1518de5ede7SAnoob Joseph if (unlikely(ctx->hash_type)) 1526cc54096SNithin Dabilpuram return -1; 1536cc54096SNithin Dabilpuram fc_type = KASUMI; 1546cc54096SNithin Dabilpuram break; 1556cc54096SNithin Dabilpuram default: 1566cc54096SNithin Dabilpuram return -1; 1576cc54096SNithin Dabilpuram } 1588de5ede7SAnoob Joseph 1598de5ede7SAnoob Joseph ctx->fc_type = fc_type; 1608de5ede7SAnoob Joseph return 0; 1616cc54096SNithin Dabilpuram } 1626cc54096SNithin Dabilpuram 1636cc54096SNithin Dabilpuram static __rte_always_inline void 1646cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx) 1656cc54096SNithin Dabilpuram { 1666cc54096SNithin Dabilpuram cpt_ctx->enc_cipher = 0; 167c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = 0; 1686cc54096SNithin Dabilpuram } 1696cc54096SNithin Dabilpuram 1706cc54096SNithin Dabilpuram static __rte_always_inline void 1716cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len) 1726cc54096SNithin Dabilpuram { 1736cc54096SNithin Dabilpuram mc_aes_type_t aes_key_type = 0; 1746cc54096SNithin Dabilpuram switch (key_len) { 175b67ecf3eSArchana Muniganti case 16: 1766cc54096SNithin Dabilpuram aes_key_type = AES_128_BIT; 1776cc54096SNithin Dabilpuram break; 178b67ecf3eSArchana Muniganti case 24: 1796cc54096SNithin Dabilpuram aes_key_type = AES_192_BIT; 1806cc54096SNithin Dabilpuram break; 181b67ecf3eSArchana Muniganti case 32: 1826cc54096SNithin Dabilpuram aes_key_type = AES_256_BIT; 1836cc54096SNithin Dabilpuram break; 1846cc54096SNithin Dabilpuram default: 1856cc54096SNithin Dabilpuram /* This should not happen */ 1866cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid AES key len"); 1876cc54096SNithin Dabilpuram return; 1886cc54096SNithin Dabilpuram } 189c3d0bc45SAnoob Joseph fctx->enc.aes_key = aes_key_type; 1906cc54096SNithin Dabilpuram } 1916cc54096SNithin Dabilpuram 1926cc54096SNithin Dabilpuram static __rte_always_inline void 193186b14d6SFan Zhang cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key, 1946cc54096SNithin Dabilpuram uint16_t key_len) 1956cc54096SNithin Dabilpuram { 1966045c06aSArchana Muniganti mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx; 1976cc54096SNithin Dabilpuram uint32_t keyx[4]; 1986045c06aSArchana Muniganti 1996cc54096SNithin Dabilpuram cpt_ctx->snow3g = 1; 2006cc54096SNithin Dabilpuram gen_key_snow3g(key, keyx); 2016045c06aSArchana Muniganti memcpy(zs_ctx->ci_key, keyx, key_len); 2026cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 2036cc54096SNithin Dabilpuram } 2046cc54096SNithin Dabilpuram 2056cc54096SNithin Dabilpuram static __rte_always_inline void 206186b14d6SFan Zhang cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key, 2076cc54096SNithin Dabilpuram uint16_t key_len) 2086cc54096SNithin Dabilpuram { 2096045c06aSArchana Muniganti mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx; 2106045c06aSArchana Muniganti 2116cc54096SNithin Dabilpuram cpt_ctx->snow3g = 0; 2126045c06aSArchana Muniganti memcpy(zs_ctx->ci_key, key, key_len); 2136045c06aSArchana Muniganti memcpy(zs_ctx->zuc_const, zuc_d, 32); 2146cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 2156cc54096SNithin Dabilpuram } 2166cc54096SNithin Dabilpuram 2176cc54096SNithin Dabilpuram static __rte_always_inline void 218186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key, 2196cc54096SNithin Dabilpuram uint16_t key_len) 2206cc54096SNithin Dabilpuram { 2216045c06aSArchana Muniganti mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx; 2226045c06aSArchana Muniganti 2236cc54096SNithin Dabilpuram cpt_ctx->k_ecb = 1; 2246045c06aSArchana Muniganti memcpy(k_ctx->ci_key, key, key_len); 2256cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 2266cc54096SNithin Dabilpuram } 2276cc54096SNithin Dabilpuram 2286cc54096SNithin Dabilpuram static __rte_always_inline void 229186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key, 2306cc54096SNithin Dabilpuram uint16_t key_len) 2316cc54096SNithin Dabilpuram { 2326045c06aSArchana Muniganti mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx; 2336045c06aSArchana Muniganti 2346045c06aSArchana Muniganti memcpy(k_ctx->ci_key, key, key_len); 2356cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0; 2366cc54096SNithin Dabilpuram } 2376cc54096SNithin Dabilpuram 2386cc54096SNithin Dabilpuram static __rte_always_inline int 2396045c06aSArchana Muniganti cpt_fc_ciph_set_key(struct cpt_ctx *cpt_ctx, cipher_type_t type, 2406045c06aSArchana Muniganti const uint8_t *key, uint16_t key_len, uint8_t *salt) 2416cc54096SNithin Dabilpuram { 2426045c06aSArchana Muniganti mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx; 2438de5ede7SAnoob Joseph int ret; 2446cc54096SNithin Dabilpuram 2458de5ede7SAnoob Joseph ret = cpt_fc_ciph_set_type(type, cpt_ctx, key_len); 2468de5ede7SAnoob Joseph if (unlikely(ret)) 2476cc54096SNithin Dabilpuram return -1; 2486cc54096SNithin Dabilpuram 2498de5ede7SAnoob Joseph if (cpt_ctx->fc_type == FC_GEN) { 2506cc54096SNithin Dabilpuram /* 2516cc54096SNithin Dabilpuram * We need to always say IV is from DPTR as user can 2527be78d02SJosh Soref * sometimes override IV per operation. 2536cc54096SNithin Dabilpuram */ 254c3d0bc45SAnoob Joseph fctx->enc.iv_source = CPT_FROM_DPTR; 2552839a8abSSucharitha Sarananaga 2562839a8abSSucharitha Sarananaga if (cpt_ctx->auth_key_len > 64) 2572839a8abSSucharitha Sarananaga return -1; 2586cc54096SNithin Dabilpuram } 2596cc54096SNithin Dabilpuram 2606cc54096SNithin Dabilpuram switch (type) { 2616cc54096SNithin Dabilpuram case PASSTHROUGH: 2626cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx); 263c3d0bc45SAnoob Joseph goto success; 2646cc54096SNithin Dabilpuram case DES3_CBC: 2656cc54096SNithin Dabilpuram /* CPT performs DES using 3DES with the 8B DES-key 2666cc54096SNithin Dabilpuram * replicated 2 more times to match the 24B 3DES-key. 2676cc54096SNithin Dabilpuram * Eg. If org. key is "0x0a 0x0b", then new key is 2686cc54096SNithin Dabilpuram * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b" 2696cc54096SNithin Dabilpuram */ 2706cc54096SNithin Dabilpuram if (key_len == 8) { 2716cc54096SNithin Dabilpuram /* Skipping the first 8B as it will be copied 2726cc54096SNithin Dabilpuram * in the regular code flow 2736cc54096SNithin Dabilpuram */ 2746cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key+key_len, key, key_len); 2756cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key+2*key_len, key, key_len); 2766cc54096SNithin Dabilpuram } 2776cc54096SNithin Dabilpuram break; 2786cc54096SNithin Dabilpuram case DES3_ECB: 2796cc54096SNithin Dabilpuram /* For DES3_ECB IV need to be from CTX. */ 280c3d0bc45SAnoob Joseph fctx->enc.iv_source = CPT_FROM_CTX; 2816cc54096SNithin Dabilpuram break; 2826cc54096SNithin Dabilpuram case AES_CBC: 2836cc54096SNithin Dabilpuram case AES_ECB: 2846cc54096SNithin Dabilpuram case AES_CFB: 2856cc54096SNithin Dabilpuram case AES_CTR: 286cb7842f2STejasree Kondoj case CHACHA20: 2876cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 2886cc54096SNithin Dabilpuram break; 2896cc54096SNithin Dabilpuram case AES_GCM: 2906cc54096SNithin Dabilpuram /* Even though iv source is from dptr, 2916cc54096SNithin Dabilpuram * aes_gcm salt is taken from ctx 2926cc54096SNithin Dabilpuram */ 2936cc54096SNithin Dabilpuram if (salt) { 2946cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_iv, salt, 4); 2956cc54096SNithin Dabilpuram /* Assuming it was just salt update 2966cc54096SNithin Dabilpuram * and nothing else 2976cc54096SNithin Dabilpuram */ 2986cc54096SNithin Dabilpuram if (!key) 299c3d0bc45SAnoob Joseph goto success; 3006cc54096SNithin Dabilpuram } 3016cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 3026cc54096SNithin Dabilpuram break; 3036cc54096SNithin Dabilpuram case AES_XTS: 3046cc54096SNithin Dabilpuram key_len = key_len / 2; 3056cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 3066cc54096SNithin Dabilpuram 3076cc54096SNithin Dabilpuram /* Copy key2 for XTS into ipad */ 3086cc54096SNithin Dabilpuram memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 3096cc54096SNithin Dabilpuram memcpy(fctx->hmac.ipad, &key[key_len], key_len); 3106cc54096SNithin Dabilpuram break; 3116cc54096SNithin Dabilpuram case SNOW3G_UEA2: 3126cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len); 3136cc54096SNithin Dabilpuram goto success; 3146cc54096SNithin Dabilpuram case ZUC_EEA3: 3156cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len); 3166cc54096SNithin Dabilpuram goto success; 3176cc54096SNithin Dabilpuram case KASUMI_F8_ECB: 3186cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len); 3196cc54096SNithin Dabilpuram goto success; 3206cc54096SNithin Dabilpuram case KASUMI_F8_CBC: 3216cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len); 3226cc54096SNithin Dabilpuram goto success; 3236cc54096SNithin Dabilpuram default: 324e40175c5SArchana Muniganti return -1; 3256cc54096SNithin Dabilpuram } 3266cc54096SNithin Dabilpuram 3276cc54096SNithin Dabilpuram /* Only for FC_GEN case */ 3286cc54096SNithin Dabilpuram 3296cc54096SNithin Dabilpuram /* For GMAC auth, cipher must be NULL */ 3306cc54096SNithin Dabilpuram if (cpt_ctx->hash_type != GMAC_TYPE) 331c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = type; 3326cc54096SNithin Dabilpuram 3336cc54096SNithin Dabilpuram memcpy(fctx->enc.encr_key, key, key_len); 3346cc54096SNithin Dabilpuram 3356cc54096SNithin Dabilpuram success: 3366cc54096SNithin Dabilpuram cpt_ctx->enc_cipher = type; 3376cc54096SNithin Dabilpuram 3386cc54096SNithin Dabilpuram return 0; 3396cc54096SNithin Dabilpuram } 3406cc54096SNithin Dabilpuram 341b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 342b74652f3SRagothaman Jayaraman fill_sg_comp(sg_comp_t *list, 343b74652f3SRagothaman Jayaraman uint32_t i, 344b74652f3SRagothaman Jayaraman phys_addr_t dma_addr, 345b74652f3SRagothaman Jayaraman uint32_t size) 346b74652f3SRagothaman Jayaraman { 347b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i>>2]; 348b74652f3SRagothaman Jayaraman 349b74652f3SRagothaman Jayaraman to->u.s.len[i%4] = rte_cpu_to_be_16(size); 350b74652f3SRagothaman Jayaraman to->ptr[i%4] = rte_cpu_to_be_64(dma_addr); 351b74652f3SRagothaman Jayaraman i++; 352b74652f3SRagothaman Jayaraman return i; 353b74652f3SRagothaman Jayaraman } 354b74652f3SRagothaman Jayaraman 355b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 356b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf(sg_comp_t *list, 357b74652f3SRagothaman Jayaraman uint32_t i, 358b74652f3SRagothaman Jayaraman buf_ptr_t *from) 359b74652f3SRagothaman Jayaraman { 360b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i>>2]; 361b74652f3SRagothaman Jayaraman 362b74652f3SRagothaman Jayaraman to->u.s.len[i%4] = rte_cpu_to_be_16(from->size); 363b74652f3SRagothaman Jayaraman to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr); 364b74652f3SRagothaman Jayaraman i++; 365b74652f3SRagothaman Jayaraman return i; 366b74652f3SRagothaman Jayaraman } 367b74652f3SRagothaman Jayaraman 368b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 369b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf_min(sg_comp_t *list, 370b74652f3SRagothaman Jayaraman uint32_t i, 371b74652f3SRagothaman Jayaraman buf_ptr_t *from, 372b74652f3SRagothaman Jayaraman uint32_t *psize) 373b74652f3SRagothaman Jayaraman { 374b74652f3SRagothaman Jayaraman sg_comp_t *to = &list[i >> 2]; 375b74652f3SRagothaman Jayaraman uint32_t size = *psize; 376b74652f3SRagothaman Jayaraman uint32_t e_len; 377b74652f3SRagothaman Jayaraman 378b74652f3SRagothaman Jayaraman e_len = (size > from->size) ? from->size : size; 379b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 380b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr); 381b74652f3SRagothaman Jayaraman *psize -= e_len; 382b74652f3SRagothaman Jayaraman i++; 383b74652f3SRagothaman Jayaraman return i; 384b74652f3SRagothaman Jayaraman } 385b74652f3SRagothaman Jayaraman 386b74652f3SRagothaman Jayaraman /* 387b74652f3SRagothaman Jayaraman * This fills the MC expected SGIO list 388b74652f3SRagothaman Jayaraman * from IOV given by user. 389b74652f3SRagothaman Jayaraman */ 390b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 391b74652f3SRagothaman Jayaraman fill_sg_comp_from_iov(sg_comp_t *list, 392b74652f3SRagothaman Jayaraman uint32_t i, 393b74652f3SRagothaman Jayaraman iov_ptr_t *from, uint32_t from_offset, 394b74652f3SRagothaman Jayaraman uint32_t *psize, buf_ptr_t *extra_buf, 395b74652f3SRagothaman Jayaraman uint32_t extra_offset) 396b74652f3SRagothaman Jayaraman { 397b74652f3SRagothaman Jayaraman int32_t j; 398b74652f3SRagothaman Jayaraman uint32_t extra_len = extra_buf ? extra_buf->size : 0; 3990022ae1eSArchana Muniganti uint32_t size = *psize; 400b74652f3SRagothaman Jayaraman 401b74652f3SRagothaman Jayaraman for (j = 0; (j < from->buf_cnt) && size; j++) { 4023aa16821SAnkur Dwivedi phys_addr_t dma_addr = from->bufs[j].dma_addr; 4033aa16821SAnkur Dwivedi uint32_t buf_sz = from->bufs[j].size; 4043aa16821SAnkur Dwivedi sg_comp_t *to = &list[i >> 2]; 405b74652f3SRagothaman Jayaraman phys_addr_t e_dma_addr; 406b74652f3SRagothaman Jayaraman uint32_t e_len; 407b74652f3SRagothaman Jayaraman 408b74652f3SRagothaman Jayaraman if (unlikely(from_offset)) { 4093aa16821SAnkur Dwivedi if (from_offset >= buf_sz) { 4103aa16821SAnkur Dwivedi from_offset -= buf_sz; 411b74652f3SRagothaman Jayaraman continue; 412b74652f3SRagothaman Jayaraman } 4133aa16821SAnkur Dwivedi e_dma_addr = dma_addr + from_offset; 4143aa16821SAnkur Dwivedi e_len = (size > (buf_sz - from_offset)) ? 4153aa16821SAnkur Dwivedi (buf_sz - from_offset) : size; 416b74652f3SRagothaman Jayaraman from_offset = 0; 417b74652f3SRagothaman Jayaraman } else { 4183aa16821SAnkur Dwivedi e_dma_addr = dma_addr; 4193aa16821SAnkur Dwivedi e_len = (size > buf_sz) ? buf_sz : size; 420b74652f3SRagothaman Jayaraman } 421b74652f3SRagothaman Jayaraman 422b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 423b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr); 424b74652f3SRagothaman Jayaraman 425b74652f3SRagothaman Jayaraman if (extra_len && (e_len >= extra_offset)) { 426b74652f3SRagothaman Jayaraman /* Break the data at given offset */ 427b74652f3SRagothaman Jayaraman uint32_t next_len = e_len - extra_offset; 428b74652f3SRagothaman Jayaraman phys_addr_t next_dma = e_dma_addr + extra_offset; 429b74652f3SRagothaman Jayaraman 430b74652f3SRagothaman Jayaraman if (!extra_offset) { 431b74652f3SRagothaman Jayaraman i--; 432b74652f3SRagothaman Jayaraman } else { 433b74652f3SRagothaman Jayaraman e_len = extra_offset; 434b74652f3SRagothaman Jayaraman size -= e_len; 435b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 436b74652f3SRagothaman Jayaraman } 437b74652f3SRagothaman Jayaraman 4380022ae1eSArchana Muniganti extra_len = RTE_MIN(extra_len, size); 439b74652f3SRagothaman Jayaraman /* Insert extra data ptr */ 440b74652f3SRagothaman Jayaraman if (extra_len) { 441b74652f3SRagothaman Jayaraman i++; 442b74652f3SRagothaman Jayaraman to = &list[i >> 2]; 443b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = 4440022ae1eSArchana Muniganti rte_cpu_to_be_16(extra_len); 445b74652f3SRagothaman Jayaraman to->ptr[i % 4] = 446b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(extra_buf->dma_addr); 4470022ae1eSArchana Muniganti size -= extra_len; 448b74652f3SRagothaman Jayaraman } 449b74652f3SRagothaman Jayaraman 4500022ae1eSArchana Muniganti next_len = RTE_MIN(next_len, size); 451b74652f3SRagothaman Jayaraman /* insert the rest of the data */ 452b74652f3SRagothaman Jayaraman if (next_len) { 453b74652f3SRagothaman Jayaraman i++; 454b74652f3SRagothaman Jayaraman to = &list[i >> 2]; 455b74652f3SRagothaman Jayaraman to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len); 456b74652f3SRagothaman Jayaraman to->ptr[i % 4] = rte_cpu_to_be_64(next_dma); 457b74652f3SRagothaman Jayaraman size -= next_len; 458b74652f3SRagothaman Jayaraman } 459b74652f3SRagothaman Jayaraman extra_len = 0; 460b74652f3SRagothaman Jayaraman 461b74652f3SRagothaman Jayaraman } else { 462b74652f3SRagothaman Jayaraman size -= e_len; 463b74652f3SRagothaman Jayaraman } 464b74652f3SRagothaman Jayaraman if (extra_offset) 465b74652f3SRagothaman Jayaraman extra_offset -= size; 466b74652f3SRagothaman Jayaraman i++; 467b74652f3SRagothaman Jayaraman } 468b74652f3SRagothaman Jayaraman 469b74652f3SRagothaman Jayaraman *psize = size; 470b74652f3SRagothaman Jayaraman return (uint32_t)i; 471b74652f3SRagothaman Jayaraman } 472b74652f3SRagothaman Jayaraman 473f39928e6SAnoob Joseph static __rte_always_inline void 474351fbee2SSrisivasubramanian S cpt_digest_gen_prep(uint32_t flags, 475351fbee2SSrisivasubramanian S uint64_t d_lens, 476351fbee2SSrisivasubramanian S digest_params_t *params, 477351fbee2SSrisivasubramanian S void *op, 478351fbee2SSrisivasubramanian S void **prep_req) 479351fbee2SSrisivasubramanian S { 480351fbee2SSrisivasubramanian S struct cpt_request_info *req; 481351fbee2SSrisivasubramanian S uint32_t size, i; 482351fbee2SSrisivasubramanian S uint16_t data_len, mac_len, key_len; 483351fbee2SSrisivasubramanian S auth_type_t hash_type; 484351fbee2SSrisivasubramanian S buf_ptr_t *meta_p; 485351fbee2SSrisivasubramanian S struct cpt_ctx *ctx; 486351fbee2SSrisivasubramanian S sg_comp_t *gather_comp; 487351fbee2SSrisivasubramanian S sg_comp_t *scatter_comp; 488351fbee2SSrisivasubramanian S uint8_t *in_buffer; 489351fbee2SSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 490351fbee2SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 491351fbee2SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 492351fbee2SSrisivasubramanian S void *c_vaddr, *m_vaddr; 493351fbee2SSrisivasubramanian S uint64_t c_dma, m_dma; 494351fbee2SSrisivasubramanian S 495351fbee2SSrisivasubramanian S ctx = params->ctx_buf.vaddr; 496351fbee2SSrisivasubramanian S meta_p = ¶ms->meta_buf; 497351fbee2SSrisivasubramanian S 498351fbee2SSrisivasubramanian S m_vaddr = meta_p->vaddr; 499351fbee2SSrisivasubramanian S m_dma = meta_p->dma_addr; 500351fbee2SSrisivasubramanian S 501351fbee2SSrisivasubramanian S /* 502351fbee2SSrisivasubramanian S * Save initial space that followed app data for completion code & 503351fbee2SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 504351fbee2SSrisivasubramanian S */ 505351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 506351fbee2SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 507351fbee2SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 508351fbee2SSrisivasubramanian S (uint8_t *)m_vaddr; 509351fbee2SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 510351fbee2SSrisivasubramanian S c_dma = m_dma + size; 511351fbee2SSrisivasubramanian S size += sizeof(cpt_res_s_t); 512351fbee2SSrisivasubramanian S 513351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 514351fbee2SSrisivasubramanian S m_dma += size; 515351fbee2SSrisivasubramanian S 516351fbee2SSrisivasubramanian S req = m_vaddr; 517351fbee2SSrisivasubramanian S 518351fbee2SSrisivasubramanian S size = sizeof(struct cpt_request_info); 519351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 520351fbee2SSrisivasubramanian S m_dma += size; 521351fbee2SSrisivasubramanian S 522351fbee2SSrisivasubramanian S hash_type = ctx->hash_type; 523351fbee2SSrisivasubramanian S mac_len = ctx->mac_len; 524351fbee2SSrisivasubramanian S key_len = ctx->auth_key_len; 525351fbee2SSrisivasubramanian S data_len = AUTH_DLEN(d_lens); 526351fbee2SSrisivasubramanian S 527351fbee2SSrisivasubramanian S /*GP op header */ 528629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = 0; 5298d8afdecSTejasree Kondoj vq_cmd_w0.s.param2 = ((uint16_t)hash_type << 8) | mac_len; 530351fbee2SSrisivasubramanian S if (ctx->hmac) { 531629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_HMAC | CPT_DMA_MODE; 532426af86bSAnoob Joseph vq_cmd_w0.s.param1 = key_len; 533ecd070acSArchana Muniganti vq_cmd_w0.s.dlen = data_len + RTE_ALIGN_CEIL(key_len, 8); 534351fbee2SSrisivasubramanian S } else { 535629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_HASH | CPT_DMA_MODE; 536351fbee2SSrisivasubramanian S vq_cmd_w0.s.param1 = 0; 537426af86bSAnoob Joseph vq_cmd_w0.s.dlen = data_len; 538351fbee2SSrisivasubramanian S } 539351fbee2SSrisivasubramanian S 540351fbee2SSrisivasubramanian S /* Null auth only case enters the if */ 541351fbee2SSrisivasubramanian S if (unlikely(!hash_type && !ctx->enc_cipher)) { 542629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MISC; 543351fbee2SSrisivasubramanian S /* Minor op is passthrough */ 544629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = 0x03; 545351fbee2SSrisivasubramanian S /* Send out completion code only */ 546426af86bSAnoob Joseph vq_cmd_w0.s.param2 = 0x1; 547351fbee2SSrisivasubramanian S } 548351fbee2SSrisivasubramanian S 549351fbee2SSrisivasubramanian S /* DPTR has SG list */ 550351fbee2SSrisivasubramanian S in_buffer = m_vaddr; 551351fbee2SSrisivasubramanian S dptr_dma = m_dma; 552351fbee2SSrisivasubramanian S 553351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 554351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 555351fbee2SSrisivasubramanian S 556351fbee2SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 557351fbee2SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 558351fbee2SSrisivasubramanian S 559351fbee2SSrisivasubramanian S /* 560351fbee2SSrisivasubramanian S * Input gather list 561351fbee2SSrisivasubramanian S */ 562351fbee2SSrisivasubramanian S 563351fbee2SSrisivasubramanian S i = 0; 564351fbee2SSrisivasubramanian S 565351fbee2SSrisivasubramanian S if (ctx->hmac) { 566db06451bSAnoob Joseph uint64_t k_dma = ctx->auth_key_iova; 567351fbee2SSrisivasubramanian S /* Key */ 568ecd070acSArchana Muniganti i = fill_sg_comp(gather_comp, i, k_dma, 569ecd070acSArchana Muniganti RTE_ALIGN_CEIL(key_len, 8)); 570351fbee2SSrisivasubramanian S } 571351fbee2SSrisivasubramanian S 572351fbee2SSrisivasubramanian S /* input data */ 573351fbee2SSrisivasubramanian S size = data_len; 574351fbee2SSrisivasubramanian S if (size) { 575351fbee2SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 576351fbee2SSrisivasubramanian S 0, &size, NULL, 0); 577f39928e6SAnoob Joseph if (unlikely(size)) { 578351fbee2SSrisivasubramanian S CPT_LOG_DP_DEBUG("Insufficient dst IOV size, short" 579351fbee2SSrisivasubramanian S " by %dB", size); 580f39928e6SAnoob Joseph return; 581351fbee2SSrisivasubramanian S } 582351fbee2SSrisivasubramanian S } else { 583351fbee2SSrisivasubramanian S /* 584351fbee2SSrisivasubramanian S * Looks like we need to support zero data 585351fbee2SSrisivasubramanian S * gather ptr in case of hash & hmac 586351fbee2SSrisivasubramanian S */ 587351fbee2SSrisivasubramanian S i++; 588351fbee2SSrisivasubramanian S } 589351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 590351fbee2SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 591351fbee2SSrisivasubramanian S 592351fbee2SSrisivasubramanian S /* 593351fbee2SSrisivasubramanian S * Output Gather list 594351fbee2SSrisivasubramanian S */ 595351fbee2SSrisivasubramanian S 596351fbee2SSrisivasubramanian S i = 0; 597351fbee2SSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 598351fbee2SSrisivasubramanian S 599351fbee2SSrisivasubramanian S if (flags & VALID_MAC_BUF) { 600f39928e6SAnoob Joseph if (unlikely(params->mac_buf.size < mac_len)) { 601f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient MAC size"); 602f39928e6SAnoob Joseph return; 603f39928e6SAnoob Joseph } 604351fbee2SSrisivasubramanian S 605351fbee2SSrisivasubramanian S size = mac_len; 606351fbee2SSrisivasubramanian S i = fill_sg_comp_from_buf_min(scatter_comp, i, 607351fbee2SSrisivasubramanian S ¶ms->mac_buf, &size); 608351fbee2SSrisivasubramanian S } else { 609351fbee2SSrisivasubramanian S size = mac_len; 610351fbee2SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 611351fbee2SSrisivasubramanian S params->src_iov, data_len, 612351fbee2SSrisivasubramanian S &size, NULL, 0); 613f39928e6SAnoob Joseph if (unlikely(size)) { 614f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient dst IOV size, short by" 615351fbee2SSrisivasubramanian S " %dB", size); 616f39928e6SAnoob Joseph return; 617351fbee2SSrisivasubramanian S } 618351fbee2SSrisivasubramanian S } 619351fbee2SSrisivasubramanian S 620351fbee2SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 621351fbee2SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 622351fbee2SSrisivasubramanian S 623351fbee2SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 624351fbee2SSrisivasubramanian S 625351fbee2SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 626426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 627351fbee2SSrisivasubramanian S 628351fbee2SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 629351fbee2SSrisivasubramanian S m_dma += size; 630351fbee2SSrisivasubramanian S 631351fbee2SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 632351fbee2SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 633351fbee2SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 634351fbee2SSrisivasubramanian S rptr_dma = c_dma - 8; 635351fbee2SSrisivasubramanian S 636351fbee2SSrisivasubramanian S req->ist.ei1 = dptr_dma; 637351fbee2SSrisivasubramanian S req->ist.ei2 = rptr_dma; 638351fbee2SSrisivasubramanian S 639351fbee2SSrisivasubramanian S /* 16 byte aligned cpt res address */ 640351fbee2SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 641351fbee2SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 642351fbee2SSrisivasubramanian S req->comp_baddr = c_dma; 643351fbee2SSrisivasubramanian S 644351fbee2SSrisivasubramanian S /* Fill microcode part of instruction */ 645351fbee2SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 646351fbee2SSrisivasubramanian S 647351fbee2SSrisivasubramanian S req->op = op; 648351fbee2SSrisivasubramanian S 649351fbee2SSrisivasubramanian S *prep_req = req; 650f39928e6SAnoob Joseph return; 651351fbee2SSrisivasubramanian S } 652351fbee2SSrisivasubramanian S 653f39928e6SAnoob Joseph static __rte_always_inline void 654b74652f3SRagothaman Jayaraman cpt_enc_hmac_prep(uint32_t flags, 655b74652f3SRagothaman Jayaraman uint64_t d_offs, 656b74652f3SRagothaman Jayaraman uint64_t d_lens, 657b74652f3SRagothaman Jayaraman fc_params_t *fc_params, 658b74652f3SRagothaman Jayaraman void *op, 659b74652f3SRagothaman Jayaraman void **prep_req) 660b74652f3SRagothaman Jayaraman { 661b74652f3SRagothaman Jayaraman uint32_t iv_offset = 0; 662b74652f3SRagothaman Jayaraman int32_t inputlen, outputlen, enc_dlen, auth_dlen; 663b74652f3SRagothaman Jayaraman struct cpt_ctx *cpt_ctx; 664b74652f3SRagothaman Jayaraman uint32_t cipher_type, hash_type; 665b74652f3SRagothaman Jayaraman uint32_t mac_len, size; 666b74652f3SRagothaman Jayaraman uint8_t iv_len = 16; 667b74652f3SRagothaman Jayaraman struct cpt_request_info *req; 668b74652f3SRagothaman Jayaraman buf_ptr_t *meta_p, *aad_buf = NULL; 669b74652f3SRagothaman Jayaraman uint32_t encr_offset, auth_offset; 670b74652f3SRagothaman Jayaraman uint32_t encr_data_len, auth_data_len, aad_len = 0; 671b74652f3SRagothaman Jayaraman uint32_t passthrough_len = 0; 672b74652f3SRagothaman Jayaraman void *m_vaddr, *offset_vaddr; 6736045c06aSArchana Muniganti uint64_t m_dma, offset_dma; 674b74652f3SRagothaman Jayaraman vq_cmd_word0_t vq_cmd_w0; 675b74652f3SRagothaman Jayaraman void *c_vaddr; 676b74652f3SRagothaman Jayaraman uint64_t c_dma; 677b74652f3SRagothaman Jayaraman 678b74652f3SRagothaman Jayaraman meta_p = &fc_params->meta_buf; 679b74652f3SRagothaman Jayaraman m_vaddr = meta_p->vaddr; 680b74652f3SRagothaman Jayaraman m_dma = meta_p->dma_addr; 681b74652f3SRagothaman Jayaraman 682b74652f3SRagothaman Jayaraman encr_offset = ENCR_OFFSET(d_offs); 683b74652f3SRagothaman Jayaraman auth_offset = AUTH_OFFSET(d_offs); 684b74652f3SRagothaman Jayaraman encr_data_len = ENCR_DLEN(d_lens); 685b74652f3SRagothaman Jayaraman auth_data_len = AUTH_DLEN(d_lens); 686b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 687b74652f3SRagothaman Jayaraman /* 688b74652f3SRagothaman Jayaraman * We dont support both aad 689b74652f3SRagothaman Jayaraman * and auth data separately 690b74652f3SRagothaman Jayaraman */ 691b74652f3SRagothaman Jayaraman auth_data_len = 0; 692b74652f3SRagothaman Jayaraman auth_offset = 0; 693b74652f3SRagothaman Jayaraman aad_len = fc_params->aad_buf.size; 694b74652f3SRagothaman Jayaraman aad_buf = &fc_params->aad_buf; 695b74652f3SRagothaman Jayaraman } 696b74652f3SRagothaman Jayaraman cpt_ctx = fc_params->ctx_buf.vaddr; 697b74652f3SRagothaman Jayaraman cipher_type = cpt_ctx->enc_cipher; 698b74652f3SRagothaman Jayaraman hash_type = cpt_ctx->hash_type; 699b74652f3SRagothaman Jayaraman mac_len = cpt_ctx->mac_len; 700b74652f3SRagothaman Jayaraman 701b74652f3SRagothaman Jayaraman /* 702b74652f3SRagothaman Jayaraman * Save initial space that followed app data for completion code & 703b74652f3SRagothaman Jayaraman * alternate completion code to fall in same cache line as app data 704b74652f3SRagothaman Jayaraman */ 705b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 706b74652f3SRagothaman Jayaraman m_dma += COMPLETION_CODE_SIZE; 707b74652f3SRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 708b74652f3SRagothaman Jayaraman (uint8_t *)m_vaddr; 709b74652f3SRagothaman Jayaraman 710b74652f3SRagothaman Jayaraman c_vaddr = (uint8_t *)m_vaddr + size; 711b74652f3SRagothaman Jayaraman c_dma = m_dma + size; 712b74652f3SRagothaman Jayaraman size += sizeof(cpt_res_s_t); 713b74652f3SRagothaman Jayaraman 714b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 715b74652f3SRagothaman Jayaraman m_dma += size; 716b74652f3SRagothaman Jayaraman 717b74652f3SRagothaman Jayaraman /* start cpt request info struct at 8 byte boundary */ 718b74652f3SRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 719b74652f3SRagothaman Jayaraman (uint8_t *)m_vaddr; 720b74652f3SRagothaman Jayaraman 721b74652f3SRagothaman Jayaraman req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 722b74652f3SRagothaman Jayaraman 723b74652f3SRagothaman Jayaraman size += sizeof(struct cpt_request_info); 724b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 725b74652f3SRagothaman Jayaraman m_dma += size; 726b74652f3SRagothaman Jayaraman 727b74652f3SRagothaman Jayaraman if (unlikely(!(flags & VALID_IV_BUF))) { 728b74652f3SRagothaman Jayaraman iv_len = 0; 729b74652f3SRagothaman Jayaraman iv_offset = ENCR_IV_OFFSET(d_offs); 730b74652f3SRagothaman Jayaraman } 731b74652f3SRagothaman Jayaraman 732b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 733b74652f3SRagothaman Jayaraman /* 734b74652f3SRagothaman Jayaraman * When AAD is given, data above encr_offset is pass through 735b74652f3SRagothaman Jayaraman * Since AAD is given as separate pointer and not as offset, 736b74652f3SRagothaman Jayaraman * this is a special case as we need to fragment input data 737b74652f3SRagothaman Jayaraman * into passthrough + encr_data and then insert AAD in between. 738b74652f3SRagothaman Jayaraman */ 739b74652f3SRagothaman Jayaraman if (hash_type != GMAC_TYPE) { 740b74652f3SRagothaman Jayaraman passthrough_len = encr_offset; 741b74652f3SRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 742b74652f3SRagothaman Jayaraman encr_offset = passthrough_len + aad_len + iv_len; 743b74652f3SRagothaman Jayaraman auth_data_len = aad_len + encr_data_len; 744b74652f3SRagothaman Jayaraman } else { 745b74652f3SRagothaman Jayaraman passthrough_len = 16 + aad_len; 746b74652f3SRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 747b74652f3SRagothaman Jayaraman auth_data_len = aad_len; 748b74652f3SRagothaman Jayaraman } 749b74652f3SRagothaman Jayaraman } else { 750b74652f3SRagothaman Jayaraman encr_offset += iv_len; 751b74652f3SRagothaman Jayaraman auth_offset += iv_len; 752b74652f3SRagothaman Jayaraman } 753b74652f3SRagothaman Jayaraman 754b74652f3SRagothaman Jayaraman /* Encryption */ 755629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_FC; 756de5eb0a6STejasree Kondoj vq_cmd_w0.s.opcode.minor = CPT_FC_MINOR_OP_ENCRYPT; 757de5eb0a6STejasree Kondoj vq_cmd_w0.s.opcode.minor |= (cpt_ctx->auth_enc << 758de5eb0a6STejasree Kondoj CPT_HMAC_FIRST_BIT_POS); 759b74652f3SRagothaman Jayaraman 7600058f305SAnkur Dwivedi if (hash_type == GMAC_TYPE) { 7610058f305SAnkur Dwivedi encr_offset = 0; 7620058f305SAnkur Dwivedi encr_data_len = 0; 7630058f305SAnkur Dwivedi } 7640058f305SAnkur Dwivedi 765b74652f3SRagothaman Jayaraman auth_dlen = auth_offset + auth_data_len; 766b74652f3SRagothaman Jayaraman enc_dlen = encr_data_len + encr_offset; 767b74652f3SRagothaman Jayaraman if (unlikely(encr_data_len & 0xf)) { 768b74652f3SRagothaman Jayaraman if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB)) 769ecd070acSArchana Muniganti enc_dlen = RTE_ALIGN_CEIL(encr_data_len, 8) + 770ecd070acSArchana Muniganti encr_offset; 771b74652f3SRagothaman Jayaraman else if (likely((cipher_type == AES_CBC) || 772b74652f3SRagothaman Jayaraman (cipher_type == AES_ECB))) 773ecd070acSArchana Muniganti enc_dlen = RTE_ALIGN_CEIL(encr_data_len, 8) + 774ecd070acSArchana Muniganti encr_offset; 775b74652f3SRagothaman Jayaraman } 776b74652f3SRagothaman Jayaraman 777b74652f3SRagothaman Jayaraman if (unlikely(auth_dlen > enc_dlen)) { 778b74652f3SRagothaman Jayaraman inputlen = auth_dlen; 779b74652f3SRagothaman Jayaraman outputlen = auth_dlen + mac_len; 780b74652f3SRagothaman Jayaraman } else { 781b74652f3SRagothaman Jayaraman inputlen = enc_dlen; 782b74652f3SRagothaman Jayaraman outputlen = enc_dlen + mac_len; 783b74652f3SRagothaman Jayaraman } 784b74652f3SRagothaman Jayaraman 785de5eb0a6STejasree Kondoj if (cpt_ctx->auth_enc != 0) 786de5eb0a6STejasree Kondoj outputlen = enc_dlen; 787de5eb0a6STejasree Kondoj 788b74652f3SRagothaman Jayaraman /* GP op header */ 789426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 790426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 791b74652f3SRagothaman Jayaraman /* 792b74652f3SRagothaman Jayaraman * In 83XX since we have a limitation of 793b74652f3SRagothaman Jayaraman * IV & Offset control word not part of instruction 794b74652f3SRagothaman Jayaraman * and need to be part of Data Buffer, we check if 795b74652f3SRagothaman Jayaraman * head room is there and then only do the Direct mode processing 796b74652f3SRagothaman Jayaraman */ 797b74652f3SRagothaman Jayaraman if (likely((flags & SINGLE_BUF_INPLACE) && 798b74652f3SRagothaman Jayaraman (flags & SINGLE_BUF_HEADTAILROOM))) { 799b74652f3SRagothaman Jayaraman void *dm_vaddr = fc_params->bufs[0].vaddr; 800b74652f3SRagothaman Jayaraman uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 801b74652f3SRagothaman Jayaraman /* 802b74652f3SRagothaman Jayaraman * This flag indicates that there is 24 bytes head room and 803b74652f3SRagothaman Jayaraman * 8 bytes tail room available, so that we get to do 804b74652f3SRagothaman Jayaraman * DIRECT MODE with limitation 805b74652f3SRagothaman Jayaraman */ 806b74652f3SRagothaman Jayaraman 807b74652f3SRagothaman Jayaraman offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 808b74652f3SRagothaman Jayaraman offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 809b74652f3SRagothaman Jayaraman 810b74652f3SRagothaman Jayaraman /* DPTR */ 811b74652f3SRagothaman Jayaraman req->ist.ei1 = offset_dma; 812b74652f3SRagothaman Jayaraman /* RPTR should just exclude offset control word */ 813b74652f3SRagothaman Jayaraman req->ist.ei2 = dm_dma_addr - iv_len; 814b74652f3SRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 815b74652f3SRagothaman Jayaraman + outputlen - iv_len); 816b74652f3SRagothaman Jayaraman 817426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 818b74652f3SRagothaman Jayaraman 819b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 820b74652f3SRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 821b74652f3SRagothaman Jayaraman + OFF_CTRL_LEN); 822b74652f3SRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 823b74652f3SRagothaman Jayaraman dest[0] = src[0]; 824b74652f3SRagothaman Jayaraman dest[1] = src[1]; 825b74652f3SRagothaman Jayaraman } 826b74652f3SRagothaman Jayaraman 827b74652f3SRagothaman Jayaraman *(uint64_t *)offset_vaddr = 828b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 829b74652f3SRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 830b74652f3SRagothaman Jayaraman ((uint64_t)auth_offset)); 831b74652f3SRagothaman Jayaraman 832b74652f3SRagothaman Jayaraman } else { 833b74652f3SRagothaman Jayaraman uint32_t i, g_size_bytes, s_size_bytes; 834b74652f3SRagothaman Jayaraman uint64_t dptr_dma, rptr_dma; 835b74652f3SRagothaman Jayaraman sg_comp_t *gather_comp; 836b74652f3SRagothaman Jayaraman sg_comp_t *scatter_comp; 837b74652f3SRagothaman Jayaraman uint8_t *in_buffer; 838b74652f3SRagothaman Jayaraman 839b74652f3SRagothaman Jayaraman /* This falls under strict SG mode */ 840b74652f3SRagothaman Jayaraman offset_vaddr = m_vaddr; 841b74652f3SRagothaman Jayaraman offset_dma = m_dma; 842b74652f3SRagothaman Jayaraman size = OFF_CTRL_LEN + iv_len; 843b74652f3SRagothaman Jayaraman 844b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 845b74652f3SRagothaman Jayaraman m_dma += size; 846b74652f3SRagothaman Jayaraman 847629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE; 848b74652f3SRagothaman Jayaraman 849b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 850b74652f3SRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 851b74652f3SRagothaman Jayaraman + OFF_CTRL_LEN); 852b74652f3SRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 853b74652f3SRagothaman Jayaraman dest[0] = src[0]; 854b74652f3SRagothaman Jayaraman dest[1] = src[1]; 855b74652f3SRagothaman Jayaraman } 856b74652f3SRagothaman Jayaraman 857b74652f3SRagothaman Jayaraman *(uint64_t *)offset_vaddr = 858b74652f3SRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 859b74652f3SRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 860b74652f3SRagothaman Jayaraman ((uint64_t)auth_offset)); 861b74652f3SRagothaman Jayaraman 862b74652f3SRagothaman Jayaraman /* DPTR has SG list */ 863b74652f3SRagothaman Jayaraman in_buffer = m_vaddr; 864b74652f3SRagothaman Jayaraman dptr_dma = m_dma; 865b74652f3SRagothaman Jayaraman 866b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[0] = 0; 867b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[1] = 0; 868b74652f3SRagothaman Jayaraman 869b74652f3SRagothaman Jayaraman /* TODO Add error check if space will be sufficient */ 870b74652f3SRagothaman Jayaraman gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 871b74652f3SRagothaman Jayaraman 872b74652f3SRagothaman Jayaraman /* 873b74652f3SRagothaman Jayaraman * Input Gather List 874b74652f3SRagothaman Jayaraman */ 875b74652f3SRagothaman Jayaraman 876b74652f3SRagothaman Jayaraman i = 0; 877b74652f3SRagothaman Jayaraman 878b74652f3SRagothaman Jayaraman /* Offset control word that includes iv */ 879b74652f3SRagothaman Jayaraman i = fill_sg_comp(gather_comp, i, offset_dma, 880b74652f3SRagothaman Jayaraman OFF_CTRL_LEN + iv_len); 881b74652f3SRagothaman Jayaraman 882b74652f3SRagothaman Jayaraman /* Add input data */ 883b74652f3SRagothaman Jayaraman size = inputlen - iv_len; 884b74652f3SRagothaman Jayaraman if (likely(size)) { 885b74652f3SRagothaman Jayaraman uint32_t aad_offset = aad_len ? passthrough_len : 0; 886b74652f3SRagothaman Jayaraman 887b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 888b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min(gather_comp, i, 889b74652f3SRagothaman Jayaraman fc_params->bufs, 890b74652f3SRagothaman Jayaraman &size); 891b74652f3SRagothaman Jayaraman } else { 892b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(gather_comp, i, 893b74652f3SRagothaman Jayaraman fc_params->src_iov, 894b74652f3SRagothaman Jayaraman 0, &size, 895b74652f3SRagothaman Jayaraman aad_buf, aad_offset); 896b74652f3SRagothaman Jayaraman } 897b74652f3SRagothaman Jayaraman 898b74652f3SRagothaman Jayaraman if (unlikely(size)) { 899b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Insufficient buffer space," 900b74652f3SRagothaman Jayaraman " size %d needed", size); 901f39928e6SAnoob Joseph return; 902b74652f3SRagothaman Jayaraman } 903b74652f3SRagothaman Jayaraman } 904b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 905b74652f3SRagothaman Jayaraman g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 906b74652f3SRagothaman Jayaraman 907b74652f3SRagothaman Jayaraman /* 908b74652f3SRagothaman Jayaraman * Output Scatter list 909b74652f3SRagothaman Jayaraman */ 910b74652f3SRagothaman Jayaraman i = 0; 911b74652f3SRagothaman Jayaraman scatter_comp = 912b74652f3SRagothaman Jayaraman (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 913b74652f3SRagothaman Jayaraman 914b74652f3SRagothaman Jayaraman /* Add IV */ 915b74652f3SRagothaman Jayaraman if (likely(iv_len)) { 916b74652f3SRagothaman Jayaraman i = fill_sg_comp(scatter_comp, i, 917b74652f3SRagothaman Jayaraman offset_dma + OFF_CTRL_LEN, 918b74652f3SRagothaman Jayaraman iv_len); 919b74652f3SRagothaman Jayaraman } 920b74652f3SRagothaman Jayaraman 921b74652f3SRagothaman Jayaraman /* output data or output data + digest*/ 922b74652f3SRagothaman Jayaraman if (unlikely(flags & VALID_MAC_BUF)) { 923b74652f3SRagothaman Jayaraman size = outputlen - iv_len - mac_len; 924b74652f3SRagothaman Jayaraman if (size) { 925b74652f3SRagothaman Jayaraman uint32_t aad_offset = 926b74652f3SRagothaman Jayaraman aad_len ? passthrough_len : 0; 927b74652f3SRagothaman Jayaraman 928b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 929b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 930b74652f3SRagothaman Jayaraman scatter_comp, 931b74652f3SRagothaman Jayaraman i, 932b74652f3SRagothaman Jayaraman fc_params->bufs, 933b74652f3SRagothaman Jayaraman &size); 934b74652f3SRagothaman Jayaraman } else { 935b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, 936b74652f3SRagothaman Jayaraman i, 937b74652f3SRagothaman Jayaraman fc_params->dst_iov, 938b74652f3SRagothaman Jayaraman 0, 939b74652f3SRagothaman Jayaraman &size, 940b74652f3SRagothaman Jayaraman aad_buf, 941b74652f3SRagothaman Jayaraman aad_offset); 942b74652f3SRagothaman Jayaraman } 943f39928e6SAnoob Joseph if (unlikely(size)) { 944f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 945f39928e6SAnoob Joseph " space, size %d needed", 946f39928e6SAnoob Joseph size); 947f39928e6SAnoob Joseph return; 948f39928e6SAnoob Joseph } 949b74652f3SRagothaman Jayaraman } 950b74652f3SRagothaman Jayaraman /* mac_data */ 951b74652f3SRagothaman Jayaraman if (mac_len) { 952b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf(scatter_comp, i, 953b74652f3SRagothaman Jayaraman &fc_params->mac_buf); 954b74652f3SRagothaman Jayaraman } 955b74652f3SRagothaman Jayaraman } else { 956b74652f3SRagothaman Jayaraman /* Output including mac */ 957b74652f3SRagothaman Jayaraman size = outputlen - iv_len; 958b74652f3SRagothaman Jayaraman if (likely(size)) { 959b74652f3SRagothaman Jayaraman uint32_t aad_offset = 960b74652f3SRagothaman Jayaraman aad_len ? passthrough_len : 0; 961b74652f3SRagothaman Jayaraman 962b74652f3SRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 963b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 964b74652f3SRagothaman Jayaraman scatter_comp, 965b74652f3SRagothaman Jayaraman i, 966b74652f3SRagothaman Jayaraman fc_params->bufs, 967b74652f3SRagothaman Jayaraman &size); 968b74652f3SRagothaman Jayaraman } else { 969b74652f3SRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, 970b74652f3SRagothaman Jayaraman i, 971b74652f3SRagothaman Jayaraman fc_params->dst_iov, 972b74652f3SRagothaman Jayaraman 0, 973b74652f3SRagothaman Jayaraman &size, 974b74652f3SRagothaman Jayaraman aad_buf, 975b74652f3SRagothaman Jayaraman aad_offset); 976b74652f3SRagothaman Jayaraman } 977b74652f3SRagothaman Jayaraman if (unlikely(size)) { 978b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Insufficient buffer" 979b74652f3SRagothaman Jayaraman " space, size %d needed", 980b74652f3SRagothaman Jayaraman size); 981f39928e6SAnoob Joseph return; 982b74652f3SRagothaman Jayaraman } 983b74652f3SRagothaman Jayaraman } 984b74652f3SRagothaman Jayaraman } 985b74652f3SRagothaman Jayaraman ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 986b74652f3SRagothaman Jayaraman s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 987b74652f3SRagothaman Jayaraman 988b74652f3SRagothaman Jayaraman size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 989b74652f3SRagothaman Jayaraman 990b74652f3SRagothaman Jayaraman /* This is DPTR len incase of SG mode */ 991426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 992b74652f3SRagothaman Jayaraman 993b74652f3SRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 994b74652f3SRagothaman Jayaraman m_dma += size; 995b74652f3SRagothaman Jayaraman 996b74652f3SRagothaman Jayaraman /* cpt alternate completion address saved earlier */ 997b74652f3SRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 998b74652f3SRagothaman Jayaraman *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 999b74652f3SRagothaman Jayaraman rptr_dma = c_dma - 8; 1000b74652f3SRagothaman Jayaraman 1001b74652f3SRagothaman Jayaraman req->ist.ei1 = dptr_dma; 1002b74652f3SRagothaman Jayaraman req->ist.ei2 = rptr_dma; 1003b74652f3SRagothaman Jayaraman } 1004b74652f3SRagothaman Jayaraman 10052a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16) || 10062a6c7922SAnoob Joseph (iv_offset >> 8) || 10072a6c7922SAnoob Joseph (auth_offset >> 8))) { 10082a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 10092a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 10102a6c7922SAnoob Joseph CPT_LOG_DP_ERR("iv_offset : %d", iv_offset); 10112a6c7922SAnoob Joseph CPT_LOG_DP_ERR("auth_offset: %d", auth_offset); 10122a6c7922SAnoob Joseph return; 10132a6c7922SAnoob Joseph } 10142a6c7922SAnoob Joseph 1015b74652f3SRagothaman Jayaraman /* 16 byte aligned cpt res address */ 1016b74652f3SRagothaman Jayaraman req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1017b74652f3SRagothaman Jayaraman *req->completion_addr = COMPLETION_CODE_INIT; 1018b74652f3SRagothaman Jayaraman req->comp_baddr = c_dma; 1019b74652f3SRagothaman Jayaraman 1020b74652f3SRagothaman Jayaraman /* Fill microcode part of instruction */ 1021b74652f3SRagothaman Jayaraman req->ist.ei0 = vq_cmd_w0.u64; 1022b74652f3SRagothaman Jayaraman 1023b74652f3SRagothaman Jayaraman req->op = op; 1024b74652f3SRagothaman Jayaraman 1025b74652f3SRagothaman Jayaraman *prep_req = req; 1026f39928e6SAnoob Joseph return; 1027b74652f3SRagothaman Jayaraman } 1028b74652f3SRagothaman Jayaraman 1029f39928e6SAnoob Joseph static __rte_always_inline void 1030177b41ceSRagothaman Jayaraman cpt_dec_hmac_prep(uint32_t flags, 1031177b41ceSRagothaman Jayaraman uint64_t d_offs, 1032177b41ceSRagothaman Jayaraman uint64_t d_lens, 1033177b41ceSRagothaman Jayaraman fc_params_t *fc_params, 1034177b41ceSRagothaman Jayaraman void *op, 1035177b41ceSRagothaman Jayaraman void **prep_req) 1036177b41ceSRagothaman Jayaraman { 1037177b41ceSRagothaman Jayaraman uint32_t iv_offset = 0, size; 1038177b41ceSRagothaman Jayaraman int32_t inputlen, outputlen, enc_dlen, auth_dlen; 1039177b41ceSRagothaman Jayaraman struct cpt_ctx *cpt_ctx; 10408de5ede7SAnoob Joseph int32_t hash_type, mac_len; 1041177b41ceSRagothaman Jayaraman uint8_t iv_len = 16; 1042177b41ceSRagothaman Jayaraman struct cpt_request_info *req; 1043177b41ceSRagothaman Jayaraman buf_ptr_t *meta_p, *aad_buf = NULL; 1044177b41ceSRagothaman Jayaraman uint32_t encr_offset, auth_offset; 1045177b41ceSRagothaman Jayaraman uint32_t encr_data_len, auth_data_len, aad_len = 0; 1046177b41ceSRagothaman Jayaraman uint32_t passthrough_len = 0; 1047177b41ceSRagothaman Jayaraman void *m_vaddr, *offset_vaddr; 10486045c06aSArchana Muniganti uint64_t m_dma, offset_dma; 1049177b41ceSRagothaman Jayaraman vq_cmd_word0_t vq_cmd_w0; 1050177b41ceSRagothaman Jayaraman void *c_vaddr; 1051177b41ceSRagothaman Jayaraman uint64_t c_dma; 1052177b41ceSRagothaman Jayaraman 1053177b41ceSRagothaman Jayaraman meta_p = &fc_params->meta_buf; 1054177b41ceSRagothaman Jayaraman m_vaddr = meta_p->vaddr; 1055177b41ceSRagothaman Jayaraman m_dma = meta_p->dma_addr; 1056177b41ceSRagothaman Jayaraman 1057177b41ceSRagothaman Jayaraman encr_offset = ENCR_OFFSET(d_offs); 1058177b41ceSRagothaman Jayaraman auth_offset = AUTH_OFFSET(d_offs); 1059177b41ceSRagothaman Jayaraman encr_data_len = ENCR_DLEN(d_lens); 1060177b41ceSRagothaman Jayaraman auth_data_len = AUTH_DLEN(d_lens); 1061177b41ceSRagothaman Jayaraman 1062177b41ceSRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 1063177b41ceSRagothaman Jayaraman /* 1064177b41ceSRagothaman Jayaraman * We dont support both aad 1065177b41ceSRagothaman Jayaraman * and auth data separately 1066177b41ceSRagothaman Jayaraman */ 1067177b41ceSRagothaman Jayaraman auth_data_len = 0; 1068177b41ceSRagothaman Jayaraman auth_offset = 0; 1069177b41ceSRagothaman Jayaraman aad_len = fc_params->aad_buf.size; 1070177b41ceSRagothaman Jayaraman aad_buf = &fc_params->aad_buf; 1071177b41ceSRagothaman Jayaraman } 1072177b41ceSRagothaman Jayaraman 1073177b41ceSRagothaman Jayaraman cpt_ctx = fc_params->ctx_buf.vaddr; 1074177b41ceSRagothaman Jayaraman hash_type = cpt_ctx->hash_type; 1075177b41ceSRagothaman Jayaraman mac_len = cpt_ctx->mac_len; 1076177b41ceSRagothaman Jayaraman 1077177b41ceSRagothaman Jayaraman if (unlikely(!(flags & VALID_IV_BUF))) { 1078177b41ceSRagothaman Jayaraman iv_len = 0; 1079177b41ceSRagothaman Jayaraman iv_offset = ENCR_IV_OFFSET(d_offs); 1080177b41ceSRagothaman Jayaraman } 1081177b41ceSRagothaman Jayaraman 1082177b41ceSRagothaman Jayaraman if (unlikely(flags & VALID_AAD_BUF)) { 1083177b41ceSRagothaman Jayaraman /* 1084177b41ceSRagothaman Jayaraman * When AAD is given, data above encr_offset is pass through 1085177b41ceSRagothaman Jayaraman * Since AAD is given as separate pointer and not as offset, 1086177b41ceSRagothaman Jayaraman * this is a special case as we need to fragment input data 1087177b41ceSRagothaman Jayaraman * into passthrough + encr_data and then insert AAD in between. 1088177b41ceSRagothaman Jayaraman */ 1089177b41ceSRagothaman Jayaraman if (hash_type != GMAC_TYPE) { 1090177b41ceSRagothaman Jayaraman passthrough_len = encr_offset; 1091177b41ceSRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 1092177b41ceSRagothaman Jayaraman encr_offset = passthrough_len + aad_len + iv_len; 1093177b41ceSRagothaman Jayaraman auth_data_len = aad_len + encr_data_len; 1094177b41ceSRagothaman Jayaraman } else { 1095177b41ceSRagothaman Jayaraman passthrough_len = 16 + aad_len; 1096177b41ceSRagothaman Jayaraman auth_offset = passthrough_len + iv_len; 1097177b41ceSRagothaman Jayaraman auth_data_len = aad_len; 1098177b41ceSRagothaman Jayaraman } 1099177b41ceSRagothaman Jayaraman } else { 1100177b41ceSRagothaman Jayaraman encr_offset += iv_len; 1101177b41ceSRagothaman Jayaraman auth_offset += iv_len; 1102177b41ceSRagothaman Jayaraman } 1103177b41ceSRagothaman Jayaraman 1104177b41ceSRagothaman Jayaraman /* 1105177b41ceSRagothaman Jayaraman * Save initial space that followed app data for completion code & 1106177b41ceSRagothaman Jayaraman * alternate completion code to fall in same cache line as app data 1107177b41ceSRagothaman Jayaraman */ 1108177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 1109177b41ceSRagothaman Jayaraman m_dma += COMPLETION_CODE_SIZE; 1110177b41ceSRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 1111177b41ceSRagothaman Jayaraman (uint8_t *)m_vaddr; 1112177b41ceSRagothaman Jayaraman c_vaddr = (uint8_t *)m_vaddr + size; 1113177b41ceSRagothaman Jayaraman c_dma = m_dma + size; 1114177b41ceSRagothaman Jayaraman size += sizeof(cpt_res_s_t); 1115177b41ceSRagothaman Jayaraman 1116177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1117177b41ceSRagothaman Jayaraman m_dma += size; 1118177b41ceSRagothaman Jayaraman 1119177b41ceSRagothaman Jayaraman /* start cpt request info structure at 8 byte alignment */ 1120177b41ceSRagothaman Jayaraman size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 1121177b41ceSRagothaman Jayaraman (uint8_t *)m_vaddr; 1122177b41ceSRagothaman Jayaraman 1123177b41ceSRagothaman Jayaraman req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 1124177b41ceSRagothaman Jayaraman 1125177b41ceSRagothaman Jayaraman size += sizeof(struct cpt_request_info); 1126177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1127177b41ceSRagothaman Jayaraman m_dma += size; 1128177b41ceSRagothaman Jayaraman 1129177b41ceSRagothaman Jayaraman /* Decryption */ 1130629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_FC; 1131de5eb0a6STejasree Kondoj vq_cmd_w0.s.opcode.minor = CPT_FC_MINOR_OP_DECRYPT; 1132de5eb0a6STejasree Kondoj vq_cmd_w0.s.opcode.minor |= (cpt_ctx->dec_auth << 1133de5eb0a6STejasree Kondoj CPT_HMAC_FIRST_BIT_POS); 1134177b41ceSRagothaman Jayaraman 11350058f305SAnkur Dwivedi if (hash_type == GMAC_TYPE) { 11360058f305SAnkur Dwivedi encr_offset = 0; 11370058f305SAnkur Dwivedi encr_data_len = 0; 11380058f305SAnkur Dwivedi } 11390058f305SAnkur Dwivedi 1140177b41ceSRagothaman Jayaraman enc_dlen = encr_offset + encr_data_len; 1141177b41ceSRagothaman Jayaraman auth_dlen = auth_offset + auth_data_len; 1142177b41ceSRagothaman Jayaraman 1143177b41ceSRagothaman Jayaraman if (auth_dlen > enc_dlen) { 1144177b41ceSRagothaman Jayaraman inputlen = auth_dlen + mac_len; 1145177b41ceSRagothaman Jayaraman outputlen = auth_dlen; 1146177b41ceSRagothaman Jayaraman } else { 1147177b41ceSRagothaman Jayaraman inputlen = enc_dlen + mac_len; 1148177b41ceSRagothaman Jayaraman outputlen = enc_dlen; 1149177b41ceSRagothaman Jayaraman } 1150177b41ceSRagothaman Jayaraman 1151de5eb0a6STejasree Kondoj if (cpt_ctx->dec_auth != 0) 1152de5eb0a6STejasree Kondoj outputlen = inputlen = enc_dlen; 1153de5eb0a6STejasree Kondoj 1154426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 1155426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 1156177b41ceSRagothaman Jayaraman 1157177b41ceSRagothaman Jayaraman /* 1158177b41ceSRagothaman Jayaraman * In 83XX since we have a limitation of 1159177b41ceSRagothaman Jayaraman * IV & Offset control word not part of instruction 1160177b41ceSRagothaman Jayaraman * and need to be part of Data Buffer, we check if 1161177b41ceSRagothaman Jayaraman * head room is there and then only do the Direct mode processing 1162177b41ceSRagothaman Jayaraman */ 1163177b41ceSRagothaman Jayaraman if (likely((flags & SINGLE_BUF_INPLACE) && 1164177b41ceSRagothaman Jayaraman (flags & SINGLE_BUF_HEADTAILROOM))) { 1165177b41ceSRagothaman Jayaraman void *dm_vaddr = fc_params->bufs[0].vaddr; 1166177b41ceSRagothaman Jayaraman uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 1167177b41ceSRagothaman Jayaraman /* 1168177b41ceSRagothaman Jayaraman * This flag indicates that there is 24 bytes head room and 1169177b41ceSRagothaman Jayaraman * 8 bytes tail room available, so that we get to do 1170177b41ceSRagothaman Jayaraman * DIRECT MODE with limitation 1171177b41ceSRagothaman Jayaraman */ 1172177b41ceSRagothaman Jayaraman 1173177b41ceSRagothaman Jayaraman offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 1174177b41ceSRagothaman Jayaraman offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 1175177b41ceSRagothaman Jayaraman req->ist.ei1 = offset_dma; 1176177b41ceSRagothaman Jayaraman 1177177b41ceSRagothaman Jayaraman /* RPTR should just exclude offset control word */ 1178177b41ceSRagothaman Jayaraman req->ist.ei2 = dm_dma_addr - iv_len; 1179177b41ceSRagothaman Jayaraman 1180177b41ceSRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr + 1181177b41ceSRagothaman Jayaraman outputlen - iv_len); 1182177b41ceSRagothaman Jayaraman /* since this is decryption, 1183177b41ceSRagothaman Jayaraman * don't touch the content of 1184177b41ceSRagothaman Jayaraman * alternate ccode space as it contains 1185177b41ceSRagothaman Jayaraman * hmac. 1186177b41ceSRagothaman Jayaraman */ 1187177b41ceSRagothaman Jayaraman 1188426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 1189177b41ceSRagothaman Jayaraman 1190177b41ceSRagothaman Jayaraman if (likely(iv_len)) { 1191177b41ceSRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1192177b41ceSRagothaman Jayaraman OFF_CTRL_LEN); 1193177b41ceSRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 1194177b41ceSRagothaman Jayaraman dest[0] = src[0]; 1195177b41ceSRagothaman Jayaraman dest[1] = src[1]; 1196177b41ceSRagothaman Jayaraman } 1197177b41ceSRagothaman Jayaraman 11982a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16) || 11992a6c7922SAnoob Joseph (iv_offset >> 8) || 12002a6c7922SAnoob Joseph (auth_offset >> 8))) { 12012a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 12022a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 12032a6c7922SAnoob Joseph CPT_LOG_DP_ERR("iv_offset : %d", iv_offset); 12042a6c7922SAnoob Joseph CPT_LOG_DP_ERR("auth_offset: %d", auth_offset); 12052a6c7922SAnoob Joseph return; 12062a6c7922SAnoob Joseph } 12072a6c7922SAnoob Joseph 1208177b41ceSRagothaman Jayaraman *(uint64_t *)offset_vaddr = 1209177b41ceSRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1210177b41ceSRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 1211177b41ceSRagothaman Jayaraman ((uint64_t)auth_offset)); 1212177b41ceSRagothaman Jayaraman 1213177b41ceSRagothaman Jayaraman } else { 1214177b41ceSRagothaman Jayaraman uint64_t dptr_dma, rptr_dma; 1215177b41ceSRagothaman Jayaraman uint32_t g_size_bytes, s_size_bytes; 1216177b41ceSRagothaman Jayaraman sg_comp_t *gather_comp; 1217177b41ceSRagothaman Jayaraman sg_comp_t *scatter_comp; 1218177b41ceSRagothaman Jayaraman uint8_t *in_buffer; 1219177b41ceSRagothaman Jayaraman uint8_t i = 0; 1220177b41ceSRagothaman Jayaraman 1221177b41ceSRagothaman Jayaraman /* This falls under strict SG mode */ 1222177b41ceSRagothaman Jayaraman offset_vaddr = m_vaddr; 1223177b41ceSRagothaman Jayaraman offset_dma = m_dma; 1224177b41ceSRagothaman Jayaraman size = OFF_CTRL_LEN + iv_len; 1225177b41ceSRagothaman Jayaraman 1226177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1227177b41ceSRagothaman Jayaraman m_dma += size; 1228177b41ceSRagothaman Jayaraman 1229629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE; 1230177b41ceSRagothaman Jayaraman 1231177b41ceSRagothaman Jayaraman if (likely(iv_len)) { 1232177b41ceSRagothaman Jayaraman uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1233177b41ceSRagothaman Jayaraman OFF_CTRL_LEN); 1234177b41ceSRagothaman Jayaraman uint64_t *src = fc_params->iv_buf; 1235177b41ceSRagothaman Jayaraman dest[0] = src[0]; 1236177b41ceSRagothaman Jayaraman dest[1] = src[1]; 1237177b41ceSRagothaman Jayaraman } 1238177b41ceSRagothaman Jayaraman 12392a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16) || 12402a6c7922SAnoob Joseph (iv_offset >> 8) || 12412a6c7922SAnoob Joseph (auth_offset >> 8))) { 12422a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 12432a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 12442a6c7922SAnoob Joseph CPT_LOG_DP_ERR("iv_offset : %d", iv_offset); 12452a6c7922SAnoob Joseph CPT_LOG_DP_ERR("auth_offset: %d", auth_offset); 12462a6c7922SAnoob Joseph return; 12472a6c7922SAnoob Joseph } 12482a6c7922SAnoob Joseph 1249177b41ceSRagothaman Jayaraman *(uint64_t *)offset_vaddr = 1250177b41ceSRagothaman Jayaraman rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1251177b41ceSRagothaman Jayaraman ((uint64_t)iv_offset << 8) | 1252177b41ceSRagothaman Jayaraman ((uint64_t)auth_offset)); 1253177b41ceSRagothaman Jayaraman 1254177b41ceSRagothaman Jayaraman /* DPTR has SG list */ 1255177b41ceSRagothaman Jayaraman in_buffer = m_vaddr; 1256177b41ceSRagothaman Jayaraman dptr_dma = m_dma; 1257177b41ceSRagothaman Jayaraman 1258177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[0] = 0; 1259177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[1] = 0; 1260177b41ceSRagothaman Jayaraman 1261177b41ceSRagothaman Jayaraman /* TODO Add error check if space will be sufficient */ 1262177b41ceSRagothaman Jayaraman gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 1263177b41ceSRagothaman Jayaraman 1264177b41ceSRagothaman Jayaraman /* 1265177b41ceSRagothaman Jayaraman * Input Gather List 1266177b41ceSRagothaman Jayaraman */ 1267177b41ceSRagothaman Jayaraman i = 0; 1268177b41ceSRagothaman Jayaraman 1269177b41ceSRagothaman Jayaraman /* Offset control word that includes iv */ 1270177b41ceSRagothaman Jayaraman i = fill_sg_comp(gather_comp, i, offset_dma, 1271177b41ceSRagothaman Jayaraman OFF_CTRL_LEN + iv_len); 1272177b41ceSRagothaman Jayaraman 1273177b41ceSRagothaman Jayaraman /* Add input data */ 1274177b41ceSRagothaman Jayaraman if (flags & VALID_MAC_BUF) { 1275177b41ceSRagothaman Jayaraman size = inputlen - iv_len - mac_len; 1276177b41ceSRagothaman Jayaraman if (size) { 1277177b41ceSRagothaman Jayaraman /* input data only */ 1278177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1279177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 1280177b41ceSRagothaman Jayaraman gather_comp, i, 1281177b41ceSRagothaman Jayaraman fc_params->bufs, 1282177b41ceSRagothaman Jayaraman &size); 1283177b41ceSRagothaman Jayaraman } else { 1284177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1285177b41ceSRagothaman Jayaraman passthrough_len : 0; 1286177b41ceSRagothaman Jayaraman 1287177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov(gather_comp, 1288177b41ceSRagothaman Jayaraman i, 1289177b41ceSRagothaman Jayaraman fc_params->src_iov, 1290177b41ceSRagothaman Jayaraman 0, &size, 1291177b41ceSRagothaman Jayaraman aad_buf, 1292177b41ceSRagothaman Jayaraman aad_offset); 1293177b41ceSRagothaman Jayaraman } 1294f39928e6SAnoob Joseph if (unlikely(size)) { 1295f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 1296f39928e6SAnoob Joseph " space, size %d needed", 1297f39928e6SAnoob Joseph size); 1298f39928e6SAnoob Joseph return; 1299f39928e6SAnoob Joseph } 1300177b41ceSRagothaman Jayaraman } 1301177b41ceSRagothaman Jayaraman 1302177b41ceSRagothaman Jayaraman /* mac data */ 1303177b41ceSRagothaman Jayaraman if (mac_len) { 1304177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf(gather_comp, i, 1305177b41ceSRagothaman Jayaraman &fc_params->mac_buf); 1306177b41ceSRagothaman Jayaraman } 1307177b41ceSRagothaman Jayaraman } else { 1308177b41ceSRagothaman Jayaraman /* input data + mac */ 1309177b41ceSRagothaman Jayaraman size = inputlen - iv_len; 1310177b41ceSRagothaman Jayaraman if (size) { 1311177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1312177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min( 1313177b41ceSRagothaman Jayaraman gather_comp, i, 1314177b41ceSRagothaman Jayaraman fc_params->bufs, 1315177b41ceSRagothaman Jayaraman &size); 1316177b41ceSRagothaman Jayaraman } else { 1317177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1318177b41ceSRagothaman Jayaraman passthrough_len : 0; 1319177b41ceSRagothaman Jayaraman 1320f39928e6SAnoob Joseph if (unlikely(!fc_params->src_iov)) { 1321f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Bad input args"); 1322f39928e6SAnoob Joseph return; 1323f39928e6SAnoob Joseph } 1324177b41ceSRagothaman Jayaraman 1325177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov( 1326177b41ceSRagothaman Jayaraman gather_comp, i, 1327177b41ceSRagothaman Jayaraman fc_params->src_iov, 1328177b41ceSRagothaman Jayaraman 0, &size, 1329177b41ceSRagothaman Jayaraman aad_buf, 1330177b41ceSRagothaman Jayaraman aad_offset); 1331177b41ceSRagothaman Jayaraman } 1332177b41ceSRagothaman Jayaraman 1333f39928e6SAnoob Joseph if (unlikely(size)) { 1334f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer" 1335f39928e6SAnoob Joseph " space, size %d needed", 1336f39928e6SAnoob Joseph size); 1337f39928e6SAnoob Joseph return; 1338f39928e6SAnoob Joseph } 1339177b41ceSRagothaman Jayaraman } 1340177b41ceSRagothaman Jayaraman } 1341177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 1342177b41ceSRagothaman Jayaraman g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1343177b41ceSRagothaman Jayaraman 1344177b41ceSRagothaman Jayaraman /* 1345177b41ceSRagothaman Jayaraman * Output Scatter List 1346177b41ceSRagothaman Jayaraman */ 1347177b41ceSRagothaman Jayaraman 1348177b41ceSRagothaman Jayaraman i = 0; 1349177b41ceSRagothaman Jayaraman scatter_comp = 1350177b41ceSRagothaman Jayaraman (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 1351177b41ceSRagothaman Jayaraman 1352177b41ceSRagothaman Jayaraman /* Add iv */ 1353177b41ceSRagothaman Jayaraman if (iv_len) { 1354177b41ceSRagothaman Jayaraman i = fill_sg_comp(scatter_comp, i, 1355177b41ceSRagothaman Jayaraman offset_dma + OFF_CTRL_LEN, 1356177b41ceSRagothaman Jayaraman iv_len); 1357177b41ceSRagothaman Jayaraman } 1358177b41ceSRagothaman Jayaraman 1359177b41ceSRagothaman Jayaraman /* Add output data */ 1360177b41ceSRagothaman Jayaraman size = outputlen - iv_len; 1361177b41ceSRagothaman Jayaraman if (size) { 1362177b41ceSRagothaman Jayaraman if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1363177b41ceSRagothaman Jayaraman /* handle single buffer here */ 1364177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_buf_min(scatter_comp, i, 1365177b41ceSRagothaman Jayaraman fc_params->bufs, 1366177b41ceSRagothaman Jayaraman &size); 1367177b41ceSRagothaman Jayaraman } else { 1368177b41ceSRagothaman Jayaraman uint32_t aad_offset = aad_len ? 1369177b41ceSRagothaman Jayaraman passthrough_len : 0; 1370177b41ceSRagothaman Jayaraman 1371f39928e6SAnoob Joseph if (unlikely(!fc_params->dst_iov)) { 1372f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Bad input args"); 1373f39928e6SAnoob Joseph return; 1374f39928e6SAnoob Joseph } 1375177b41ceSRagothaman Jayaraman 1376177b41ceSRagothaman Jayaraman i = fill_sg_comp_from_iov(scatter_comp, i, 1377177b41ceSRagothaman Jayaraman fc_params->dst_iov, 0, 1378177b41ceSRagothaman Jayaraman &size, aad_buf, 1379177b41ceSRagothaman Jayaraman aad_offset); 1380177b41ceSRagothaman Jayaraman } 1381177b41ceSRagothaman Jayaraman 1382f39928e6SAnoob Joseph if (unlikely(size)) { 1383f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1384f39928e6SAnoob Joseph " size %d needed", size); 1385f39928e6SAnoob Joseph return; 1386f39928e6SAnoob Joseph } 1387177b41ceSRagothaman Jayaraman } 1388177b41ceSRagothaman Jayaraman 1389177b41ceSRagothaman Jayaraman ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 1390177b41ceSRagothaman Jayaraman s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1391177b41ceSRagothaman Jayaraman 1392177b41ceSRagothaman Jayaraman size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 1393177b41ceSRagothaman Jayaraman 1394177b41ceSRagothaman Jayaraman /* This is DPTR len incase of SG mode */ 1395426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 1396177b41ceSRagothaman Jayaraman 1397177b41ceSRagothaman Jayaraman m_vaddr = (uint8_t *)m_vaddr + size; 1398177b41ceSRagothaman Jayaraman m_dma += size; 1399177b41ceSRagothaman Jayaraman 1400177b41ceSRagothaman Jayaraman /* cpt alternate completion address saved earlier */ 1401177b41ceSRagothaman Jayaraman req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 1402177b41ceSRagothaman Jayaraman *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 1403177b41ceSRagothaman Jayaraman rptr_dma = c_dma - 8; 1404177b41ceSRagothaman Jayaraman size += COMPLETION_CODE_SIZE; 1405177b41ceSRagothaman Jayaraman 1406177b41ceSRagothaman Jayaraman req->ist.ei1 = dptr_dma; 1407177b41ceSRagothaman Jayaraman req->ist.ei2 = rptr_dma; 1408177b41ceSRagothaman Jayaraman } 1409177b41ceSRagothaman Jayaraman 1410177b41ceSRagothaman Jayaraman /* 16 byte aligned cpt res address */ 1411177b41ceSRagothaman Jayaraman req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1412177b41ceSRagothaman Jayaraman *req->completion_addr = COMPLETION_CODE_INIT; 1413177b41ceSRagothaman Jayaraman req->comp_baddr = c_dma; 1414177b41ceSRagothaman Jayaraman 1415177b41ceSRagothaman Jayaraman /* Fill microcode part of instruction */ 1416177b41ceSRagothaman Jayaraman req->ist.ei0 = vq_cmd_w0.u64; 1417177b41ceSRagothaman Jayaraman 1418177b41ceSRagothaman Jayaraman req->op = op; 1419177b41ceSRagothaman Jayaraman 1420177b41ceSRagothaman Jayaraman *prep_req = req; 1421f39928e6SAnoob Joseph return; 1422177b41ceSRagothaman Jayaraman } 1423177b41ceSRagothaman Jayaraman 1424f39928e6SAnoob Joseph static __rte_always_inline void 142500d92c66SSrisivasubramanian S cpt_zuc_snow3g_enc_prep(uint32_t req_flags, 142600d92c66SSrisivasubramanian S uint64_t d_offs, 142700d92c66SSrisivasubramanian S uint64_t d_lens, 142800d92c66SSrisivasubramanian S fc_params_t *params, 142900d92c66SSrisivasubramanian S void *op, 143000d92c66SSrisivasubramanian S void **prep_req) 143100d92c66SSrisivasubramanian S { 143200d92c66SSrisivasubramanian S uint32_t size; 143300d92c66SSrisivasubramanian S int32_t inputlen, outputlen; 143400d92c66SSrisivasubramanian S struct cpt_ctx *cpt_ctx; 143500d92c66SSrisivasubramanian S uint32_t mac_len = 0; 143600d92c66SSrisivasubramanian S uint8_t snow3g, j; 143700d92c66SSrisivasubramanian S struct cpt_request_info *req; 143800d92c66SSrisivasubramanian S buf_ptr_t *buf_p; 143900d92c66SSrisivasubramanian S uint32_t encr_offset = 0, auth_offset = 0; 144000d92c66SSrisivasubramanian S uint32_t encr_data_len = 0, auth_data_len = 0; 14418de5ede7SAnoob Joseph int flags, iv_len = 16; 144200d92c66SSrisivasubramanian S void *m_vaddr, *c_vaddr; 144300d92c66SSrisivasubramanian S uint64_t m_dma, c_dma, offset_ctrl; 144400d92c66SSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 144500d92c66SSrisivasubramanian S uint32_t *iv_s, iv[4]; 144600d92c66SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 144700d92c66SSrisivasubramanian S 144800d92c66SSrisivasubramanian S buf_p = ¶ms->meta_buf; 144900d92c66SSrisivasubramanian S m_vaddr = buf_p->vaddr; 145000d92c66SSrisivasubramanian S m_dma = buf_p->dma_addr; 145100d92c66SSrisivasubramanian S 145200d92c66SSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 145300d92c66SSrisivasubramanian S flags = cpt_ctx->zsk_flags; 145400d92c66SSrisivasubramanian S mac_len = cpt_ctx->mac_len; 145500d92c66SSrisivasubramanian S snow3g = cpt_ctx->snow3g; 145600d92c66SSrisivasubramanian S 145700d92c66SSrisivasubramanian S /* 145800d92c66SSrisivasubramanian S * Save initial space that followed app data for completion code & 145900d92c66SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 146000d92c66SSrisivasubramanian S */ 146100d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 146200d92c66SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 146300d92c66SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 146400d92c66SSrisivasubramanian S (uint8_t *)m_vaddr; 146500d92c66SSrisivasubramanian S 146600d92c66SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 146700d92c66SSrisivasubramanian S c_dma = m_dma + size; 146800d92c66SSrisivasubramanian S size += sizeof(cpt_res_s_t); 146900d92c66SSrisivasubramanian S 147000d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 147100d92c66SSrisivasubramanian S m_dma += size; 147200d92c66SSrisivasubramanian S 147300d92c66SSrisivasubramanian S /* Reserve memory for cpt request info */ 147400d92c66SSrisivasubramanian S req = m_vaddr; 147500d92c66SSrisivasubramanian S 147600d92c66SSrisivasubramanian S size = sizeof(struct cpt_request_info); 147700d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 147800d92c66SSrisivasubramanian S m_dma += size; 147900d92c66SSrisivasubramanian S 1480629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ZUC_SNOW3G; 148100d92c66SSrisivasubramanian S 148200d92c66SSrisivasubramanian S /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1483131966f8SAnkur Dwivedi 1484629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 148500d92c66SSrisivasubramanian S (0 << 3) | (flags & 0x7)); 148600d92c66SSrisivasubramanian S 148700d92c66SSrisivasubramanian S if (flags == 0x1) { 148800d92c66SSrisivasubramanian S /* 148900d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 149000d92c66SSrisivasubramanian S * TODO: Rounding off 149100d92c66SSrisivasubramanian S */ 149200d92c66SSrisivasubramanian S auth_data_len = AUTH_DLEN(d_lens); 149300d92c66SSrisivasubramanian S 149400d92c66SSrisivasubramanian S /* EIA3 or UIA2 */ 149500d92c66SSrisivasubramanian S auth_offset = AUTH_OFFSET(d_offs); 149600d92c66SSrisivasubramanian S auth_offset = auth_offset / 8; 149700d92c66SSrisivasubramanian S 149800d92c66SSrisivasubramanian S /* consider iv len */ 149900d92c66SSrisivasubramanian S auth_offset += iv_len; 150000d92c66SSrisivasubramanian S 150100d92c66SSrisivasubramanian S inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 150200d92c66SSrisivasubramanian S outputlen = mac_len; 150300d92c66SSrisivasubramanian S 150400d92c66SSrisivasubramanian S offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset); 150500d92c66SSrisivasubramanian S 150600d92c66SSrisivasubramanian S } else { 150700d92c66SSrisivasubramanian S /* EEA3 or UEA2 */ 150800d92c66SSrisivasubramanian S /* 150900d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 151000d92c66SSrisivasubramanian S * TODO: Rounding off 151100d92c66SSrisivasubramanian S */ 151200d92c66SSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 151300d92c66SSrisivasubramanian S 151400d92c66SSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs); 151500d92c66SSrisivasubramanian S encr_offset = encr_offset / 8; 151600d92c66SSrisivasubramanian S /* consider iv len */ 151700d92c66SSrisivasubramanian S encr_offset += iv_len; 151800d92c66SSrisivasubramanian S 151900d92c66SSrisivasubramanian S inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 152000d92c66SSrisivasubramanian S outputlen = inputlen; 152100d92c66SSrisivasubramanian S 152200d92c66SSrisivasubramanian S /* iv offset is 0 */ 152300d92c66SSrisivasubramanian S offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 152400d92c66SSrisivasubramanian S } 152500d92c66SSrisivasubramanian S 15262a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16) || 15272a6c7922SAnoob Joseph (auth_offset >> 8))) { 15282a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 15292a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 15302a6c7922SAnoob Joseph CPT_LOG_DP_ERR("auth_offset: %d", auth_offset); 15312a6c7922SAnoob Joseph return; 15322a6c7922SAnoob Joseph } 15332a6c7922SAnoob Joseph 153400d92c66SSrisivasubramanian S /* IV */ 153500d92c66SSrisivasubramanian S iv_s = (flags == 0x1) ? params->auth_iv_buf : 153600d92c66SSrisivasubramanian S params->iv_buf; 153700d92c66SSrisivasubramanian S 153800d92c66SSrisivasubramanian S if (snow3g) { 153900d92c66SSrisivasubramanian S /* 154000d92c66SSrisivasubramanian S * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 154100d92c66SSrisivasubramanian S * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 154200d92c66SSrisivasubramanian S */ 154300d92c66SSrisivasubramanian S 154400d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 154500d92c66SSrisivasubramanian S iv[j] = iv_s[3 - j]; 154600d92c66SSrisivasubramanian S } else { 154700d92c66SSrisivasubramanian S /* ZUC doesn't need a swap */ 154800d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 154900d92c66SSrisivasubramanian S iv[j] = iv_s[j]; 155000d92c66SSrisivasubramanian S } 155100d92c66SSrisivasubramanian S 155200d92c66SSrisivasubramanian S /* 155300d92c66SSrisivasubramanian S * GP op header, lengths are expected in bits. 155400d92c66SSrisivasubramanian S */ 1555426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 1556426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 155700d92c66SSrisivasubramanian S 155800d92c66SSrisivasubramanian S /* 155900d92c66SSrisivasubramanian S * In 83XX since we have a limitation of 156000d92c66SSrisivasubramanian S * IV & Offset control word not part of instruction 156100d92c66SSrisivasubramanian S * and need to be part of Data Buffer, we check if 156200d92c66SSrisivasubramanian S * head room is there and then only do the Direct mode processing 156300d92c66SSrisivasubramanian S */ 156400d92c66SSrisivasubramanian S if (likely((req_flags & SINGLE_BUF_INPLACE) && 156500d92c66SSrisivasubramanian S (req_flags & SINGLE_BUF_HEADTAILROOM))) { 156600d92c66SSrisivasubramanian S void *dm_vaddr = params->bufs[0].vaddr; 156700d92c66SSrisivasubramanian S uint64_t dm_dma_addr = params->bufs[0].dma_addr; 156800d92c66SSrisivasubramanian S /* 156900d92c66SSrisivasubramanian S * This flag indicates that there is 24 bytes head room and 157000d92c66SSrisivasubramanian S * 8 bytes tail room available, so that we get to do 157100d92c66SSrisivasubramanian S * DIRECT MODE with limitation 157200d92c66SSrisivasubramanian S */ 157300d92c66SSrisivasubramanian S 157400d92c66SSrisivasubramanian S offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 157500d92c66SSrisivasubramanian S OFF_CTRL_LEN - iv_len); 157600d92c66SSrisivasubramanian S offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 157700d92c66SSrisivasubramanian S 157800d92c66SSrisivasubramanian S /* DPTR */ 157900d92c66SSrisivasubramanian S req->ist.ei1 = offset_dma; 158000d92c66SSrisivasubramanian S /* RPTR should just exclude offset control word */ 158100d92c66SSrisivasubramanian S req->ist.ei2 = dm_dma_addr - iv_len; 158200d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 158300d92c66SSrisivasubramanian S + outputlen - iv_len); 158400d92c66SSrisivasubramanian S 1585426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 158600d92c66SSrisivasubramanian S 158700d92c66SSrisivasubramanian S if (likely(iv_len)) { 158800d92c66SSrisivasubramanian S uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 158900d92c66SSrisivasubramanian S + OFF_CTRL_LEN); 159000d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 159100d92c66SSrisivasubramanian S } 159200d92c66SSrisivasubramanian S 159300d92c66SSrisivasubramanian S *offset_vaddr = offset_ctrl; 159400d92c66SSrisivasubramanian S } else { 159500d92c66SSrisivasubramanian S uint32_t i, g_size_bytes, s_size_bytes; 159600d92c66SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 159700d92c66SSrisivasubramanian S sg_comp_t *gather_comp; 159800d92c66SSrisivasubramanian S sg_comp_t *scatter_comp; 159900d92c66SSrisivasubramanian S uint8_t *in_buffer; 160000d92c66SSrisivasubramanian S uint32_t *iv_d; 160100d92c66SSrisivasubramanian S 160200d92c66SSrisivasubramanian S /* save space for iv */ 160300d92c66SSrisivasubramanian S offset_vaddr = m_vaddr; 160400d92c66SSrisivasubramanian S offset_dma = m_dma; 160500d92c66SSrisivasubramanian S 160600d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 160700d92c66SSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 160800d92c66SSrisivasubramanian S 1609629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE; 161000d92c66SSrisivasubramanian S 161100d92c66SSrisivasubramanian S /* DPTR has SG list */ 161200d92c66SSrisivasubramanian S in_buffer = m_vaddr; 161300d92c66SSrisivasubramanian S dptr_dma = m_dma; 161400d92c66SSrisivasubramanian S 161500d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 161600d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 161700d92c66SSrisivasubramanian S 161800d92c66SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 161900d92c66SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 162000d92c66SSrisivasubramanian S 162100d92c66SSrisivasubramanian S /* 162200d92c66SSrisivasubramanian S * Input Gather List 162300d92c66SSrisivasubramanian S */ 162400d92c66SSrisivasubramanian S i = 0; 162500d92c66SSrisivasubramanian S 162600d92c66SSrisivasubramanian S /* Offset control word followed by iv */ 162700d92c66SSrisivasubramanian S 162800d92c66SSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, 162900d92c66SSrisivasubramanian S OFF_CTRL_LEN + iv_len); 163000d92c66SSrisivasubramanian S 163100d92c66SSrisivasubramanian S /* iv offset is 0 */ 163200d92c66SSrisivasubramanian S *offset_vaddr = offset_ctrl; 163300d92c66SSrisivasubramanian S 163400d92c66SSrisivasubramanian S iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 163500d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 163600d92c66SSrisivasubramanian S 163700d92c66SSrisivasubramanian S /* input data */ 163800d92c66SSrisivasubramanian S size = inputlen - iv_len; 163900d92c66SSrisivasubramanian S if (size) { 164000d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 164100d92c66SSrisivasubramanian S params->src_iov, 164200d92c66SSrisivasubramanian S 0, &size, NULL, 0); 1643f39928e6SAnoob Joseph if (unlikely(size)) { 1644f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1645f39928e6SAnoob Joseph " size %d needed", size); 1646f39928e6SAnoob Joseph return; 1647f39928e6SAnoob Joseph } 164800d92c66SSrisivasubramanian S } 164900d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 165000d92c66SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 165100d92c66SSrisivasubramanian S 165200d92c66SSrisivasubramanian S /* 165300d92c66SSrisivasubramanian S * Output Scatter List 165400d92c66SSrisivasubramanian S */ 165500d92c66SSrisivasubramanian S 165600d92c66SSrisivasubramanian S i = 0; 165700d92c66SSrisivasubramanian S scatter_comp = 165800d92c66SSrisivasubramanian S (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 165900d92c66SSrisivasubramanian S 166000d92c66SSrisivasubramanian S if (flags == 0x1) { 166100d92c66SSrisivasubramanian S /* IV in SLIST only for EEA3 & UEA2 */ 166200d92c66SSrisivasubramanian S iv_len = 0; 166300d92c66SSrisivasubramanian S } 166400d92c66SSrisivasubramanian S 166500d92c66SSrisivasubramanian S if (iv_len) { 166600d92c66SSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 166700d92c66SSrisivasubramanian S offset_dma + OFF_CTRL_LEN, iv_len); 166800d92c66SSrisivasubramanian S } 166900d92c66SSrisivasubramanian S 167000d92c66SSrisivasubramanian S /* Add output data */ 167100d92c66SSrisivasubramanian S if (req_flags & VALID_MAC_BUF) { 167200d92c66SSrisivasubramanian S size = outputlen - iv_len - mac_len; 167300d92c66SSrisivasubramanian S if (size) { 167400d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 167500d92c66SSrisivasubramanian S params->dst_iov, 0, 167600d92c66SSrisivasubramanian S &size, NULL, 0); 167700d92c66SSrisivasubramanian S 1678f39928e6SAnoob Joseph if (unlikely(size)) { 1679f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1680f39928e6SAnoob Joseph " size %d needed", size); 1681f39928e6SAnoob Joseph return; 1682f39928e6SAnoob Joseph } 168300d92c66SSrisivasubramanian S } 168400d92c66SSrisivasubramanian S 168500d92c66SSrisivasubramanian S /* mac data */ 168600d92c66SSrisivasubramanian S if (mac_len) { 168700d92c66SSrisivasubramanian S i = fill_sg_comp_from_buf(scatter_comp, i, 168800d92c66SSrisivasubramanian S ¶ms->mac_buf); 168900d92c66SSrisivasubramanian S } 169000d92c66SSrisivasubramanian S } else { 169100d92c66SSrisivasubramanian S /* Output including mac */ 169200d92c66SSrisivasubramanian S size = outputlen - iv_len; 169300d92c66SSrisivasubramanian S if (size) { 169400d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 169500d92c66SSrisivasubramanian S params->dst_iov, 0, 169600d92c66SSrisivasubramanian S &size, NULL, 0); 169700d92c66SSrisivasubramanian S 1698f39928e6SAnoob Joseph if (unlikely(size)) { 1699f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1700f39928e6SAnoob Joseph " size %d needed", size); 1701f39928e6SAnoob Joseph return; 1702f39928e6SAnoob Joseph } 170300d92c66SSrisivasubramanian S } 170400d92c66SSrisivasubramanian S } 170500d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 170600d92c66SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 170700d92c66SSrisivasubramanian S 170800d92c66SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 170900d92c66SSrisivasubramanian S 171000d92c66SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 1711426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 171200d92c66SSrisivasubramanian S 171300d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 171400d92c66SSrisivasubramanian S m_dma += size; 171500d92c66SSrisivasubramanian S 171600d92c66SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 171700d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 171800d92c66SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 171900d92c66SSrisivasubramanian S rptr_dma = c_dma - 8; 172000d92c66SSrisivasubramanian S 172100d92c66SSrisivasubramanian S req->ist.ei1 = dptr_dma; 172200d92c66SSrisivasubramanian S req->ist.ei2 = rptr_dma; 172300d92c66SSrisivasubramanian S } 172400d92c66SSrisivasubramanian S 172500d92c66SSrisivasubramanian S /* 16 byte aligned cpt res address */ 172600d92c66SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 172700d92c66SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 172800d92c66SSrisivasubramanian S req->comp_baddr = c_dma; 172900d92c66SSrisivasubramanian S 173000d92c66SSrisivasubramanian S /* Fill microcode part of instruction */ 173100d92c66SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 173200d92c66SSrisivasubramanian S 173300d92c66SSrisivasubramanian S req->op = op; 173400d92c66SSrisivasubramanian S 173500d92c66SSrisivasubramanian S *prep_req = req; 1736f39928e6SAnoob Joseph return; 173700d92c66SSrisivasubramanian S } 173800d92c66SSrisivasubramanian S 1739f39928e6SAnoob Joseph static __rte_always_inline void 174000d92c66SSrisivasubramanian S cpt_zuc_snow3g_dec_prep(uint32_t req_flags, 174100d92c66SSrisivasubramanian S uint64_t d_offs, 174200d92c66SSrisivasubramanian S uint64_t d_lens, 174300d92c66SSrisivasubramanian S fc_params_t *params, 174400d92c66SSrisivasubramanian S void *op, 174500d92c66SSrisivasubramanian S void **prep_req) 174600d92c66SSrisivasubramanian S { 174700d92c66SSrisivasubramanian S uint32_t size; 174800d92c66SSrisivasubramanian S int32_t inputlen = 0, outputlen; 174900d92c66SSrisivasubramanian S struct cpt_ctx *cpt_ctx; 175000d92c66SSrisivasubramanian S uint8_t snow3g, iv_len = 16; 175100d92c66SSrisivasubramanian S struct cpt_request_info *req; 175200d92c66SSrisivasubramanian S buf_ptr_t *buf_p; 175300d92c66SSrisivasubramanian S uint32_t encr_offset; 175400d92c66SSrisivasubramanian S uint32_t encr_data_len; 17558de5ede7SAnoob Joseph int flags; 175600d92c66SSrisivasubramanian S void *m_vaddr, *c_vaddr; 175700d92c66SSrisivasubramanian S uint64_t m_dma, c_dma; 175800d92c66SSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 175900d92c66SSrisivasubramanian S uint32_t *iv_s, iv[4], j; 176000d92c66SSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 176100d92c66SSrisivasubramanian S 176200d92c66SSrisivasubramanian S buf_p = ¶ms->meta_buf; 176300d92c66SSrisivasubramanian S m_vaddr = buf_p->vaddr; 176400d92c66SSrisivasubramanian S m_dma = buf_p->dma_addr; 176500d92c66SSrisivasubramanian S 176600d92c66SSrisivasubramanian S /* 176700d92c66SSrisivasubramanian S * Microcode expects offsets in bytes 176800d92c66SSrisivasubramanian S * TODO: Rounding off 176900d92c66SSrisivasubramanian S */ 177000d92c66SSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 177100d92c66SSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 177200d92c66SSrisivasubramanian S 177300d92c66SSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 177400d92c66SSrisivasubramanian S flags = cpt_ctx->zsk_flags; 177500d92c66SSrisivasubramanian S snow3g = cpt_ctx->snow3g; 177600d92c66SSrisivasubramanian S /* 177700d92c66SSrisivasubramanian S * Save initial space that followed app data for completion code & 177800d92c66SSrisivasubramanian S * alternate completion code to fall in same cache line as app data 177900d92c66SSrisivasubramanian S */ 178000d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 178100d92c66SSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 178200d92c66SSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 178300d92c66SSrisivasubramanian S (uint8_t *)m_vaddr; 178400d92c66SSrisivasubramanian S 178500d92c66SSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 178600d92c66SSrisivasubramanian S c_dma = m_dma + size; 178700d92c66SSrisivasubramanian S size += sizeof(cpt_res_s_t); 178800d92c66SSrisivasubramanian S 178900d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 179000d92c66SSrisivasubramanian S m_dma += size; 179100d92c66SSrisivasubramanian S 179200d92c66SSrisivasubramanian S /* Reserve memory for cpt request info */ 179300d92c66SSrisivasubramanian S req = m_vaddr; 179400d92c66SSrisivasubramanian S 179500d92c66SSrisivasubramanian S size = sizeof(struct cpt_request_info); 179600d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 179700d92c66SSrisivasubramanian S m_dma += size; 179800d92c66SSrisivasubramanian S 1799629ac988SArchana Muniganti vq_cmd_w0.u64 = 0; 1800629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ZUC_SNOW3G; 180100d92c66SSrisivasubramanian S 180200d92c66SSrisivasubramanian S /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1803131966f8SAnkur Dwivedi 1804629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 180500d92c66SSrisivasubramanian S (0 << 3) | (flags & 0x7)); 180600d92c66SSrisivasubramanian S 180700d92c66SSrisivasubramanian S /* consider iv len */ 180800d92c66SSrisivasubramanian S encr_offset += iv_len; 180900d92c66SSrisivasubramanian S 181000d92c66SSrisivasubramanian S inputlen = encr_offset + 181100d92c66SSrisivasubramanian S (RTE_ALIGN(encr_data_len, 8) / 8); 181200d92c66SSrisivasubramanian S outputlen = inputlen; 181300d92c66SSrisivasubramanian S 181400d92c66SSrisivasubramanian S /* IV */ 181500d92c66SSrisivasubramanian S iv_s = params->iv_buf; 181600d92c66SSrisivasubramanian S if (snow3g) { 181700d92c66SSrisivasubramanian S /* 181800d92c66SSrisivasubramanian S * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 181900d92c66SSrisivasubramanian S * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 182000d92c66SSrisivasubramanian S */ 182100d92c66SSrisivasubramanian S 182200d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 182300d92c66SSrisivasubramanian S iv[j] = iv_s[3 - j]; 182400d92c66SSrisivasubramanian S } else { 182500d92c66SSrisivasubramanian S /* ZUC doesn't need a swap */ 182600d92c66SSrisivasubramanian S for (j = 0; j < 4; j++) 182700d92c66SSrisivasubramanian S iv[j] = iv_s[j]; 182800d92c66SSrisivasubramanian S } 182900d92c66SSrisivasubramanian S 183000d92c66SSrisivasubramanian S /* 183100d92c66SSrisivasubramanian S * GP op header, lengths are expected in bits. 183200d92c66SSrisivasubramanian S */ 1833426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 183400d92c66SSrisivasubramanian S 183500d92c66SSrisivasubramanian S /* 183600d92c66SSrisivasubramanian S * In 83XX since we have a limitation of 183700d92c66SSrisivasubramanian S * IV & Offset control word not part of instruction 183800d92c66SSrisivasubramanian S * and need to be part of Data Buffer, we check if 183900d92c66SSrisivasubramanian S * head room is there and then only do the Direct mode processing 184000d92c66SSrisivasubramanian S */ 184100d92c66SSrisivasubramanian S if (likely((req_flags & SINGLE_BUF_INPLACE) && 184200d92c66SSrisivasubramanian S (req_flags & SINGLE_BUF_HEADTAILROOM))) { 184300d92c66SSrisivasubramanian S void *dm_vaddr = params->bufs[0].vaddr; 184400d92c66SSrisivasubramanian S uint64_t dm_dma_addr = params->bufs[0].dma_addr; 184500d92c66SSrisivasubramanian S /* 184600d92c66SSrisivasubramanian S * This flag indicates that there is 24 bytes head room and 184700d92c66SSrisivasubramanian S * 8 bytes tail room available, so that we get to do 184800d92c66SSrisivasubramanian S * DIRECT MODE with limitation 184900d92c66SSrisivasubramanian S */ 185000d92c66SSrisivasubramanian S 185100d92c66SSrisivasubramanian S offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 185200d92c66SSrisivasubramanian S OFF_CTRL_LEN - iv_len); 185300d92c66SSrisivasubramanian S offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 185400d92c66SSrisivasubramanian S 185500d92c66SSrisivasubramanian S /* DPTR */ 185600d92c66SSrisivasubramanian S req->ist.ei1 = offset_dma; 185700d92c66SSrisivasubramanian S /* RPTR should just exclude offset control word */ 185800d92c66SSrisivasubramanian S req->ist.ei2 = dm_dma_addr - iv_len; 185900d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 186000d92c66SSrisivasubramanian S + outputlen - iv_len); 186100d92c66SSrisivasubramanian S 1862426af86bSAnoob Joseph vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 186300d92c66SSrisivasubramanian S 186400d92c66SSrisivasubramanian S if (likely(iv_len)) { 186500d92c66SSrisivasubramanian S uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 186600d92c66SSrisivasubramanian S + OFF_CTRL_LEN); 186700d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 186800d92c66SSrisivasubramanian S } 186900d92c66SSrisivasubramanian S 187000d92c66SSrisivasubramanian S /* iv offset is 0 */ 187100d92c66SSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 187200d92c66SSrisivasubramanian S } else { 187300d92c66SSrisivasubramanian S uint32_t i, g_size_bytes, s_size_bytes; 187400d92c66SSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 187500d92c66SSrisivasubramanian S sg_comp_t *gather_comp; 187600d92c66SSrisivasubramanian S sg_comp_t *scatter_comp; 187700d92c66SSrisivasubramanian S uint8_t *in_buffer; 187800d92c66SSrisivasubramanian S uint32_t *iv_d; 187900d92c66SSrisivasubramanian S 188000d92c66SSrisivasubramanian S /* save space for offset and iv... */ 188100d92c66SSrisivasubramanian S offset_vaddr = m_vaddr; 188200d92c66SSrisivasubramanian S offset_dma = m_dma; 188300d92c66SSrisivasubramanian S 188400d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 188500d92c66SSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 188600d92c66SSrisivasubramanian S 1887629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE; 188800d92c66SSrisivasubramanian S 188900d92c66SSrisivasubramanian S /* DPTR has SG list */ 189000d92c66SSrisivasubramanian S in_buffer = m_vaddr; 189100d92c66SSrisivasubramanian S dptr_dma = m_dma; 189200d92c66SSrisivasubramanian S 189300d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 189400d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 189500d92c66SSrisivasubramanian S 189600d92c66SSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 189700d92c66SSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 189800d92c66SSrisivasubramanian S 189900d92c66SSrisivasubramanian S /* 190000d92c66SSrisivasubramanian S * Input Gather List 190100d92c66SSrisivasubramanian S */ 190200d92c66SSrisivasubramanian S i = 0; 190300d92c66SSrisivasubramanian S 190400d92c66SSrisivasubramanian S /* Offset control word */ 190500d92c66SSrisivasubramanian S 190600d92c66SSrisivasubramanian S /* iv offset is 0 */ 190700d92c66SSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 190800d92c66SSrisivasubramanian S 190900d92c66SSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, 191000d92c66SSrisivasubramanian S OFF_CTRL_LEN + iv_len); 191100d92c66SSrisivasubramanian S 191200d92c66SSrisivasubramanian S iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 191300d92c66SSrisivasubramanian S memcpy(iv_d, iv, 16); 191400d92c66SSrisivasubramanian S 191500d92c66SSrisivasubramanian S /* Add input data */ 191600d92c66SSrisivasubramanian S size = inputlen - iv_len; 191700d92c66SSrisivasubramanian S if (size) { 191800d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 191900d92c66SSrisivasubramanian S params->src_iov, 192000d92c66SSrisivasubramanian S 0, &size, NULL, 0); 1921f39928e6SAnoob Joseph if (unlikely(size)) { 1922f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1923f39928e6SAnoob Joseph " size %d needed", size); 1924f39928e6SAnoob Joseph return; 1925f39928e6SAnoob Joseph } 192600d92c66SSrisivasubramanian S } 192700d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 192800d92c66SSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 192900d92c66SSrisivasubramanian S 193000d92c66SSrisivasubramanian S /* 193100d92c66SSrisivasubramanian S * Output Scatter List 193200d92c66SSrisivasubramanian S */ 193300d92c66SSrisivasubramanian S 193400d92c66SSrisivasubramanian S i = 0; 193500d92c66SSrisivasubramanian S scatter_comp = 193600d92c66SSrisivasubramanian S (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 193700d92c66SSrisivasubramanian S 193800d92c66SSrisivasubramanian S /* IV */ 193900d92c66SSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 194000d92c66SSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 194100d92c66SSrisivasubramanian S iv_len); 194200d92c66SSrisivasubramanian S 194300d92c66SSrisivasubramanian S /* Add output data */ 194400d92c66SSrisivasubramanian S size = outputlen - iv_len; 194500d92c66SSrisivasubramanian S if (size) { 194600d92c66SSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 194700d92c66SSrisivasubramanian S params->dst_iov, 0, 194800d92c66SSrisivasubramanian S &size, NULL, 0); 194900d92c66SSrisivasubramanian S 1950f39928e6SAnoob Joseph if (unlikely(size)) { 1951f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 1952f39928e6SAnoob Joseph " size %d needed", size); 1953f39928e6SAnoob Joseph return; 1954f39928e6SAnoob Joseph } 195500d92c66SSrisivasubramanian S } 195600d92c66SSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 195700d92c66SSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 195800d92c66SSrisivasubramanian S 195900d92c66SSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 196000d92c66SSrisivasubramanian S 196100d92c66SSrisivasubramanian S /* This is DPTR len incase of SG mode */ 1962426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 196300d92c66SSrisivasubramanian S 196400d92c66SSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 196500d92c66SSrisivasubramanian S m_dma += size; 196600d92c66SSrisivasubramanian S 196700d92c66SSrisivasubramanian S /* cpt alternate completion address saved earlier */ 196800d92c66SSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 196900d92c66SSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 197000d92c66SSrisivasubramanian S rptr_dma = c_dma - 8; 197100d92c66SSrisivasubramanian S 197200d92c66SSrisivasubramanian S req->ist.ei1 = dptr_dma; 197300d92c66SSrisivasubramanian S req->ist.ei2 = rptr_dma; 197400d92c66SSrisivasubramanian S } 197500d92c66SSrisivasubramanian S 19762a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16))) { 19772a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 19782a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 19792a6c7922SAnoob Joseph return; 19802a6c7922SAnoob Joseph } 19812a6c7922SAnoob Joseph 198200d92c66SSrisivasubramanian S /* 16 byte aligned cpt res address */ 198300d92c66SSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 198400d92c66SSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 198500d92c66SSrisivasubramanian S req->comp_baddr = c_dma; 198600d92c66SSrisivasubramanian S 198700d92c66SSrisivasubramanian S /* Fill microcode part of instruction */ 198800d92c66SSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 198900d92c66SSrisivasubramanian S 199000d92c66SSrisivasubramanian S req->op = op; 199100d92c66SSrisivasubramanian S 199200d92c66SSrisivasubramanian S *prep_req = req; 1993f39928e6SAnoob Joseph return; 199400d92c66SSrisivasubramanian S } 199500d92c66SSrisivasubramanian S 1996f39928e6SAnoob Joseph static __rte_always_inline void 1997da39e3ecSSrisivasubramanian S cpt_kasumi_enc_prep(uint32_t req_flags, 1998da39e3ecSSrisivasubramanian S uint64_t d_offs, 1999da39e3ecSSrisivasubramanian S uint64_t d_lens, 2000da39e3ecSSrisivasubramanian S fc_params_t *params, 2001da39e3ecSSrisivasubramanian S void *op, 2002da39e3ecSSrisivasubramanian S void **prep_req) 2003da39e3ecSSrisivasubramanian S { 2004da39e3ecSSrisivasubramanian S uint32_t size; 2005da39e3ecSSrisivasubramanian S int32_t inputlen = 0, outputlen = 0; 2006da39e3ecSSrisivasubramanian S struct cpt_ctx *cpt_ctx; 2007da39e3ecSSrisivasubramanian S uint32_t mac_len = 0; 2008da39e3ecSSrisivasubramanian S uint8_t i = 0; 2009da39e3ecSSrisivasubramanian S struct cpt_request_info *req; 2010da39e3ecSSrisivasubramanian S buf_ptr_t *buf_p; 2011da39e3ecSSrisivasubramanian S uint32_t encr_offset, auth_offset; 2012da39e3ecSSrisivasubramanian S uint32_t encr_data_len, auth_data_len; 20138de5ede7SAnoob Joseph int flags; 2014da39e3ecSSrisivasubramanian S uint8_t *iv_s, *iv_d, iv_len = 8; 2015da39e3ecSSrisivasubramanian S uint8_t dir = 0; 2016da39e3ecSSrisivasubramanian S void *m_vaddr, *c_vaddr; 2017da39e3ecSSrisivasubramanian S uint64_t m_dma, c_dma; 2018da39e3ecSSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 2019da39e3ecSSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 2020da39e3ecSSrisivasubramanian S uint8_t *in_buffer; 2021da39e3ecSSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 2022da39e3ecSSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 2023da39e3ecSSrisivasubramanian S sg_comp_t *gather_comp; 2024da39e3ecSSrisivasubramanian S sg_comp_t *scatter_comp; 2025da39e3ecSSrisivasubramanian S 2026da39e3ecSSrisivasubramanian S buf_p = ¶ms->meta_buf; 2027da39e3ecSSrisivasubramanian S m_vaddr = buf_p->vaddr; 2028da39e3ecSSrisivasubramanian S m_dma = buf_p->dma_addr; 2029da39e3ecSSrisivasubramanian S 2030da39e3ecSSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 2031da39e3ecSSrisivasubramanian S auth_offset = AUTH_OFFSET(d_offs) / 8; 2032da39e3ecSSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 2033da39e3ecSSrisivasubramanian S auth_data_len = AUTH_DLEN(d_lens); 2034da39e3ecSSrisivasubramanian S 2035da39e3ecSSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 2036da39e3ecSSrisivasubramanian S flags = cpt_ctx->zsk_flags; 2037da39e3ecSSrisivasubramanian S mac_len = cpt_ctx->mac_len; 2038da39e3ecSSrisivasubramanian S 2039da39e3ecSSrisivasubramanian S if (flags == 0x0) 2040da39e3ecSSrisivasubramanian S iv_s = params->iv_buf; 2041da39e3ecSSrisivasubramanian S else 2042da39e3ecSSrisivasubramanian S iv_s = params->auth_iv_buf; 2043da39e3ecSSrisivasubramanian S 2044da39e3ecSSrisivasubramanian S dir = iv_s[8] & 0x1; 2045da39e3ecSSrisivasubramanian S 2046da39e3ecSSrisivasubramanian S /* 2047da39e3ecSSrisivasubramanian S * Save initial space that followed app data for completion code & 2048da39e3ecSSrisivasubramanian S * alternate completion code to fall in same cache line as app data 2049da39e3ecSSrisivasubramanian S */ 2050da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2051da39e3ecSSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 2052da39e3ecSSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2053da39e3ecSSrisivasubramanian S (uint8_t *)m_vaddr; 2054da39e3ecSSrisivasubramanian S 2055da39e3ecSSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 2056da39e3ecSSrisivasubramanian S c_dma = m_dma + size; 2057da39e3ecSSrisivasubramanian S size += sizeof(cpt_res_s_t); 2058da39e3ecSSrisivasubramanian S 2059da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2060da39e3ecSSrisivasubramanian S m_dma += size; 2061da39e3ecSSrisivasubramanian S 2062da39e3ecSSrisivasubramanian S /* Reserve memory for cpt request info */ 2063da39e3ecSSrisivasubramanian S req = m_vaddr; 2064da39e3ecSSrisivasubramanian S 2065da39e3ecSSrisivasubramanian S size = sizeof(struct cpt_request_info); 2066da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2067da39e3ecSSrisivasubramanian S m_dma += size; 2068da39e3ecSSrisivasubramanian S 2069629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2070da39e3ecSSrisivasubramanian S 2071da39e3ecSSrisivasubramanian S /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2072629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2073da39e3ecSSrisivasubramanian S (dir << 4) | (0 << 3) | (flags & 0x7)); 2074da39e3ecSSrisivasubramanian S 2075da39e3ecSSrisivasubramanian S /* 2076da39e3ecSSrisivasubramanian S * GP op header, lengths are expected in bits. 2077da39e3ecSSrisivasubramanian S */ 2078426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 2079426af86bSAnoob Joseph vq_cmd_w0.s.param2 = auth_data_len; 2080da39e3ecSSrisivasubramanian S 2081da39e3ecSSrisivasubramanian S /* consider iv len */ 2082da39e3ecSSrisivasubramanian S if (flags == 0x0) { 2083da39e3ecSSrisivasubramanian S encr_offset += iv_len; 2084da39e3ecSSrisivasubramanian S auth_offset += iv_len; 2085da39e3ecSSrisivasubramanian S } 2086da39e3ecSSrisivasubramanian S 2087da39e3ecSSrisivasubramanian S /* save space for offset ctrl and iv */ 2088da39e3ecSSrisivasubramanian S offset_vaddr = m_vaddr; 2089da39e3ecSSrisivasubramanian S offset_dma = m_dma; 2090da39e3ecSSrisivasubramanian S 2091da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2092da39e3ecSSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 2093da39e3ecSSrisivasubramanian S 2094da39e3ecSSrisivasubramanian S /* DPTR has SG list */ 2095da39e3ecSSrisivasubramanian S in_buffer = m_vaddr; 2096da39e3ecSSrisivasubramanian S dptr_dma = m_dma; 2097da39e3ecSSrisivasubramanian S 2098da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 2099da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 2100da39e3ecSSrisivasubramanian S 2101da39e3ecSSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 2102da39e3ecSSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2103da39e3ecSSrisivasubramanian S 2104da39e3ecSSrisivasubramanian S /* 2105da39e3ecSSrisivasubramanian S * Input Gather List 2106da39e3ecSSrisivasubramanian S */ 2107da39e3ecSSrisivasubramanian S i = 0; 2108da39e3ecSSrisivasubramanian S 2109da39e3ecSSrisivasubramanian S /* Offset control word followed by iv */ 2110da39e3ecSSrisivasubramanian S 2111da39e3ecSSrisivasubramanian S if (flags == 0x0) { 2112da39e3ecSSrisivasubramanian S inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 2113da39e3ecSSrisivasubramanian S outputlen = inputlen; 2114da39e3ecSSrisivasubramanian S /* iv offset is 0 */ 2115da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 21162a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16))) { 21172a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 21182a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 21192a6c7922SAnoob Joseph return; 21202a6c7922SAnoob Joseph } 2121da39e3ecSSrisivasubramanian S } else { 2122da39e3ecSSrisivasubramanian S inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 2123da39e3ecSSrisivasubramanian S outputlen = mac_len; 2124da39e3ecSSrisivasubramanian S /* iv offset is 0 */ 2125da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)auth_offset); 21262a6c7922SAnoob Joseph if (unlikely((auth_offset >> 8))) { 21272a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 21282a6c7922SAnoob Joseph CPT_LOG_DP_ERR("auth_offset: %d", auth_offset); 21292a6c7922SAnoob Joseph return; 21302a6c7922SAnoob Joseph } 2131da39e3ecSSrisivasubramanian S } 2132da39e3ecSSrisivasubramanian S 2133da39e3ecSSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2134da39e3ecSSrisivasubramanian S 2135da39e3ecSSrisivasubramanian S /* IV */ 2136da39e3ecSSrisivasubramanian S iv_d = (uint8_t *)offset_vaddr + OFF_CTRL_LEN; 2137da39e3ecSSrisivasubramanian S memcpy(iv_d, iv_s, iv_len); 2138da39e3ecSSrisivasubramanian S 2139da39e3ecSSrisivasubramanian S /* input data */ 2140da39e3ecSSrisivasubramanian S size = inputlen - iv_len; 2141da39e3ecSSrisivasubramanian S if (size) { 2142da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 2143da39e3ecSSrisivasubramanian S params->src_iov, 0, 2144da39e3ecSSrisivasubramanian S &size, NULL, 0); 2145da39e3ecSSrisivasubramanian S 2146f39928e6SAnoob Joseph if (unlikely(size)) { 2147f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2148f39928e6SAnoob Joseph " size %d needed", size); 2149f39928e6SAnoob Joseph return; 2150f39928e6SAnoob Joseph } 2151da39e3ecSSrisivasubramanian S } 2152da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2153da39e3ecSSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2154da39e3ecSSrisivasubramanian S 2155da39e3ecSSrisivasubramanian S /* 2156da39e3ecSSrisivasubramanian S * Output Scatter List 2157da39e3ecSSrisivasubramanian S */ 2158da39e3ecSSrisivasubramanian S 2159da39e3ecSSrisivasubramanian S i = 0; 2160da39e3ecSSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2161da39e3ecSSrisivasubramanian S 2162da39e3ecSSrisivasubramanian S if (flags == 0x1) { 2163da39e3ecSSrisivasubramanian S /* IV in SLIST only for F8 */ 2164da39e3ecSSrisivasubramanian S iv_len = 0; 2165da39e3ecSSrisivasubramanian S } 2166da39e3ecSSrisivasubramanian S 2167da39e3ecSSrisivasubramanian S /* IV */ 2168da39e3ecSSrisivasubramanian S if (iv_len) { 2169da39e3ecSSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 2170da39e3ecSSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 2171da39e3ecSSrisivasubramanian S iv_len); 2172da39e3ecSSrisivasubramanian S } 2173da39e3ecSSrisivasubramanian S 2174da39e3ecSSrisivasubramanian S /* Add output data */ 2175da39e3ecSSrisivasubramanian S if (req_flags & VALID_MAC_BUF) { 2176da39e3ecSSrisivasubramanian S size = outputlen - iv_len - mac_len; 2177da39e3ecSSrisivasubramanian S if (size) { 2178da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2179da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2180da39e3ecSSrisivasubramanian S &size, NULL, 0); 2181da39e3ecSSrisivasubramanian S 2182f39928e6SAnoob Joseph if (unlikely(size)) { 2183f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2184f39928e6SAnoob Joseph " size %d needed", size); 2185f39928e6SAnoob Joseph return; 2186f39928e6SAnoob Joseph } 2187da39e3ecSSrisivasubramanian S } 2188da39e3ecSSrisivasubramanian S 2189da39e3ecSSrisivasubramanian S /* mac data */ 2190da39e3ecSSrisivasubramanian S if (mac_len) { 2191da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_buf(scatter_comp, i, 2192da39e3ecSSrisivasubramanian S ¶ms->mac_buf); 2193da39e3ecSSrisivasubramanian S } 2194da39e3ecSSrisivasubramanian S } else { 2195da39e3ecSSrisivasubramanian S /* Output including mac */ 2196da39e3ecSSrisivasubramanian S size = outputlen - iv_len; 2197da39e3ecSSrisivasubramanian S if (size) { 2198da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2199da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2200da39e3ecSSrisivasubramanian S &size, NULL, 0); 2201da39e3ecSSrisivasubramanian S 2202f39928e6SAnoob Joseph if (unlikely(size)) { 2203f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2204f39928e6SAnoob Joseph " size %d needed", size); 2205f39928e6SAnoob Joseph return; 2206f39928e6SAnoob Joseph } 2207da39e3ecSSrisivasubramanian S } 2208da39e3ecSSrisivasubramanian S } 2209da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2210da39e3ecSSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2211da39e3ecSSrisivasubramanian S 2212da39e3ecSSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2213da39e3ecSSrisivasubramanian S 2214da39e3ecSSrisivasubramanian S /* This is DPTR len incase of SG mode */ 2215426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 2216da39e3ecSSrisivasubramanian S 2217da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2218da39e3ecSSrisivasubramanian S m_dma += size; 2219da39e3ecSSrisivasubramanian S 2220da39e3ecSSrisivasubramanian S /* cpt alternate completion address saved earlier */ 2221da39e3ecSSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2222da39e3ecSSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2223da39e3ecSSrisivasubramanian S rptr_dma = c_dma - 8; 2224da39e3ecSSrisivasubramanian S 2225da39e3ecSSrisivasubramanian S req->ist.ei1 = dptr_dma; 2226da39e3ecSSrisivasubramanian S req->ist.ei2 = rptr_dma; 2227da39e3ecSSrisivasubramanian S 2228da39e3ecSSrisivasubramanian S /* 16 byte aligned cpt res address */ 2229da39e3ecSSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2230da39e3ecSSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 2231da39e3ecSSrisivasubramanian S req->comp_baddr = c_dma; 2232da39e3ecSSrisivasubramanian S 2233da39e3ecSSrisivasubramanian S /* Fill microcode part of instruction */ 2234da39e3ecSSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 2235da39e3ecSSrisivasubramanian S 2236da39e3ecSSrisivasubramanian S req->op = op; 2237da39e3ecSSrisivasubramanian S 2238da39e3ecSSrisivasubramanian S *prep_req = req; 2239f39928e6SAnoob Joseph return; 2240da39e3ecSSrisivasubramanian S } 2241da39e3ecSSrisivasubramanian S 2242f39928e6SAnoob Joseph static __rte_always_inline void 2243da39e3ecSSrisivasubramanian S cpt_kasumi_dec_prep(uint64_t d_offs, 2244da39e3ecSSrisivasubramanian S uint64_t d_lens, 2245da39e3ecSSrisivasubramanian S fc_params_t *params, 2246da39e3ecSSrisivasubramanian S void *op, 2247da39e3ecSSrisivasubramanian S void **prep_req) 2248da39e3ecSSrisivasubramanian S { 2249da39e3ecSSrisivasubramanian S uint32_t size; 2250da39e3ecSSrisivasubramanian S int32_t inputlen = 0, outputlen; 2251da39e3ecSSrisivasubramanian S struct cpt_ctx *cpt_ctx; 2252da39e3ecSSrisivasubramanian S uint8_t i = 0, iv_len = 8; 2253da39e3ecSSrisivasubramanian S struct cpt_request_info *req; 2254da39e3ecSSrisivasubramanian S buf_ptr_t *buf_p; 2255da39e3ecSSrisivasubramanian S uint32_t encr_offset; 2256da39e3ecSSrisivasubramanian S uint32_t encr_data_len; 22578de5ede7SAnoob Joseph int flags; 2258da39e3ecSSrisivasubramanian S uint8_t dir = 0; 2259da39e3ecSSrisivasubramanian S void *m_vaddr, *c_vaddr; 2260da39e3ecSSrisivasubramanian S uint64_t m_dma, c_dma; 2261da39e3ecSSrisivasubramanian S uint64_t *offset_vaddr, offset_dma; 2262da39e3ecSSrisivasubramanian S vq_cmd_word0_t vq_cmd_w0; 2263da39e3ecSSrisivasubramanian S uint8_t *in_buffer; 2264da39e3ecSSrisivasubramanian S uint32_t g_size_bytes, s_size_bytes; 2265da39e3ecSSrisivasubramanian S uint64_t dptr_dma, rptr_dma; 2266da39e3ecSSrisivasubramanian S sg_comp_t *gather_comp; 2267da39e3ecSSrisivasubramanian S sg_comp_t *scatter_comp; 2268da39e3ecSSrisivasubramanian S 2269da39e3ecSSrisivasubramanian S buf_p = ¶ms->meta_buf; 2270da39e3ecSSrisivasubramanian S m_vaddr = buf_p->vaddr; 2271da39e3ecSSrisivasubramanian S m_dma = buf_p->dma_addr; 2272da39e3ecSSrisivasubramanian S 2273da39e3ecSSrisivasubramanian S encr_offset = ENCR_OFFSET(d_offs) / 8; 2274da39e3ecSSrisivasubramanian S encr_data_len = ENCR_DLEN(d_lens); 2275da39e3ecSSrisivasubramanian S 2276da39e3ecSSrisivasubramanian S cpt_ctx = params->ctx_buf.vaddr; 2277da39e3ecSSrisivasubramanian S flags = cpt_ctx->zsk_flags; 2278da39e3ecSSrisivasubramanian S /* 2279da39e3ecSSrisivasubramanian S * Save initial space that followed app data for completion code & 2280da39e3ecSSrisivasubramanian S * alternate completion code to fall in same cache line as app data 2281da39e3ecSSrisivasubramanian S */ 2282da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2283da39e3ecSSrisivasubramanian S m_dma += COMPLETION_CODE_SIZE; 2284da39e3ecSSrisivasubramanian S size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2285da39e3ecSSrisivasubramanian S (uint8_t *)m_vaddr; 2286da39e3ecSSrisivasubramanian S 2287da39e3ecSSrisivasubramanian S c_vaddr = (uint8_t *)m_vaddr + size; 2288da39e3ecSSrisivasubramanian S c_dma = m_dma + size; 2289da39e3ecSSrisivasubramanian S size += sizeof(cpt_res_s_t); 2290da39e3ecSSrisivasubramanian S 2291da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2292da39e3ecSSrisivasubramanian S m_dma += size; 2293da39e3ecSSrisivasubramanian S 2294da39e3ecSSrisivasubramanian S /* Reserve memory for cpt request info */ 2295da39e3ecSSrisivasubramanian S req = m_vaddr; 2296da39e3ecSSrisivasubramanian S 2297da39e3ecSSrisivasubramanian S size = sizeof(struct cpt_request_info); 2298da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2299da39e3ecSSrisivasubramanian S m_dma += size; 2300da39e3ecSSrisivasubramanian S 2301629ac988SArchana Muniganti vq_cmd_w0.u64 = 0; 2302629ac988SArchana Muniganti vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2303da39e3ecSSrisivasubramanian S 2304da39e3ecSSrisivasubramanian S /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2305629ac988SArchana Muniganti vq_cmd_w0.s.opcode.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2306da39e3ecSSrisivasubramanian S (dir << 4) | (0 << 3) | (flags & 0x7)); 2307da39e3ecSSrisivasubramanian S 2308da39e3ecSSrisivasubramanian S /* 2309da39e3ecSSrisivasubramanian S * GP op header, lengths are expected in bits. 2310da39e3ecSSrisivasubramanian S */ 2311426af86bSAnoob Joseph vq_cmd_w0.s.param1 = encr_data_len; 2312da39e3ecSSrisivasubramanian S 2313da39e3ecSSrisivasubramanian S /* consider iv len */ 2314da39e3ecSSrisivasubramanian S encr_offset += iv_len; 2315da39e3ecSSrisivasubramanian S 2316d937e872SAnoob Joseph inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 2317da39e3ecSSrisivasubramanian S outputlen = inputlen; 2318da39e3ecSSrisivasubramanian S 2319da39e3ecSSrisivasubramanian S /* save space for offset ctrl & iv */ 2320da39e3ecSSrisivasubramanian S offset_vaddr = m_vaddr; 2321da39e3ecSSrisivasubramanian S offset_dma = m_dma; 2322da39e3ecSSrisivasubramanian S 2323da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2324da39e3ecSSrisivasubramanian S m_dma += OFF_CTRL_LEN + iv_len; 2325da39e3ecSSrisivasubramanian S 2326da39e3ecSSrisivasubramanian S /* DPTR has SG list */ 2327da39e3ecSSrisivasubramanian S in_buffer = m_vaddr; 2328da39e3ecSSrisivasubramanian S dptr_dma = m_dma; 2329da39e3ecSSrisivasubramanian S 2330da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[0] = 0; 2331da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[1] = 0; 2332da39e3ecSSrisivasubramanian S 2333da39e3ecSSrisivasubramanian S /* TODO Add error check if space will be sufficient */ 2334da39e3ecSSrisivasubramanian S gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2335da39e3ecSSrisivasubramanian S 2336da39e3ecSSrisivasubramanian S /* 2337da39e3ecSSrisivasubramanian S * Input Gather List 2338da39e3ecSSrisivasubramanian S */ 2339da39e3ecSSrisivasubramanian S i = 0; 2340da39e3ecSSrisivasubramanian S 2341da39e3ecSSrisivasubramanian S /* Offset control word followed by iv */ 2342da39e3ecSSrisivasubramanian S *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 23432a6c7922SAnoob Joseph if (unlikely((encr_offset >> 16))) { 23442a6c7922SAnoob Joseph CPT_LOG_DP_ERR("Offset not supported"); 23452a6c7922SAnoob Joseph CPT_LOG_DP_ERR("enc_offset: %d", encr_offset); 23462a6c7922SAnoob Joseph return; 23472a6c7922SAnoob Joseph } 2348da39e3ecSSrisivasubramanian S 2349da39e3ecSSrisivasubramanian S i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2350da39e3ecSSrisivasubramanian S 2351da39e3ecSSrisivasubramanian S /* IV */ 2352da39e3ecSSrisivasubramanian S memcpy((uint8_t *)offset_vaddr + OFF_CTRL_LEN, 2353da39e3ecSSrisivasubramanian S params->iv_buf, iv_len); 2354da39e3ecSSrisivasubramanian S 2355da39e3ecSSrisivasubramanian S /* Add input data */ 2356da39e3ecSSrisivasubramanian S size = inputlen - iv_len; 2357da39e3ecSSrisivasubramanian S if (size) { 2358da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(gather_comp, i, 2359da39e3ecSSrisivasubramanian S params->src_iov, 2360da39e3ecSSrisivasubramanian S 0, &size, NULL, 0); 2361f39928e6SAnoob Joseph if (unlikely(size)) { 2362f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2363f39928e6SAnoob Joseph " size %d needed", size); 2364f39928e6SAnoob Joseph return; 2365f39928e6SAnoob Joseph } 2366da39e3ecSSrisivasubramanian S } 2367da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2368da39e3ecSSrisivasubramanian S g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2369da39e3ecSSrisivasubramanian S 2370da39e3ecSSrisivasubramanian S /* 2371da39e3ecSSrisivasubramanian S * Output Scatter List 2372da39e3ecSSrisivasubramanian S */ 2373da39e3ecSSrisivasubramanian S 2374da39e3ecSSrisivasubramanian S i = 0; 2375da39e3ecSSrisivasubramanian S scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2376da39e3ecSSrisivasubramanian S 2377da39e3ecSSrisivasubramanian S /* IV */ 2378da39e3ecSSrisivasubramanian S i = fill_sg_comp(scatter_comp, i, 2379da39e3ecSSrisivasubramanian S offset_dma + OFF_CTRL_LEN, 2380da39e3ecSSrisivasubramanian S iv_len); 2381da39e3ecSSrisivasubramanian S 2382da39e3ecSSrisivasubramanian S /* Add output data */ 2383da39e3ecSSrisivasubramanian S size = outputlen - iv_len; 2384da39e3ecSSrisivasubramanian S if (size) { 2385da39e3ecSSrisivasubramanian S i = fill_sg_comp_from_iov(scatter_comp, i, 2386da39e3ecSSrisivasubramanian S params->dst_iov, 0, 2387da39e3ecSSrisivasubramanian S &size, NULL, 0); 2388f39928e6SAnoob Joseph if (unlikely(size)) { 2389f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Insufficient buffer space," 2390f39928e6SAnoob Joseph " size %d needed", size); 2391f39928e6SAnoob Joseph return; 2392f39928e6SAnoob Joseph } 2393da39e3ecSSrisivasubramanian S } 2394da39e3ecSSrisivasubramanian S ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2395da39e3ecSSrisivasubramanian S s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2396da39e3ecSSrisivasubramanian S 2397da39e3ecSSrisivasubramanian S size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2398da39e3ecSSrisivasubramanian S 2399da39e3ecSSrisivasubramanian S /* This is DPTR len incase of SG mode */ 2400426af86bSAnoob Joseph vq_cmd_w0.s.dlen = size; 2401da39e3ecSSrisivasubramanian S 2402da39e3ecSSrisivasubramanian S m_vaddr = (uint8_t *)m_vaddr + size; 2403da39e3ecSSrisivasubramanian S m_dma += size; 2404da39e3ecSSrisivasubramanian S 2405da39e3ecSSrisivasubramanian S /* cpt alternate completion address saved earlier */ 2406da39e3ecSSrisivasubramanian S req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2407da39e3ecSSrisivasubramanian S *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2408da39e3ecSSrisivasubramanian S rptr_dma = c_dma - 8; 2409da39e3ecSSrisivasubramanian S 2410da39e3ecSSrisivasubramanian S req->ist.ei1 = dptr_dma; 2411da39e3ecSSrisivasubramanian S req->ist.ei2 = rptr_dma; 2412da39e3ecSSrisivasubramanian S 2413da39e3ecSSrisivasubramanian S /* 16 byte aligned cpt res address */ 2414da39e3ecSSrisivasubramanian S req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2415da39e3ecSSrisivasubramanian S *req->completion_addr = COMPLETION_CODE_INIT; 2416da39e3ecSSrisivasubramanian S req->comp_baddr = c_dma; 2417da39e3ecSSrisivasubramanian S 2418da39e3ecSSrisivasubramanian S /* Fill microcode part of instruction */ 2419da39e3ecSSrisivasubramanian S req->ist.ei0 = vq_cmd_w0.u64; 2420da39e3ecSSrisivasubramanian S 2421da39e3ecSSrisivasubramanian S req->op = op; 2422da39e3ecSSrisivasubramanian S 2423da39e3ecSSrisivasubramanian S *prep_req = req; 2424f39928e6SAnoob Joseph return; 2425da39e3ecSSrisivasubramanian S } 2426da39e3ecSSrisivasubramanian S 2427177b41ceSRagothaman Jayaraman static __rte_always_inline void * 2428177b41ceSRagothaman Jayaraman cpt_fc_dec_hmac_prep(uint32_t flags, 2429177b41ceSRagothaman Jayaraman uint64_t d_offs, 2430177b41ceSRagothaman Jayaraman uint64_t d_lens, 2431177b41ceSRagothaman Jayaraman fc_params_t *fc_params, 2432f39928e6SAnoob Joseph void *op) 2433177b41ceSRagothaman Jayaraman { 2434177b41ceSRagothaman Jayaraman struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2435177b41ceSRagothaman Jayaraman uint8_t fc_type; 2436177b41ceSRagothaman Jayaraman void *prep_req = NULL; 2437177b41ceSRagothaman Jayaraman 2438177b41ceSRagothaman Jayaraman fc_type = ctx->fc_type; 2439177b41ceSRagothaman Jayaraman 2440177b41ceSRagothaman Jayaraman if (likely(fc_type == FC_GEN)) { 2441f39928e6SAnoob Joseph cpt_dec_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2442da39e3ecSSrisivasubramanian S &prep_req); 2443f39928e6SAnoob Joseph } else if (fc_type == ZUC_SNOW3G) { 2444f39928e6SAnoob Joseph cpt_zuc_snow3g_dec_prep(flags, d_offs, d_lens, fc_params, op, 2445f39928e6SAnoob Joseph &prep_req); 2446f39928e6SAnoob Joseph } else if (fc_type == KASUMI) { 2447f39928e6SAnoob Joseph cpt_kasumi_dec_prep(d_offs, d_lens, fc_params, op, &prep_req); 2448f39928e6SAnoob Joseph } 2449f39928e6SAnoob Joseph 2450177b41ceSRagothaman Jayaraman /* 2451177b41ceSRagothaman Jayaraman * For AUTH_ONLY case, 2452177b41ceSRagothaman Jayaraman * MC only supports digest generation and verification 2453177b41ceSRagothaman Jayaraman * should be done in software by memcmp() 2454177b41ceSRagothaman Jayaraman */ 2455177b41ceSRagothaman Jayaraman 2456177b41ceSRagothaman Jayaraman return prep_req; 2457177b41ceSRagothaman Jayaraman } 2458177b41ceSRagothaman Jayaraman 2459e3866e73SThomas Monjalon static __rte_always_inline void *__rte_hot 2460b74652f3SRagothaman Jayaraman cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens, 2461f39928e6SAnoob Joseph fc_params_t *fc_params, void *op) 2462b74652f3SRagothaman Jayaraman { 2463b74652f3SRagothaman Jayaraman struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2464b74652f3SRagothaman Jayaraman uint8_t fc_type; 2465b74652f3SRagothaman Jayaraman void *prep_req = NULL; 2466b74652f3SRagothaman Jayaraman 2467b74652f3SRagothaman Jayaraman fc_type = ctx->fc_type; 2468b74652f3SRagothaman Jayaraman 2469b74652f3SRagothaman Jayaraman /* Common api for rest of the ops */ 2470b74652f3SRagothaman Jayaraman if (likely(fc_type == FC_GEN)) { 2471f39928e6SAnoob Joseph cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2472351fbee2SSrisivasubramanian S &prep_req); 2473f39928e6SAnoob Joseph } else if (fc_type == ZUC_SNOW3G) { 2474f39928e6SAnoob Joseph cpt_zuc_snow3g_enc_prep(flags, d_offs, d_lens, fc_params, op, 2475f39928e6SAnoob Joseph &prep_req); 2476f39928e6SAnoob Joseph } else if (fc_type == KASUMI) { 2477f39928e6SAnoob Joseph cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, op, 2478f39928e6SAnoob Joseph &prep_req); 2479f39928e6SAnoob Joseph } else if (fc_type == HASH_HMAC) { 2480f39928e6SAnoob Joseph cpt_digest_gen_prep(flags, d_lens, fc_params, op, &prep_req); 2481b74652f3SRagothaman Jayaraman } 2482b74652f3SRagothaman Jayaraman 2483b74652f3SRagothaman Jayaraman return prep_req; 2484b74652f3SRagothaman Jayaraman } 2485b74652f3SRagothaman Jayaraman 24866cc54096SNithin Dabilpuram static __rte_always_inline int 24876045c06aSArchana Muniganti cpt_fc_auth_set_key(struct cpt_ctx *cpt_ctx, auth_type_t type, 24886045c06aSArchana Muniganti const uint8_t *key, uint16_t key_len, uint16_t mac_len) 24896cc54096SNithin Dabilpuram { 24906045c06aSArchana Muniganti mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx; 24916045c06aSArchana Muniganti mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx; 24926045c06aSArchana Muniganti mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx; 24936cc54096SNithin Dabilpuram 24946cc54096SNithin Dabilpuram if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) { 24956cc54096SNithin Dabilpuram uint32_t keyx[4]; 24966cc54096SNithin Dabilpuram 24976cc54096SNithin Dabilpuram if (key_len != 16) 24986cc54096SNithin Dabilpuram return -1; 24996cc54096SNithin Dabilpuram /* No support for AEAD yet */ 25006cc54096SNithin Dabilpuram if (cpt_ctx->enc_cipher) 25016cc54096SNithin Dabilpuram return -1; 25026cc54096SNithin Dabilpuram /* For ZUC/SNOW3G/Kasumi */ 25036cc54096SNithin Dabilpuram switch (type) { 25046cc54096SNithin Dabilpuram case SNOW3G_UIA2: 25056cc54096SNithin Dabilpuram cpt_ctx->snow3g = 1; 25066cc54096SNithin Dabilpuram gen_key_snow3g(key, keyx); 25076045c06aSArchana Muniganti memcpy(zs_ctx->ci_key, keyx, key_len); 25086cc54096SNithin Dabilpuram cpt_ctx->fc_type = ZUC_SNOW3G; 25096cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 25106cc54096SNithin Dabilpuram break; 25116cc54096SNithin Dabilpuram case ZUC_EIA3: 25126cc54096SNithin Dabilpuram cpt_ctx->snow3g = 0; 25136045c06aSArchana Muniganti memcpy(zs_ctx->ci_key, key, key_len); 25146045c06aSArchana Muniganti memcpy(zs_ctx->zuc_const, zuc_d, 32); 25156cc54096SNithin Dabilpuram cpt_ctx->fc_type = ZUC_SNOW3G; 25166cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 25176cc54096SNithin Dabilpuram break; 25186cc54096SNithin Dabilpuram case KASUMI_F9_ECB: 25196cc54096SNithin Dabilpuram /* Kasumi ECB mode */ 25206cc54096SNithin Dabilpuram cpt_ctx->k_ecb = 1; 25216045c06aSArchana Muniganti memcpy(k_ctx->ci_key, key, key_len); 25226cc54096SNithin Dabilpuram cpt_ctx->fc_type = KASUMI; 25236cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 25246cc54096SNithin Dabilpuram break; 25256cc54096SNithin Dabilpuram case KASUMI_F9_CBC: 25266045c06aSArchana Muniganti memcpy(k_ctx->ci_key, key, key_len); 25276cc54096SNithin Dabilpuram cpt_ctx->fc_type = KASUMI; 25286cc54096SNithin Dabilpuram cpt_ctx->zsk_flags = 0x1; 25296cc54096SNithin Dabilpuram break; 25306cc54096SNithin Dabilpuram default: 25316cc54096SNithin Dabilpuram return -1; 25326cc54096SNithin Dabilpuram } 25336cc54096SNithin Dabilpuram cpt_ctx->mac_len = 4; 25346cc54096SNithin Dabilpuram cpt_ctx->hash_type = type; 25356cc54096SNithin Dabilpuram return 0; 25366cc54096SNithin Dabilpuram } 25376cc54096SNithin Dabilpuram 25386cc54096SNithin Dabilpuram if (!(cpt_ctx->fc_type == FC_GEN && !type)) { 25396cc54096SNithin Dabilpuram if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher) 25406cc54096SNithin Dabilpuram cpt_ctx->fc_type = HASH_HMAC; 25416cc54096SNithin Dabilpuram } 25426cc54096SNithin Dabilpuram 25432839a8abSSucharitha Sarananaga if (cpt_ctx->fc_type == FC_GEN && key_len > 64) 25442839a8abSSucharitha Sarananaga return -1; 25452839a8abSSucharitha Sarananaga 25466cc54096SNithin Dabilpuram /* For GMAC auth, cipher must be NULL */ 25476cc54096SNithin Dabilpuram if (type == GMAC_TYPE) 2548c3d0bc45SAnoob Joseph fctx->enc.enc_cipher = 0; 25496cc54096SNithin Dabilpuram 2550c3d0bc45SAnoob Joseph fctx->enc.hash_type = cpt_ctx->hash_type = type; 2551c3d0bc45SAnoob Joseph fctx->enc.mac_len = cpt_ctx->mac_len = mac_len; 25526cc54096SNithin Dabilpuram 25536cc54096SNithin Dabilpuram if (key_len) { 25546cc54096SNithin Dabilpuram cpt_ctx->hmac = 1; 2555db06451bSAnoob Joseph 2556db06451bSAnoob Joseph cpt_ctx->auth_key = rte_zmalloc(NULL, key_len, 8); 2557db06451bSAnoob Joseph if (cpt_ctx->auth_key == NULL) 2558db06451bSAnoob Joseph return -1; 2559db06451bSAnoob Joseph 2560db06451bSAnoob Joseph cpt_ctx->auth_key_iova = rte_mem_virt2iova(cpt_ctx->auth_key); 25616cc54096SNithin Dabilpuram memcpy(cpt_ctx->auth_key, key, key_len); 25626cc54096SNithin Dabilpuram cpt_ctx->auth_key_len = key_len; 25636cc54096SNithin Dabilpuram memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 25646cc54096SNithin Dabilpuram memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad)); 25652839a8abSSucharitha Sarananaga 25662839a8abSSucharitha Sarananaga if (key_len <= 64) 25676cc54096SNithin Dabilpuram memcpy(fctx->hmac.opad, key, key_len); 2568c3d0bc45SAnoob Joseph fctx->enc.auth_input_type = 1; 25696cc54096SNithin Dabilpuram } 25706cc54096SNithin Dabilpuram return 0; 25716cc54096SNithin Dabilpuram } 25726cc54096SNithin Dabilpuram 25736cc54096SNithin Dabilpuram static __rte_always_inline int 25746cc54096SNithin Dabilpuram fill_sess_aead(struct rte_crypto_sym_xform *xform, 25756cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 25766cc54096SNithin Dabilpuram { 25776cc54096SNithin Dabilpuram struct rte_crypto_aead_xform *aead_form; 25786cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 25796cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 25806cc54096SNithin Dabilpuram uint32_t cipher_key_len = 0; 25818de5ede7SAnoob Joseph uint8_t aes_gcm = 0; 25826cc54096SNithin Dabilpuram aead_form = &xform->aead; 25838de5ede7SAnoob Joseph void *ctx = SESS_PRIV(sess); 25846cc54096SNithin Dabilpuram 2585cb7842f2STejasree Kondoj if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { 25866cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 25876cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_GENERATE; 2588cb7842f2STejasree Kondoj } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) { 25896cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 25906cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_VERIFY; 25916cc54096SNithin Dabilpuram } else { 2592*f665790aSDavid Marchand CPT_LOG_DP_ERR("Unknown aead operation"); 25936cc54096SNithin Dabilpuram return -1; 25946cc54096SNithin Dabilpuram } 25956cc54096SNithin Dabilpuram switch (aead_form->algo) { 25966cc54096SNithin Dabilpuram case RTE_CRYPTO_AEAD_AES_GCM: 25976cc54096SNithin Dabilpuram enc_type = AES_GCM; 25986cc54096SNithin Dabilpuram cipher_key_len = 16; 25996cc54096SNithin Dabilpuram aes_gcm = 1; 26006cc54096SNithin Dabilpuram break; 26016cc54096SNithin Dabilpuram case RTE_CRYPTO_AEAD_AES_CCM: 26026cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 26036cc54096SNithin Dabilpuram aead_form->algo); 26046cc54096SNithin Dabilpuram return -1; 2605cb7842f2STejasree Kondoj case RTE_CRYPTO_AEAD_CHACHA20_POLY1305: 2606cb7842f2STejasree Kondoj enc_type = CHACHA20; 2607cb7842f2STejasree Kondoj auth_type = POLY1305; 2608cb7842f2STejasree Kondoj cipher_key_len = 32; 2609cb7842f2STejasree Kondoj sess->chacha_poly = 1; 2610cb7842f2STejasree Kondoj break; 26116cc54096SNithin Dabilpuram default: 26126cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 26136cc54096SNithin Dabilpuram aead_form->algo); 26146cc54096SNithin Dabilpuram return -1; 26156cc54096SNithin Dabilpuram } 26166cc54096SNithin Dabilpuram if (aead_form->key.length < cipher_key_len) { 26176cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 26186cc54096SNithin Dabilpuram (unsigned int long)aead_form->key.length); 26196cc54096SNithin Dabilpuram return -1; 26206cc54096SNithin Dabilpuram } 26218de5ede7SAnoob Joseph sess->zsk_flag = 0; 26226cc54096SNithin Dabilpuram sess->aes_gcm = aes_gcm; 26236cc54096SNithin Dabilpuram sess->mac_len = aead_form->digest_length; 26246cc54096SNithin Dabilpuram sess->iv_offset = aead_form->iv.offset; 26256cc54096SNithin Dabilpuram sess->iv_length = aead_form->iv.length; 26266cc54096SNithin Dabilpuram sess->aad_length = aead_form->aad_length; 26276cc54096SNithin Dabilpuram 2628e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data, 2629e40175c5SArchana Muniganti aead_form->key.length, NULL))) 2630e40175c5SArchana Muniganti return -1; 26316cc54096SNithin Dabilpuram 2632e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2633e40175c5SArchana Muniganti aead_form->digest_length))) 2634e40175c5SArchana Muniganti return -1; 26356cc54096SNithin Dabilpuram 26366cc54096SNithin Dabilpuram return 0; 26376cc54096SNithin Dabilpuram } 26386cc54096SNithin Dabilpuram 26396cc54096SNithin Dabilpuram static __rte_always_inline int 26406cc54096SNithin Dabilpuram fill_sess_cipher(struct rte_crypto_sym_xform *xform, 26416cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 26426cc54096SNithin Dabilpuram { 26436cc54096SNithin Dabilpuram struct rte_crypto_cipher_xform *c_form; 2644de5eb0a6STejasree Kondoj struct cpt_ctx *ctx = SESS_PRIV(sess); 26456cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 26466cc54096SNithin Dabilpuram uint32_t cipher_key_len = 0; 26478de5ede7SAnoob Joseph uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0; 26486cc54096SNithin Dabilpuram 26496cc54096SNithin Dabilpuram c_form = &xform->cipher; 26506cc54096SNithin Dabilpuram 26516cc54096SNithin Dabilpuram if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 26526cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 2653de5eb0a6STejasree Kondoj else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { 26546cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 2655de5eb0a6STejasree Kondoj if (xform->next != NULL && 2656de5eb0a6STejasree Kondoj xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 2657de5eb0a6STejasree Kondoj /* Perform decryption followed by auth verify */ 2658de5eb0a6STejasree Kondoj ctx->dec_auth = 1; 2659de5eb0a6STejasree Kondoj } 2660de5eb0a6STejasree Kondoj } else { 2661*f665790aSDavid Marchand CPT_LOG_DP_ERR("Unknown cipher operation"); 26626cc54096SNithin Dabilpuram return -1; 26636cc54096SNithin Dabilpuram } 26646cc54096SNithin Dabilpuram 26656cc54096SNithin Dabilpuram switch (c_form->algo) { 26666cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_CBC: 26676cc54096SNithin Dabilpuram enc_type = AES_CBC; 26686cc54096SNithin Dabilpuram cipher_key_len = 16; 26696cc54096SNithin Dabilpuram break; 26706cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_CBC: 26716cc54096SNithin Dabilpuram enc_type = DES3_CBC; 26726cc54096SNithin Dabilpuram cipher_key_len = 24; 26736cc54096SNithin Dabilpuram break; 26746cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_DES_CBC: 26756cc54096SNithin Dabilpuram /* DES is implemented using 3DES in hardware */ 26766cc54096SNithin Dabilpuram enc_type = DES3_CBC; 26776cc54096SNithin Dabilpuram cipher_key_len = 8; 26786cc54096SNithin Dabilpuram break; 26796cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_CTR: 26806cc54096SNithin Dabilpuram enc_type = AES_CTR; 26816cc54096SNithin Dabilpuram cipher_key_len = 16; 26826cc54096SNithin Dabilpuram aes_ctr = 1; 26836cc54096SNithin Dabilpuram break; 26846cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_NULL: 26856cc54096SNithin Dabilpuram enc_type = 0; 26866cc54096SNithin Dabilpuram is_null = 1; 26876cc54096SNithin Dabilpuram break; 26886cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_KASUMI_F8: 26896cc54096SNithin Dabilpuram enc_type = KASUMI_F8_ECB; 26906cc54096SNithin Dabilpuram cipher_key_len = 16; 26916cc54096SNithin Dabilpuram zsk_flag = K_F8; 26926cc54096SNithin Dabilpuram break; 26936cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: 26946cc54096SNithin Dabilpuram enc_type = SNOW3G_UEA2; 26956cc54096SNithin Dabilpuram cipher_key_len = 16; 26966cc54096SNithin Dabilpuram zsk_flag = ZS_EA; 26976cc54096SNithin Dabilpuram break; 26986cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_ZUC_EEA3: 26996cc54096SNithin Dabilpuram enc_type = ZUC_EEA3; 27006cc54096SNithin Dabilpuram cipher_key_len = 16; 27016cc54096SNithin Dabilpuram zsk_flag = ZS_EA; 27026cc54096SNithin Dabilpuram break; 27036cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_XTS: 27046cc54096SNithin Dabilpuram enc_type = AES_XTS; 27056cc54096SNithin Dabilpuram cipher_key_len = 16; 27066cc54096SNithin Dabilpuram break; 27076cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_ECB: 27086cc54096SNithin Dabilpuram enc_type = DES3_ECB; 27096cc54096SNithin Dabilpuram cipher_key_len = 24; 27106cc54096SNithin Dabilpuram break; 27116cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_ECB: 27126cc54096SNithin Dabilpuram enc_type = AES_ECB; 27136cc54096SNithin Dabilpuram cipher_key_len = 16; 27146cc54096SNithin Dabilpuram break; 27156cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_3DES_CTR: 27166cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_AES_F8: 27176cc54096SNithin Dabilpuram case RTE_CRYPTO_CIPHER_ARC4: 27186cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 27196cc54096SNithin Dabilpuram c_form->algo); 27206cc54096SNithin Dabilpuram return -1; 27216cc54096SNithin Dabilpuram default: 27226cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 27236cc54096SNithin Dabilpuram c_form->algo); 27246cc54096SNithin Dabilpuram return -1; 27256cc54096SNithin Dabilpuram } 27266cc54096SNithin Dabilpuram 27276cc54096SNithin Dabilpuram if (c_form->key.length < cipher_key_len) { 27286cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 27296cc54096SNithin Dabilpuram (unsigned long) c_form->key.length); 27306cc54096SNithin Dabilpuram return -1; 27316cc54096SNithin Dabilpuram } 27326cc54096SNithin Dabilpuram 27336cc54096SNithin Dabilpuram sess->zsk_flag = zsk_flag; 27348de5ede7SAnoob Joseph sess->aes_gcm = 0; 27356cc54096SNithin Dabilpuram sess->aes_ctr = aes_ctr; 27366cc54096SNithin Dabilpuram sess->iv_offset = c_form->iv.offset; 27376cc54096SNithin Dabilpuram sess->iv_length = c_form->iv.length; 27386cc54096SNithin Dabilpuram sess->is_null = is_null; 27396cc54096SNithin Dabilpuram 2740e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type, 2741e40175c5SArchana Muniganti c_form->key.data, c_form->key.length, NULL))) 2742e40175c5SArchana Muniganti return -1; 27436cc54096SNithin Dabilpuram 27446cc54096SNithin Dabilpuram return 0; 27456cc54096SNithin Dabilpuram } 27466cc54096SNithin Dabilpuram 27476cc54096SNithin Dabilpuram static __rte_always_inline int 27486cc54096SNithin Dabilpuram fill_sess_auth(struct rte_crypto_sym_xform *xform, 27496cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 27506cc54096SNithin Dabilpuram { 2751de5eb0a6STejasree Kondoj struct cpt_ctx *ctx = SESS_PRIV(sess); 27526cc54096SNithin Dabilpuram struct rte_crypto_auth_xform *a_form; 27536cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 27546cc54096SNithin Dabilpuram uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0; 27556cc54096SNithin Dabilpuram 2756de5eb0a6STejasree Kondoj if (xform->next != NULL && 2757de5eb0a6STejasree Kondoj xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 2758de5eb0a6STejasree Kondoj xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { 2759de5eb0a6STejasree Kondoj /* Perform auth followed by encryption */ 2760de5eb0a6STejasree Kondoj ctx->auth_enc = 1; 2761de5eb0a6STejasree Kondoj } 2762de5eb0a6STejasree Kondoj 27636cc54096SNithin Dabilpuram a_form = &xform->auth; 27646cc54096SNithin Dabilpuram 27656cc54096SNithin Dabilpuram if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 27666cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_VERIFY; 27676cc54096SNithin Dabilpuram else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 27686cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_AUTH_GENERATE; 27696cc54096SNithin Dabilpuram else { 27706cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Unknown auth operation"); 27716cc54096SNithin Dabilpuram return -1; 27726cc54096SNithin Dabilpuram } 27736cc54096SNithin Dabilpuram 27746cc54096SNithin Dabilpuram switch (a_form->algo) { 27756cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA1_HMAC: 27766cc54096SNithin Dabilpuram /* Fall through */ 27776cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA1: 27786cc54096SNithin Dabilpuram auth_type = SHA1_TYPE; 27796cc54096SNithin Dabilpuram break; 27806cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA256_HMAC: 27816cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA256: 27826cc54096SNithin Dabilpuram auth_type = SHA2_SHA256; 27836cc54096SNithin Dabilpuram break; 27846cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA512_HMAC: 27856cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA512: 27866cc54096SNithin Dabilpuram auth_type = SHA2_SHA512; 27876cc54096SNithin Dabilpuram break; 27886cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_GMAC: 27896cc54096SNithin Dabilpuram auth_type = GMAC_TYPE; 27906cc54096SNithin Dabilpuram aes_gcm = 1; 27916cc54096SNithin Dabilpuram break; 27926cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA224_HMAC: 27936cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA224: 27946cc54096SNithin Dabilpuram auth_type = SHA2_SHA224; 27956cc54096SNithin Dabilpuram break; 27966cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA384_HMAC: 27976cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SHA384: 27986cc54096SNithin Dabilpuram auth_type = SHA2_SHA384; 27996cc54096SNithin Dabilpuram break; 28006cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_MD5_HMAC: 28016cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_MD5: 28026cc54096SNithin Dabilpuram auth_type = MD5_TYPE; 28036cc54096SNithin Dabilpuram break; 28046cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_KASUMI_F9: 28056cc54096SNithin Dabilpuram auth_type = KASUMI_F9_ECB; 28066cc54096SNithin Dabilpuram /* 28076cc54096SNithin Dabilpuram * Indicate that direction needs to be taken out 28086cc54096SNithin Dabilpuram * from end of src 28096cc54096SNithin Dabilpuram */ 28106cc54096SNithin Dabilpuram zsk_flag = K_F9; 28116cc54096SNithin Dabilpuram break; 28126cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_SNOW3G_UIA2: 28136cc54096SNithin Dabilpuram auth_type = SNOW3G_UIA2; 28146cc54096SNithin Dabilpuram zsk_flag = ZS_IA; 28156cc54096SNithin Dabilpuram break; 28166cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_ZUC_EIA3: 28176cc54096SNithin Dabilpuram auth_type = ZUC_EIA3; 28186cc54096SNithin Dabilpuram zsk_flag = ZS_IA; 28196cc54096SNithin Dabilpuram break; 28206cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_NULL: 28216cc54096SNithin Dabilpuram auth_type = 0; 28226cc54096SNithin Dabilpuram is_null = 1; 28236cc54096SNithin Dabilpuram break; 28246cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 28256cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_CMAC: 28266cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_CBC_MAC: 28276cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u", 28286cc54096SNithin Dabilpuram a_form->algo); 28298de5ede7SAnoob Joseph return -1; 28306cc54096SNithin Dabilpuram default: 28316cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified", 28326cc54096SNithin Dabilpuram a_form->algo); 28338de5ede7SAnoob Joseph return -1; 28346cc54096SNithin Dabilpuram } 28356cc54096SNithin Dabilpuram 28366cc54096SNithin Dabilpuram sess->zsk_flag = zsk_flag; 28376cc54096SNithin Dabilpuram sess->aes_gcm = aes_gcm; 28386cc54096SNithin Dabilpuram sess->mac_len = a_form->digest_length; 28396cc54096SNithin Dabilpuram sess->is_null = is_null; 28406cc54096SNithin Dabilpuram if (zsk_flag) { 28416cc54096SNithin Dabilpuram sess->auth_iv_offset = a_form->iv.offset; 28426cc54096SNithin Dabilpuram sess->auth_iv_length = a_form->iv.length; 28436cc54096SNithin Dabilpuram } 2844e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type, 2845e40175c5SArchana Muniganti a_form->key.data, a_form->key.length, 2846e40175c5SArchana Muniganti a_form->digest_length))) 2847e40175c5SArchana Muniganti return -1; 28486cc54096SNithin Dabilpuram 28496cc54096SNithin Dabilpuram return 0; 28506cc54096SNithin Dabilpuram } 28516cc54096SNithin Dabilpuram 28526cc54096SNithin Dabilpuram static __rte_always_inline int 28536cc54096SNithin Dabilpuram fill_sess_gmac(struct rte_crypto_sym_xform *xform, 28546cc54096SNithin Dabilpuram struct cpt_sess_misc *sess) 28556cc54096SNithin Dabilpuram { 28566cc54096SNithin Dabilpuram struct rte_crypto_auth_xform *a_form; 28576cc54096SNithin Dabilpuram cipher_type_t enc_type = 0; /* NULL Cipher type */ 28586cc54096SNithin Dabilpuram auth_type_t auth_type = 0; /* NULL Auth type */ 28598de5ede7SAnoob Joseph void *ctx = SESS_PRIV(sess); 28606cc54096SNithin Dabilpuram 28616cc54096SNithin Dabilpuram a_form = &xform->auth; 28626cc54096SNithin Dabilpuram 28636cc54096SNithin Dabilpuram if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 28646cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_ENCODE; 28656cc54096SNithin Dabilpuram else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 28666cc54096SNithin Dabilpuram sess->cpt_op |= CPT_OP_DECODE; 28676cc54096SNithin Dabilpuram else { 28686cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Unknown auth operation"); 28696cc54096SNithin Dabilpuram return -1; 28706cc54096SNithin Dabilpuram } 28716cc54096SNithin Dabilpuram 28726cc54096SNithin Dabilpuram switch (a_form->algo) { 28736cc54096SNithin Dabilpuram case RTE_CRYPTO_AUTH_AES_GMAC: 28746cc54096SNithin Dabilpuram enc_type = AES_GCM; 28756cc54096SNithin Dabilpuram auth_type = GMAC_TYPE; 28766cc54096SNithin Dabilpuram break; 28776cc54096SNithin Dabilpuram default: 28786cc54096SNithin Dabilpuram CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 28796cc54096SNithin Dabilpuram a_form->algo); 28806cc54096SNithin Dabilpuram return -1; 28816cc54096SNithin Dabilpuram } 28826cc54096SNithin Dabilpuram 28838de5ede7SAnoob Joseph sess->zsk_flag = 0; 28848de5ede7SAnoob Joseph sess->aes_gcm = 0; 28856cc54096SNithin Dabilpuram sess->is_gmac = 1; 28866cc54096SNithin Dabilpuram sess->iv_offset = a_form->iv.offset; 28876cc54096SNithin Dabilpuram sess->iv_length = a_form->iv.length; 28886cc54096SNithin Dabilpuram sess->mac_len = a_form->digest_length; 28896cc54096SNithin Dabilpuram 2890e40175c5SArchana Muniganti if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data, 2891e40175c5SArchana Muniganti a_form->key.length, NULL))) 2892e40175c5SArchana Muniganti return -1; 2893e40175c5SArchana Muniganti 2894e40175c5SArchana Muniganti if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2895e40175c5SArchana Muniganti a_form->digest_length))) 2896e40175c5SArchana Muniganti return -1; 28976cc54096SNithin Dabilpuram 28986cc54096SNithin Dabilpuram return 0; 28996cc54096SNithin Dabilpuram } 29006cc54096SNithin Dabilpuram 2901b74652f3SRagothaman Jayaraman static __rte_always_inline void * 2902b74652f3SRagothaman Jayaraman alloc_op_meta(struct rte_mbuf *m_src, 2903b74652f3SRagothaman Jayaraman buf_ptr_t *buf, 2904b74652f3SRagothaman Jayaraman int32_t len, 2905b74652f3SRagothaman Jayaraman struct rte_mempool *cpt_meta_pool) 2906b74652f3SRagothaman Jayaraman { 2907b74652f3SRagothaman Jayaraman uint8_t *mdata; 2908b74652f3SRagothaman Jayaraman 2909b74652f3SRagothaman Jayaraman #ifndef CPT_ALWAYS_USE_SEPARATE_BUF 2910b74652f3SRagothaman Jayaraman if (likely(m_src && (m_src->nb_segs == 1))) { 2911b74652f3SRagothaman Jayaraman int32_t tailroom; 2912b74652f3SRagothaman Jayaraman phys_addr_t mphys; 2913b74652f3SRagothaman Jayaraman 2914b74652f3SRagothaman Jayaraman /* Check if tailroom is sufficient to hold meta data */ 2915b74652f3SRagothaman Jayaraman tailroom = rte_pktmbuf_tailroom(m_src); 2916b74652f3SRagothaman Jayaraman if (likely(tailroom > len + 8)) { 2917b74652f3SRagothaman Jayaraman mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len; 29184be71727SThomas Monjalon mphys = m_src->buf_iova + m_src->buf_len; 2919b74652f3SRagothaman Jayaraman mdata -= len; 2920b74652f3SRagothaman Jayaraman mphys -= len; 2921b74652f3SRagothaman Jayaraman buf->vaddr = mdata; 2922b74652f3SRagothaman Jayaraman buf->dma_addr = mphys; 2923b74652f3SRagothaman Jayaraman buf->size = len; 2924b74652f3SRagothaman Jayaraman /* Indicate that this is a mbuf allocated mdata */ 2925b74652f3SRagothaman Jayaraman mdata = (uint8_t *)((uint64_t)mdata | 1ull); 2926b74652f3SRagothaman Jayaraman return mdata; 2927b74652f3SRagothaman Jayaraman } 2928b74652f3SRagothaman Jayaraman } 2929b74652f3SRagothaman Jayaraman #else 2930b74652f3SRagothaman Jayaraman RTE_SET_USED(m_src); 2931b74652f3SRagothaman Jayaraman #endif 2932b74652f3SRagothaman Jayaraman 2933b74652f3SRagothaman Jayaraman if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0)) 2934b74652f3SRagothaman Jayaraman return NULL; 2935b74652f3SRagothaman Jayaraman 2936b74652f3SRagothaman Jayaraman buf->vaddr = mdata; 2937b74652f3SRagothaman Jayaraman buf->dma_addr = rte_mempool_virt2iova(mdata); 2938b74652f3SRagothaman Jayaraman buf->size = len; 2939b74652f3SRagothaman Jayaraman 2940b74652f3SRagothaman Jayaraman return mdata; 2941b74652f3SRagothaman Jayaraman } 2942b74652f3SRagothaman Jayaraman 2943b74652f3SRagothaman Jayaraman /** 2944b74652f3SRagothaman Jayaraman * cpt_free_metabuf - free metabuf to mempool. 2945b74652f3SRagothaman Jayaraman * @param instance: pointer to instance. 2946b74652f3SRagothaman Jayaraman * @param objp: pointer to the metabuf. 2947b74652f3SRagothaman Jayaraman */ 2948b74652f3SRagothaman Jayaraman static __rte_always_inline void 2949b74652f3SRagothaman Jayaraman free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool) 2950b74652f3SRagothaman Jayaraman { 2951b74652f3SRagothaman Jayaraman bool nofree = ((uintptr_t)mdata & 1ull); 2952b74652f3SRagothaman Jayaraman 2953b74652f3SRagothaman Jayaraman if (likely(nofree)) 2954b74652f3SRagothaman Jayaraman return; 2955b74652f3SRagothaman Jayaraman rte_mempool_put(cpt_meta_pool, mdata); 2956b74652f3SRagothaman Jayaraman } 2957b74652f3SRagothaman Jayaraman 2958b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 2959b74652f3SRagothaman Jayaraman prepare_iov_from_pkt(struct rte_mbuf *pkt, 2960b74652f3SRagothaman Jayaraman iov_ptr_t *iovec, uint32_t start_offset) 2961b74652f3SRagothaman Jayaraman { 2962b74652f3SRagothaman Jayaraman uint16_t index = 0; 2963b74652f3SRagothaman Jayaraman void *seg_data = NULL; 2964b74652f3SRagothaman Jayaraman phys_addr_t seg_phys; 2965b74652f3SRagothaman Jayaraman int32_t seg_size = 0; 2966b74652f3SRagothaman Jayaraman 2967b74652f3SRagothaman Jayaraman if (!pkt) { 2968b74652f3SRagothaman Jayaraman iovec->buf_cnt = 0; 2969b74652f3SRagothaman Jayaraman return 0; 2970b74652f3SRagothaman Jayaraman } 2971b74652f3SRagothaman Jayaraman 2972b74652f3SRagothaman Jayaraman if (!start_offset) { 2973b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 2974ce627d63SThomas Monjalon seg_phys = rte_pktmbuf_iova(pkt); 2975b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 2976b74652f3SRagothaman Jayaraman } else { 2977b74652f3SRagothaman Jayaraman while (start_offset >= pkt->data_len) { 2978b74652f3SRagothaman Jayaraman start_offset -= pkt->data_len; 2979b74652f3SRagothaman Jayaraman pkt = pkt->next; 2980b74652f3SRagothaman Jayaraman } 2981b74652f3SRagothaman Jayaraman 2982b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset); 2983ce627d63SThomas Monjalon seg_phys = rte_pktmbuf_iova_offset(pkt, start_offset); 2984b74652f3SRagothaman Jayaraman seg_size = pkt->data_len - start_offset; 2985b74652f3SRagothaman Jayaraman if (!seg_size) 2986b74652f3SRagothaman Jayaraman return 1; 2987b74652f3SRagothaman Jayaraman } 2988b74652f3SRagothaman Jayaraman 2989b74652f3SRagothaman Jayaraman /* first seg */ 2990b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 2991b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 2992b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 2993b74652f3SRagothaman Jayaraman index++; 2994b74652f3SRagothaman Jayaraman pkt = pkt->next; 2995b74652f3SRagothaman Jayaraman 2996b74652f3SRagothaman Jayaraman while (unlikely(pkt != NULL)) { 2997b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 2998ce627d63SThomas Monjalon seg_phys = rte_pktmbuf_iova(pkt); 2999b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 3000b74652f3SRagothaman Jayaraman if (!seg_size) 3001b74652f3SRagothaman Jayaraman break; 3002b74652f3SRagothaman Jayaraman 3003b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 3004b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 3005b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 3006b74652f3SRagothaman Jayaraman 3007b74652f3SRagothaman Jayaraman index++; 3008b74652f3SRagothaman Jayaraman 3009b74652f3SRagothaman Jayaraman pkt = pkt->next; 3010b74652f3SRagothaman Jayaraman } 3011b74652f3SRagothaman Jayaraman 3012b74652f3SRagothaman Jayaraman iovec->buf_cnt = index; 3013b74652f3SRagothaman Jayaraman return 0; 3014b74652f3SRagothaman Jayaraman } 3015b74652f3SRagothaman Jayaraman 3016b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t 3017b74652f3SRagothaman Jayaraman prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt, 3018b74652f3SRagothaman Jayaraman fc_params_t *param, 3019b74652f3SRagothaman Jayaraman uint32_t *flags) 3020b74652f3SRagothaman Jayaraman { 3021b74652f3SRagothaman Jayaraman uint16_t index = 0; 3022b74652f3SRagothaman Jayaraman void *seg_data = NULL; 3023b74652f3SRagothaman Jayaraman phys_addr_t seg_phys; 3024b74652f3SRagothaman Jayaraman uint32_t seg_size = 0; 3025b74652f3SRagothaman Jayaraman iov_ptr_t *iovec; 3026b74652f3SRagothaman Jayaraman 3027b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 3028ce627d63SThomas Monjalon seg_phys = rte_pktmbuf_iova(pkt); 3029b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 3030b74652f3SRagothaman Jayaraman 3031b74652f3SRagothaman Jayaraman /* first seg */ 3032b74652f3SRagothaman Jayaraman if (likely(!pkt->next)) { 3033b74652f3SRagothaman Jayaraman uint32_t headroom, tailroom; 3034b74652f3SRagothaman Jayaraman 3035b74652f3SRagothaman Jayaraman *flags |= SINGLE_BUF_INPLACE; 3036b74652f3SRagothaman Jayaraman headroom = rte_pktmbuf_headroom(pkt); 3037b74652f3SRagothaman Jayaraman tailroom = rte_pktmbuf_tailroom(pkt); 3038b74652f3SRagothaman Jayaraman if (likely((headroom >= 24) && 3039b74652f3SRagothaman Jayaraman (tailroom >= 8))) { 30407be78d02SJosh Soref /* In 83XX this is prerequisite for Direct mode */ 3041b74652f3SRagothaman Jayaraman *flags |= SINGLE_BUF_HEADTAILROOM; 3042b74652f3SRagothaman Jayaraman } 3043b74652f3SRagothaman Jayaraman param->bufs[0].vaddr = seg_data; 3044b74652f3SRagothaman Jayaraman param->bufs[0].dma_addr = seg_phys; 3045b74652f3SRagothaman Jayaraman param->bufs[0].size = seg_size; 3046b74652f3SRagothaman Jayaraman return 0; 3047b74652f3SRagothaman Jayaraman } 3048b74652f3SRagothaman Jayaraman iovec = param->src_iov; 3049b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 3050b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 3051b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 3052b74652f3SRagothaman Jayaraman index++; 3053b74652f3SRagothaman Jayaraman pkt = pkt->next; 3054b74652f3SRagothaman Jayaraman 3055b74652f3SRagothaman Jayaraman while (unlikely(pkt != NULL)) { 3056b74652f3SRagothaman Jayaraman seg_data = rte_pktmbuf_mtod(pkt, void *); 3057ce627d63SThomas Monjalon seg_phys = rte_pktmbuf_iova(pkt); 3058b74652f3SRagothaman Jayaraman seg_size = pkt->data_len; 3059b74652f3SRagothaman Jayaraman 3060b74652f3SRagothaman Jayaraman if (!seg_size) 3061b74652f3SRagothaman Jayaraman break; 3062b74652f3SRagothaman Jayaraman 3063b74652f3SRagothaman Jayaraman iovec->bufs[index].vaddr = seg_data; 3064b74652f3SRagothaman Jayaraman iovec->bufs[index].dma_addr = seg_phys; 3065b74652f3SRagothaman Jayaraman iovec->bufs[index].size = seg_size; 3066b74652f3SRagothaman Jayaraman 3067b74652f3SRagothaman Jayaraman index++; 3068b74652f3SRagothaman Jayaraman 3069b74652f3SRagothaman Jayaraman pkt = pkt->next; 3070b74652f3SRagothaman Jayaraman } 3071b74652f3SRagothaman Jayaraman 3072b74652f3SRagothaman Jayaraman iovec->buf_cnt = index; 3073b74652f3SRagothaman Jayaraman return 0; 3074b74652f3SRagothaman Jayaraman } 3075b74652f3SRagothaman Jayaraman 3076f39928e6SAnoob Joseph static __rte_always_inline int 3077b74652f3SRagothaman Jayaraman fill_fc_params(struct rte_crypto_op *cop, 3078b74652f3SRagothaman Jayaraman struct cpt_sess_misc *sess_misc, 3079ec54bc9dSAnoob Joseph struct cpt_qp_meta_info *m_info, 3080b74652f3SRagothaman Jayaraman void **mdata_ptr, 3081f39928e6SAnoob Joseph void **prep_req) 3082b74652f3SRagothaman Jayaraman { 3083b74652f3SRagothaman Jayaraman uint32_t space = 0; 3084b74652f3SRagothaman Jayaraman struct rte_crypto_sym_op *sym_op = cop->sym; 3085de5eb0a6STejasree Kondoj struct cpt_ctx *ctx = SESS_PRIV(sess_misc); 3086f39928e6SAnoob Joseph void *mdata = NULL; 3087b74652f3SRagothaman Jayaraman uintptr_t *op; 3088b74652f3SRagothaman Jayaraman uint32_t mc_hash_off; 3089b74652f3SRagothaman Jayaraman uint32_t flags = 0; 3090b74652f3SRagothaman Jayaraman uint64_t d_offs, d_lens; 3091b74652f3SRagothaman Jayaraman struct rte_mbuf *m_src, *m_dst; 3092b74652f3SRagothaman Jayaraman uint8_t cpt_op = sess_misc->cpt_op; 3093b74652f3SRagothaman Jayaraman #ifdef CPT_ALWAYS_USE_SG_MODE 3094b74652f3SRagothaman Jayaraman uint8_t inplace = 0; 3095b74652f3SRagothaman Jayaraman #else 3096b74652f3SRagothaman Jayaraman uint8_t inplace = 1; 3097b74652f3SRagothaman Jayaraman #endif 3098b74652f3SRagothaman Jayaraman fc_params_t fc_params; 3099b74652f3SRagothaman Jayaraman char src[SRC_IOV_SIZE]; 3100b74652f3SRagothaman Jayaraman char dst[SRC_IOV_SIZE]; 3101b74652f3SRagothaman Jayaraman uint32_t iv_buf[4]; 3102f39928e6SAnoob Joseph int ret; 3103b74652f3SRagothaman Jayaraman 3104b74652f3SRagothaman Jayaraman if (likely(sess_misc->iv_length)) { 3105b74652f3SRagothaman Jayaraman flags |= VALID_IV_BUF; 3106b74652f3SRagothaman Jayaraman fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, 3107b74652f3SRagothaman Jayaraman uint8_t *, sess_misc->iv_offset); 3108b74652f3SRagothaman Jayaraman if (sess_misc->aes_ctr && 3109b74652f3SRagothaman Jayaraman unlikely(sess_misc->iv_length != 16)) { 3110b74652f3SRagothaman Jayaraman memcpy((uint8_t *)iv_buf, 3111b74652f3SRagothaman Jayaraman rte_crypto_op_ctod_offset(cop, 3112b74652f3SRagothaman Jayaraman uint8_t *, sess_misc->iv_offset), 12); 3113b74652f3SRagothaman Jayaraman iv_buf[3] = rte_cpu_to_be_32(0x1); 3114b74652f3SRagothaman Jayaraman fc_params.iv_buf = iv_buf; 3115b74652f3SRagothaman Jayaraman } 3116b74652f3SRagothaman Jayaraman } 3117b74652f3SRagothaman Jayaraman 31188de5ede7SAnoob Joseph if (sess_misc->zsk_flag) { 3119b74652f3SRagothaman Jayaraman fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3120b74652f3SRagothaman Jayaraman uint8_t *, 3121b74652f3SRagothaman Jayaraman sess_misc->auth_iv_offset); 31228de5ede7SAnoob Joseph if (sess_misc->zsk_flag != ZS_EA) 3123b74652f3SRagothaman Jayaraman inplace = 0; 3124b74652f3SRagothaman Jayaraman } 3125b74652f3SRagothaman Jayaraman m_src = sym_op->m_src; 3126b74652f3SRagothaman Jayaraman m_dst = sym_op->m_dst; 3127b74652f3SRagothaman Jayaraman 3128cb7842f2STejasree Kondoj if (sess_misc->aes_gcm || sess_misc->chacha_poly) { 3129b74652f3SRagothaman Jayaraman uint8_t *salt; 3130b74652f3SRagothaman Jayaraman uint8_t *aad_data; 3131b74652f3SRagothaman Jayaraman uint16_t aad_len; 3132b74652f3SRagothaman Jayaraman 3133b74652f3SRagothaman Jayaraman d_offs = sym_op->aead.data.offset; 3134b74652f3SRagothaman Jayaraman d_lens = sym_op->aead.data.length; 3135b74652f3SRagothaman Jayaraman mc_hash_off = sym_op->aead.data.offset + 3136b74652f3SRagothaman Jayaraman sym_op->aead.data.length; 3137b74652f3SRagothaman Jayaraman 3138b74652f3SRagothaman Jayaraman aad_data = sym_op->aead.aad.data; 3139b74652f3SRagothaman Jayaraman aad_len = sess_misc->aad_length; 3140b74652f3SRagothaman Jayaraman if (likely((aad_data + aad_len) == 3141b74652f3SRagothaman Jayaraman rte_pktmbuf_mtod_offset(m_src, 3142b74652f3SRagothaman Jayaraman uint8_t *, 3143b74652f3SRagothaman Jayaraman sym_op->aead.data.offset))) { 3144b74652f3SRagothaman Jayaraman d_offs = (d_offs - aad_len) | (d_offs << 16); 3145b74652f3SRagothaman Jayaraman d_lens = (d_lens + aad_len) | (d_lens << 32); 3146b74652f3SRagothaman Jayaraman } else { 3147b74652f3SRagothaman Jayaraman fc_params.aad_buf.vaddr = sym_op->aead.aad.data; 3148b74652f3SRagothaman Jayaraman fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr; 3149b74652f3SRagothaman Jayaraman fc_params.aad_buf.size = aad_len; 3150b74652f3SRagothaman Jayaraman flags |= VALID_AAD_BUF; 3151b74652f3SRagothaman Jayaraman inplace = 0; 3152b74652f3SRagothaman Jayaraman d_offs = d_offs << 16; 3153b74652f3SRagothaman Jayaraman d_lens = d_lens << 32; 3154b74652f3SRagothaman Jayaraman } 3155b74652f3SRagothaman Jayaraman 3156b74652f3SRagothaman Jayaraman salt = fc_params.iv_buf; 3157b74652f3SRagothaman Jayaraman if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3158b74652f3SRagothaman Jayaraman cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3159b74652f3SRagothaman Jayaraman sess_misc->salt = *(uint32_t *)salt; 3160b74652f3SRagothaman Jayaraman } 3161b74652f3SRagothaman Jayaraman fc_params.iv_buf = salt + 4; 31628de5ede7SAnoob Joseph if (likely(sess_misc->mac_len)) { 3163b74652f3SRagothaman Jayaraman struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst : 3164b74652f3SRagothaman Jayaraman m_src; 3165b74652f3SRagothaman Jayaraman 3166b74652f3SRagothaman Jayaraman if (!m) 3167b74652f3SRagothaman Jayaraman m = m_src; 3168b74652f3SRagothaman Jayaraman 3169b74652f3SRagothaman Jayaraman /* hmac immediately following data is best case */ 3170795651c8SStephen Hemminger if (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) != 3171b74652f3SRagothaman Jayaraman (uint8_t *)sym_op->aead.digest.data)) { 3172b74652f3SRagothaman Jayaraman flags |= VALID_MAC_BUF; 3173b74652f3SRagothaman Jayaraman fc_params.mac_buf.size = sess_misc->mac_len; 3174b74652f3SRagothaman Jayaraman fc_params.mac_buf.vaddr = 3175b74652f3SRagothaman Jayaraman sym_op->aead.digest.data; 3176b74652f3SRagothaman Jayaraman fc_params.mac_buf.dma_addr = 3177b74652f3SRagothaman Jayaraman sym_op->aead.digest.phys_addr; 3178b74652f3SRagothaman Jayaraman inplace = 0; 3179b74652f3SRagothaman Jayaraman } 3180b74652f3SRagothaman Jayaraman } 3181b74652f3SRagothaman Jayaraman } else { 3182b74652f3SRagothaman Jayaraman d_offs = sym_op->cipher.data.offset; 3183b74652f3SRagothaman Jayaraman d_lens = sym_op->cipher.data.length; 3184b74652f3SRagothaman Jayaraman mc_hash_off = sym_op->cipher.data.offset + 3185b74652f3SRagothaman Jayaraman sym_op->cipher.data.length; 3186b74652f3SRagothaman Jayaraman d_offs = (d_offs << 16) | sym_op->auth.data.offset; 3187b74652f3SRagothaman Jayaraman d_lens = (d_lens << 32) | sym_op->auth.data.length; 3188b74652f3SRagothaman Jayaraman 3189b74652f3SRagothaman Jayaraman if (mc_hash_off < (sym_op->auth.data.offset + 3190b74652f3SRagothaman Jayaraman sym_op->auth.data.length)){ 3191b74652f3SRagothaman Jayaraman mc_hash_off = (sym_op->auth.data.offset + 3192b74652f3SRagothaman Jayaraman sym_op->auth.data.length); 3193b74652f3SRagothaman Jayaraman } 3194b74652f3SRagothaman Jayaraman /* for gmac, salt should be updated like in gcm */ 3195b74652f3SRagothaman Jayaraman if (unlikely(sess_misc->is_gmac)) { 3196b74652f3SRagothaman Jayaraman uint8_t *salt; 3197b74652f3SRagothaman Jayaraman salt = fc_params.iv_buf; 3198b74652f3SRagothaman Jayaraman if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3199b74652f3SRagothaman Jayaraman cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3200b74652f3SRagothaman Jayaraman sess_misc->salt = *(uint32_t *)salt; 3201b74652f3SRagothaman Jayaraman } 3202b74652f3SRagothaman Jayaraman fc_params.iv_buf = salt + 4; 3203b74652f3SRagothaman Jayaraman } 32048de5ede7SAnoob Joseph if (likely(sess_misc->mac_len)) { 3205b74652f3SRagothaman Jayaraman struct rte_mbuf *m; 3206b74652f3SRagothaman Jayaraman 3207b74652f3SRagothaman Jayaraman m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src; 3208b74652f3SRagothaman Jayaraman if (!m) 3209b74652f3SRagothaman Jayaraman m = m_src; 3210b74652f3SRagothaman Jayaraman 3211b74652f3SRagothaman Jayaraman /* hmac immediately following data is best case */ 3212de5eb0a6STejasree Kondoj if (!ctx->dec_auth && !ctx->auth_enc && 3213795651c8SStephen Hemminger (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) != 3214de5eb0a6STejasree Kondoj (uint8_t *)sym_op->auth.digest.data))) { 3215b74652f3SRagothaman Jayaraman flags |= VALID_MAC_BUF; 3216b74652f3SRagothaman Jayaraman fc_params.mac_buf.size = 3217b74652f3SRagothaman Jayaraman sess_misc->mac_len; 3218b74652f3SRagothaman Jayaraman fc_params.mac_buf.vaddr = 3219b74652f3SRagothaman Jayaraman sym_op->auth.digest.data; 3220b74652f3SRagothaman Jayaraman fc_params.mac_buf.dma_addr = 3221b74652f3SRagothaman Jayaraman sym_op->auth.digest.phys_addr; 3222b74652f3SRagothaman Jayaraman inplace = 0; 3223b74652f3SRagothaman Jayaraman } 3224b74652f3SRagothaman Jayaraman } 3225b74652f3SRagothaman Jayaraman } 3226b74652f3SRagothaman Jayaraman fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc); 3227b74652f3SRagothaman Jayaraman fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr; 3228b74652f3SRagothaman Jayaraman 3229de5eb0a6STejasree Kondoj if (!ctx->dec_auth && 3230de5eb0a6STejasree Kondoj unlikely(sess_misc->is_null || 3231de5eb0a6STejasree Kondoj sess_misc->cpt_op == CPT_OP_DECODE)) 3232b74652f3SRagothaman Jayaraman inplace = 0; 3233b74652f3SRagothaman Jayaraman 3234b74652f3SRagothaman Jayaraman if (likely(!m_dst && inplace)) { 3235b74652f3SRagothaman Jayaraman /* Case of single buffer without AAD buf or 3236b74652f3SRagothaman Jayaraman * separate mac buf in place and 3237b74652f3SRagothaman Jayaraman * not air crypto 3238b74652f3SRagothaman Jayaraman */ 3239b74652f3SRagothaman Jayaraman fc_params.dst_iov = fc_params.src_iov = (void *)src; 3240b74652f3SRagothaman Jayaraman 3241b74652f3SRagothaman Jayaraman if (unlikely(prepare_iov_from_pkt_inplace(m_src, 3242b74652f3SRagothaman Jayaraman &fc_params, 3243b74652f3SRagothaman Jayaraman &flags))) { 3244b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare inplace src iov failed"); 3245f39928e6SAnoob Joseph ret = -EINVAL; 3246f39928e6SAnoob Joseph goto err_exit; 3247b74652f3SRagothaman Jayaraman } 3248b74652f3SRagothaman Jayaraman 3249b74652f3SRagothaman Jayaraman } else { 3250b74652f3SRagothaman Jayaraman /* Out of place processing */ 3251b74652f3SRagothaman Jayaraman fc_params.src_iov = (void *)src; 3252b74652f3SRagothaman Jayaraman fc_params.dst_iov = (void *)dst; 3253b74652f3SRagothaman Jayaraman 3254b74652f3SRagothaman Jayaraman /* Store SG I/O in the api for reuse */ 3255b74652f3SRagothaman Jayaraman if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) { 3256b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare src iov failed"); 3257f39928e6SAnoob Joseph ret = -EINVAL; 3258f39928e6SAnoob Joseph goto err_exit; 3259b74652f3SRagothaman Jayaraman } 3260b74652f3SRagothaman Jayaraman 3261b74652f3SRagothaman Jayaraman if (unlikely(m_dst != NULL)) { 3262b74652f3SRagothaman Jayaraman uint32_t pkt_len; 3263b74652f3SRagothaman Jayaraman 3264b74652f3SRagothaman Jayaraman /* Try to make room as much as src has */ 3265b74652f3SRagothaman Jayaraman pkt_len = rte_pktmbuf_pkt_len(m_dst); 3266b74652f3SRagothaman Jayaraman 3267b74652f3SRagothaman Jayaraman if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) { 3268b74652f3SRagothaman Jayaraman pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len; 3269b74652f3SRagothaman Jayaraman if (!rte_pktmbuf_append(m_dst, pkt_len)) { 3270b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Not enough space in " 3271b74652f3SRagothaman Jayaraman "m_dst %p, need %u" 3272b74652f3SRagothaman Jayaraman " more", 3273b74652f3SRagothaman Jayaraman m_dst, pkt_len); 3274f39928e6SAnoob Joseph ret = -EINVAL; 3275f39928e6SAnoob Joseph goto err_exit; 3276b74652f3SRagothaman Jayaraman } 3277b74652f3SRagothaman Jayaraman } 3278b74652f3SRagothaman Jayaraman 3279b74652f3SRagothaman Jayaraman if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) { 3280b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Prepare dst iov failed for " 3281b74652f3SRagothaman Jayaraman "m_dst %p", m_dst); 3282f39928e6SAnoob Joseph ret = -EINVAL; 3283f39928e6SAnoob Joseph goto err_exit; 3284b74652f3SRagothaman Jayaraman } 3285b74652f3SRagothaman Jayaraman } else { 3286b74652f3SRagothaman Jayaraman fc_params.dst_iov = (void *)src; 3287b74652f3SRagothaman Jayaraman } 3288b74652f3SRagothaman Jayaraman } 3289b74652f3SRagothaman Jayaraman 3290b74652f3SRagothaman Jayaraman if (likely(flags & SINGLE_BUF_HEADTAILROOM)) 3291ec54bc9dSAnoob Joseph mdata = alloc_op_meta(m_src, &fc_params.meta_buf, 3292ec54bc9dSAnoob Joseph m_info->lb_mlen, m_info->pool); 3293b74652f3SRagothaman Jayaraman else 3294ec54bc9dSAnoob Joseph mdata = alloc_op_meta(NULL, &fc_params.meta_buf, 3295ec54bc9dSAnoob Joseph m_info->sg_mlen, m_info->pool); 3296b74652f3SRagothaman Jayaraman 3297b74652f3SRagothaman Jayaraman if (unlikely(mdata == NULL)) { 3298b74652f3SRagothaman Jayaraman CPT_LOG_DP_ERR("Error allocating meta buffer for request"); 3299f39928e6SAnoob Joseph ret = -ENOMEM; 3300f39928e6SAnoob Joseph goto err_exit; 3301b74652f3SRagothaman Jayaraman } 3302b74652f3SRagothaman Jayaraman 3303b74652f3SRagothaman Jayaraman op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull); 3304b74652f3SRagothaman Jayaraman op[0] = (uintptr_t)mdata; 3305b74652f3SRagothaman Jayaraman op[1] = (uintptr_t)cop; 3306b74652f3SRagothaman Jayaraman op[2] = op[3] = 0; /* Used to indicate auth verify */ 3307b74652f3SRagothaman Jayaraman space += 4 * sizeof(uint64_t); 3308b74652f3SRagothaman Jayaraman 3309b74652f3SRagothaman Jayaraman fc_params.meta_buf.vaddr = (uint8_t *)op + space; 3310b74652f3SRagothaman Jayaraman fc_params.meta_buf.dma_addr += space; 3311b74652f3SRagothaman Jayaraman fc_params.meta_buf.size -= space; 3312b74652f3SRagothaman Jayaraman 3313b74652f3SRagothaman Jayaraman /* Finally prepare the instruction */ 3314b74652f3SRagothaman Jayaraman if (cpt_op & CPT_OP_ENCODE) 3315f39928e6SAnoob Joseph *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, 3316f39928e6SAnoob Joseph &fc_params, op); 3317177b41ceSRagothaman Jayaraman else 3318f39928e6SAnoob Joseph *prep_req = cpt_fc_dec_hmac_prep(flags, d_offs, d_lens, 3319f39928e6SAnoob Joseph &fc_params, op); 3320b74652f3SRagothaman Jayaraman 3321f39928e6SAnoob Joseph if (unlikely(*prep_req == NULL)) { 3322f39928e6SAnoob Joseph CPT_LOG_DP_ERR("Preparing request failed due to bad input arg"); 3323f39928e6SAnoob Joseph ret = -EINVAL; 3324f39928e6SAnoob Joseph goto free_mdata_and_exit; 3325f39928e6SAnoob Joseph } 3326f39928e6SAnoob Joseph 3327b74652f3SRagothaman Jayaraman *mdata_ptr = mdata; 3328f39928e6SAnoob Joseph 3329f39928e6SAnoob Joseph return 0; 3330f39928e6SAnoob Joseph 3331f39928e6SAnoob Joseph free_mdata_and_exit: 3332ec54bc9dSAnoob Joseph free_op_meta(mdata, m_info->pool); 3333f39928e6SAnoob Joseph err_exit: 3334f39928e6SAnoob Joseph return ret; 3335b74652f3SRagothaman Jayaraman } 3336b74652f3SRagothaman Jayaraman 333789f1a8d6STejasree Kondoj static __rte_always_inline void 333889f1a8d6STejasree Kondoj compl_auth_verify(struct rte_crypto_op *op, 333989f1a8d6STejasree Kondoj uint8_t *gen_mac, 334089f1a8d6STejasree Kondoj uint64_t mac_len) 334189f1a8d6STejasree Kondoj { 334289f1a8d6STejasree Kondoj uint8_t *mac; 334389f1a8d6STejasree Kondoj struct rte_crypto_sym_op *sym_op = op->sym; 334489f1a8d6STejasree Kondoj 334589f1a8d6STejasree Kondoj if (sym_op->auth.digest.data) 334689f1a8d6STejasree Kondoj mac = sym_op->auth.digest.data; 334789f1a8d6STejasree Kondoj else 334889f1a8d6STejasree Kondoj mac = rte_pktmbuf_mtod_offset(sym_op->m_src, 334989f1a8d6STejasree Kondoj uint8_t *, 335089f1a8d6STejasree Kondoj sym_op->auth.data.length + 335189f1a8d6STejasree Kondoj sym_op->auth.data.offset); 335289f1a8d6STejasree Kondoj if (!mac) { 335389f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_ERROR; 335489f1a8d6STejasree Kondoj return; 335589f1a8d6STejasree Kondoj } 335689f1a8d6STejasree Kondoj 335789f1a8d6STejasree Kondoj if (memcmp(mac, gen_mac, mac_len)) 335889f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; 335989f1a8d6STejasree Kondoj else 336089f1a8d6STejasree Kondoj op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 336189f1a8d6STejasree Kondoj } 336289f1a8d6STejasree Kondoj 3363351fbee2SSrisivasubramanian S static __rte_always_inline void 3364351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(uint8_t *src, 3365351fbee2SSrisivasubramanian S uint32_t counter_num_bytes, 3366351fbee2SSrisivasubramanian S uint32_t *addr_length_in_bits, 3367351fbee2SSrisivasubramanian S uint8_t *addr_direction) 3368351fbee2SSrisivasubramanian S { 3369351fbee2SSrisivasubramanian S uint8_t found = 0; 3370f9494b67SAnkur Dwivedi uint32_t pos; 3371f9494b67SAnkur Dwivedi uint8_t last_byte; 3372351fbee2SSrisivasubramanian S while (!found && counter_num_bytes > 0) { 3373351fbee2SSrisivasubramanian S counter_num_bytes--; 3374351fbee2SSrisivasubramanian S if (src[counter_num_bytes] == 0x00) 3375351fbee2SSrisivasubramanian S continue; 3376f9494b67SAnkur Dwivedi pos = rte_bsf32(src[counter_num_bytes]); 3377f9494b67SAnkur Dwivedi if (pos == 7) { 3378f9494b67SAnkur Dwivedi if (likely(counter_num_bytes > 0)) { 3379f9494b67SAnkur Dwivedi last_byte = src[counter_num_bytes - 1]; 3380f9494b67SAnkur Dwivedi *addr_direction = last_byte & 0x1; 3381f9494b67SAnkur Dwivedi *addr_length_in_bits = counter_num_bytes * 8 3382f9494b67SAnkur Dwivedi - 1; 3383f9494b67SAnkur Dwivedi } 3384351fbee2SSrisivasubramanian S } else { 3385f9494b67SAnkur Dwivedi last_byte = src[counter_num_bytes]; 3386f9494b67SAnkur Dwivedi *addr_direction = (last_byte >> (pos + 1)) & 0x1; 3387f9494b67SAnkur Dwivedi *addr_length_in_bits = counter_num_bytes * 8 3388f9494b67SAnkur Dwivedi + (8 - (pos + 2)); 3389f9494b67SAnkur Dwivedi } 3390351fbee2SSrisivasubramanian S found = 1; 3391351fbee2SSrisivasubramanian S } 3392351fbee2SSrisivasubramanian S } 3393351fbee2SSrisivasubramanian S 3394351fbee2SSrisivasubramanian S /* 3395351fbee2SSrisivasubramanian S * This handles all auth only except AES_GMAC 3396351fbee2SSrisivasubramanian S */ 3397f39928e6SAnoob Joseph static __rte_always_inline int 3398351fbee2SSrisivasubramanian S fill_digest_params(struct rte_crypto_op *cop, 3399351fbee2SSrisivasubramanian S struct cpt_sess_misc *sess, 3400ec54bc9dSAnoob Joseph struct cpt_qp_meta_info *m_info, 3401351fbee2SSrisivasubramanian S void **mdata_ptr, 3402f39928e6SAnoob Joseph void **prep_req) 3403351fbee2SSrisivasubramanian S { 3404351fbee2SSrisivasubramanian S uint32_t space = 0; 3405351fbee2SSrisivasubramanian S struct rte_crypto_sym_op *sym_op = cop->sym; 3406351fbee2SSrisivasubramanian S void *mdata; 3407351fbee2SSrisivasubramanian S phys_addr_t mphys; 3408351fbee2SSrisivasubramanian S uint64_t *op; 3409351fbee2SSrisivasubramanian S uint32_t auth_range_off; 3410351fbee2SSrisivasubramanian S uint32_t flags = 0; 3411351fbee2SSrisivasubramanian S uint64_t d_offs = 0, d_lens; 3412351fbee2SSrisivasubramanian S struct rte_mbuf *m_src, *m_dst; 3413351fbee2SSrisivasubramanian S uint16_t auth_op = sess->cpt_op & CPT_OP_AUTH_MASK; 3414351fbee2SSrisivasubramanian S uint16_t mac_len = sess->mac_len; 3415351fbee2SSrisivasubramanian S fc_params_t params; 3416351fbee2SSrisivasubramanian S char src[SRC_IOV_SIZE]; 3417351fbee2SSrisivasubramanian S uint8_t iv_buf[16]; 3418f39928e6SAnoob Joseph int ret; 3419f39928e6SAnoob Joseph 3420351fbee2SSrisivasubramanian S memset(¶ms, 0, sizeof(fc_params_t)); 3421351fbee2SSrisivasubramanian S 3422351fbee2SSrisivasubramanian S m_src = sym_op->m_src; 3423351fbee2SSrisivasubramanian S 3424351fbee2SSrisivasubramanian S /* For just digest lets force mempool alloc */ 3425ec54bc9dSAnoob Joseph mdata = alloc_op_meta(NULL, ¶ms.meta_buf, m_info->sg_mlen, 3426ec54bc9dSAnoob Joseph m_info->pool); 3427351fbee2SSrisivasubramanian S if (mdata == NULL) { 3428f39928e6SAnoob Joseph ret = -ENOMEM; 3429f39928e6SAnoob Joseph goto err_exit; 3430351fbee2SSrisivasubramanian S } 3431351fbee2SSrisivasubramanian S 3432351fbee2SSrisivasubramanian S mphys = params.meta_buf.dma_addr; 3433351fbee2SSrisivasubramanian S 3434351fbee2SSrisivasubramanian S op = mdata; 3435351fbee2SSrisivasubramanian S op[0] = (uintptr_t)mdata; 3436351fbee2SSrisivasubramanian S op[1] = (uintptr_t)cop; 3437351fbee2SSrisivasubramanian S op[2] = op[3] = 0; /* Used to indicate auth verify */ 3438351fbee2SSrisivasubramanian S space += 4 * sizeof(uint64_t); 3439351fbee2SSrisivasubramanian S 3440351fbee2SSrisivasubramanian S auth_range_off = sym_op->auth.data.offset; 3441351fbee2SSrisivasubramanian S 3442351fbee2SSrisivasubramanian S flags = VALID_MAC_BUF; 3443351fbee2SSrisivasubramanian S params.src_iov = (void *)src; 34448de5ede7SAnoob Joseph if (unlikely(sess->zsk_flag)) { 3445351fbee2SSrisivasubramanian S /* 3446351fbee2SSrisivasubramanian S * Since for Zuc, Kasumi, Snow3g offsets are in bits 3447351fbee2SSrisivasubramanian S * we will send pass through even for auth only case, 3448351fbee2SSrisivasubramanian S * let MC handle it 3449351fbee2SSrisivasubramanian S */ 3450351fbee2SSrisivasubramanian S d_offs = auth_range_off; 3451351fbee2SSrisivasubramanian S auth_range_off = 0; 3452351fbee2SSrisivasubramanian S params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3453351fbee2SSrisivasubramanian S uint8_t *, sess->auth_iv_offset); 34548de5ede7SAnoob Joseph if (sess->zsk_flag == K_F9) { 3455351fbee2SSrisivasubramanian S uint32_t length_in_bits, num_bytes; 3456351fbee2SSrisivasubramanian S uint8_t *src, direction = 0; 3457351fbee2SSrisivasubramanian S 3458351fbee2SSrisivasubramanian S memcpy(iv_buf, rte_pktmbuf_mtod(cop->sym->m_src, 3459351fbee2SSrisivasubramanian S uint8_t *), 8); 3460351fbee2SSrisivasubramanian S /* 3461351fbee2SSrisivasubramanian S * This is kasumi f9, take direction from 3462351fbee2SSrisivasubramanian S * source buffer 3463351fbee2SSrisivasubramanian S */ 3464351fbee2SSrisivasubramanian S length_in_bits = cop->sym->auth.data.length; 3465351fbee2SSrisivasubramanian S num_bytes = (length_in_bits >> 3); 3466351fbee2SSrisivasubramanian S src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *); 3467351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(src, 34688de5ede7SAnoob Joseph num_bytes, 3469351fbee2SSrisivasubramanian S &length_in_bits, 3470351fbee2SSrisivasubramanian S &direction); 3471351fbee2SSrisivasubramanian S length_in_bits -= 64; 3472351fbee2SSrisivasubramanian S cop->sym->auth.data.offset += 64; 3473351fbee2SSrisivasubramanian S d_offs = cop->sym->auth.data.offset; 3474351fbee2SSrisivasubramanian S auth_range_off = d_offs / 8; 3475351fbee2SSrisivasubramanian S cop->sym->auth.data.length = length_in_bits; 3476351fbee2SSrisivasubramanian S 3477351fbee2SSrisivasubramanian S /* Store it at end of auth iv */ 3478351fbee2SSrisivasubramanian S iv_buf[8] = direction; 3479351fbee2SSrisivasubramanian S params.auth_iv_buf = iv_buf; 3480351fbee2SSrisivasubramanian S } 3481351fbee2SSrisivasubramanian S } 3482351fbee2SSrisivasubramanian S 3483351fbee2SSrisivasubramanian S d_lens = sym_op->auth.data.length; 3484351fbee2SSrisivasubramanian S 3485351fbee2SSrisivasubramanian S params.ctx_buf.vaddr = SESS_PRIV(sess); 3486351fbee2SSrisivasubramanian S params.ctx_buf.dma_addr = sess->ctx_dma_addr; 3487351fbee2SSrisivasubramanian S 3488351fbee2SSrisivasubramanian S if (auth_op == CPT_OP_AUTH_GENERATE) { 3489351fbee2SSrisivasubramanian S if (sym_op->auth.digest.data) { 3490351fbee2SSrisivasubramanian S /* 3491351fbee2SSrisivasubramanian S * Digest to be generated 3492351fbee2SSrisivasubramanian S * in separate buffer 3493351fbee2SSrisivasubramanian S */ 3494351fbee2SSrisivasubramanian S params.mac_buf.size = 3495351fbee2SSrisivasubramanian S sess->mac_len; 3496351fbee2SSrisivasubramanian S params.mac_buf.vaddr = 3497351fbee2SSrisivasubramanian S sym_op->auth.digest.data; 3498351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = 3499351fbee2SSrisivasubramanian S sym_op->auth.digest.phys_addr; 3500351fbee2SSrisivasubramanian S } else { 3501351fbee2SSrisivasubramanian S uint32_t off = sym_op->auth.data.offset + 3502351fbee2SSrisivasubramanian S sym_op->auth.data.length; 3503351fbee2SSrisivasubramanian S int32_t dlen, space; 3504351fbee2SSrisivasubramanian S 3505351fbee2SSrisivasubramanian S m_dst = sym_op->m_dst ? 3506351fbee2SSrisivasubramanian S sym_op->m_dst : sym_op->m_src; 3507351fbee2SSrisivasubramanian S dlen = rte_pktmbuf_pkt_len(m_dst); 3508351fbee2SSrisivasubramanian S 3509351fbee2SSrisivasubramanian S space = off + mac_len - dlen; 3510351fbee2SSrisivasubramanian S if (space > 0) 3511351fbee2SSrisivasubramanian S if (!rte_pktmbuf_append(m_dst, space)) { 3512351fbee2SSrisivasubramanian S CPT_LOG_DP_ERR("Failed to extend " 3513351fbee2SSrisivasubramanian S "mbuf by %uB", space); 3514f39928e6SAnoob Joseph ret = -EINVAL; 3515f39928e6SAnoob Joseph goto free_mdata_and_exit; 3516351fbee2SSrisivasubramanian S } 3517351fbee2SSrisivasubramanian S 3518351fbee2SSrisivasubramanian S params.mac_buf.vaddr = 3519351fbee2SSrisivasubramanian S rte_pktmbuf_mtod_offset(m_dst, void *, off); 3520351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = 3521ce627d63SThomas Monjalon rte_pktmbuf_iova_offset(m_dst, off); 3522351fbee2SSrisivasubramanian S params.mac_buf.size = mac_len; 3523351fbee2SSrisivasubramanian S } 3524351fbee2SSrisivasubramanian S } else { 3525351fbee2SSrisivasubramanian S /* Need space for storing generated mac */ 3526351fbee2SSrisivasubramanian S params.mac_buf.vaddr = (uint8_t *)mdata + space; 3527351fbee2SSrisivasubramanian S params.mac_buf.dma_addr = mphys + space; 3528351fbee2SSrisivasubramanian S params.mac_buf.size = mac_len; 3529351fbee2SSrisivasubramanian S space += RTE_ALIGN_CEIL(mac_len, 8); 3530351fbee2SSrisivasubramanian S op[2] = (uintptr_t)params.mac_buf.vaddr; 3531351fbee2SSrisivasubramanian S op[3] = mac_len; 3532351fbee2SSrisivasubramanian S } 3533351fbee2SSrisivasubramanian S 3534351fbee2SSrisivasubramanian S params.meta_buf.vaddr = (uint8_t *)mdata + space; 3535351fbee2SSrisivasubramanian S params.meta_buf.dma_addr = mphys + space; 3536351fbee2SSrisivasubramanian S params.meta_buf.size -= space; 3537351fbee2SSrisivasubramanian S 3538351fbee2SSrisivasubramanian S /* Out of place processing */ 3539351fbee2SSrisivasubramanian S params.src_iov = (void *)src; 3540351fbee2SSrisivasubramanian S 3541351fbee2SSrisivasubramanian S /*Store SG I/O in the api for reuse */ 3542351fbee2SSrisivasubramanian S if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off)) { 3543351fbee2SSrisivasubramanian S CPT_LOG_DP_ERR("Prepare src iov failed"); 3544f39928e6SAnoob Joseph ret = -EINVAL; 3545f39928e6SAnoob Joseph goto free_mdata_and_exit; 3546351fbee2SSrisivasubramanian S } 3547351fbee2SSrisivasubramanian S 3548f39928e6SAnoob Joseph *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, ¶ms, op); 3549f39928e6SAnoob Joseph if (unlikely(*prep_req == NULL)) { 3550f39928e6SAnoob Joseph ret = -EINVAL; 3551f39928e6SAnoob Joseph goto free_mdata_and_exit; 3552f39928e6SAnoob Joseph } 3553f39928e6SAnoob Joseph 3554351fbee2SSrisivasubramanian S *mdata_ptr = mdata; 3555f39928e6SAnoob Joseph 3556f39928e6SAnoob Joseph return 0; 3557f39928e6SAnoob Joseph 3558f39928e6SAnoob Joseph free_mdata_and_exit: 3559ec54bc9dSAnoob Joseph free_op_meta(mdata, m_info->pool); 3560f39928e6SAnoob Joseph err_exit: 3561f39928e6SAnoob Joseph return ret; 3562351fbee2SSrisivasubramanian S } 3563351fbee2SSrisivasubramanian S 356443d01767SNithin Dabilpuram #endif /*_CPT_UCODE_H_ */ 3565