+ if (cipher_xform) {
+ session->cipher_key.data = rte_zmalloc(NULL,
+ cipher_xform->key.length,
+ RTE_CACHE_LINE_SIZE);
+ if (session->cipher_key.data == NULL &&
+ cipher_xform->key.length > 0) {
+ DPAA_SEC_ERR("No Memory for cipher key");
+ return -ENOMEM;
+ }
+
+ session->cipher_key.length = cipher_xform->key.length;
+ memcpy(session->cipher_key.data, cipher_xform->key.data,
+ cipher_xform->key.length);
+ session->cipher_alg = cipher_xform->algo;
+ } else {
+ session->cipher_key.data = NULL;
+ session->cipher_key.length = 0;
+ session->cipher_alg = RTE_CRYPTO_CIPHER_NULL;
+ }
+
+ if (auth_xform) {
+ session->auth_key.data = rte_zmalloc(NULL,
+ auth_xform->key.length,
+ RTE_CACHE_LINE_SIZE);
+ if (session->auth_key.data == NULL &&
+ auth_xform->key.length > 0) {
+ DPAA_SEC_ERR("No Memory for auth key");
+ return -ENOMEM;
+ }
+ session->auth_key.length = auth_xform->key.length;
+ memcpy(session->auth_key.data, auth_xform->key.data,
+ auth_xform->key.length);
+ session->auth_alg = auth_xform->algo;
+ session->digest_length = auth_xform->digest_length;
+ } else {
+ session->auth_key.data = NULL;
+ session->auth_key.length = 0;
+ session->auth_alg = RTE_CRYPTO_AUTH_NULL;
+ }
+
+ switch (session->auth_alg) {
+ case RTE_CRYPTO_AUTH_SHA1_HMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_SHA1_96;
+ session->auth_key.algmode = OP_ALG_AAI_HMAC;
+ break;
+ case RTE_CRYPTO_AUTH_MD5_HMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_MD5_96;
+ session->auth_key.algmode = OP_ALG_AAI_HMAC;
+ break;
+ case RTE_CRYPTO_AUTH_SHA256_HMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_SHA2_256_128;
+ session->auth_key.algmode = OP_ALG_AAI_HMAC;
+ if (session->digest_length != 16)
+ DPAA_SEC_WARN(
+ "+++Using sha256-hmac truncated len is non-standard,"
+ "it will not work with lookaside proto");
+ break;
+ case RTE_CRYPTO_AUTH_SHA384_HMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_SHA2_384_192;
+ session->auth_key.algmode = OP_ALG_AAI_HMAC;
+ break;
+ case RTE_CRYPTO_AUTH_SHA512_HMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_SHA2_512_256;
+ session->auth_key.algmode = OP_ALG_AAI_HMAC;
+ break;
+ case RTE_CRYPTO_AUTH_AES_CMAC:
+ session->auth_key.alg = OP_PCL_IPSEC_AES_CMAC_96;
+ break;
+ case RTE_CRYPTO_AUTH_NULL:
+ session->auth_key.alg = OP_PCL_IPSEC_HMAC_NULL;
+ break;
+ case RTE_CRYPTO_AUTH_SHA224_HMAC:
+ case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+ case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+ case RTE_CRYPTO_AUTH_SHA1:
+ case RTE_CRYPTO_AUTH_SHA256:
+ case RTE_CRYPTO_AUTH_SHA512:
+ case RTE_CRYPTO_AUTH_SHA224:
+ case RTE_CRYPTO_AUTH_SHA384:
+ case RTE_CRYPTO_AUTH_MD5:
+ case RTE_CRYPTO_AUTH_AES_GMAC:
+ case RTE_CRYPTO_AUTH_KASUMI_F9:
+ case RTE_CRYPTO_AUTH_AES_CBC_MAC:
+ case RTE_CRYPTO_AUTH_ZUC_EIA3:
+ DPAA_SEC_ERR("Crypto: Unsupported auth alg %u",
+ session->auth_alg);
+ return -ENOTSUP;
+ default:
+ DPAA_SEC_ERR("Crypto: Undefined Auth specified %u",
+ session->auth_alg);
+ return -ENOTSUP;
+ }
+
+ switch (session->cipher_alg) {
+ case RTE_CRYPTO_CIPHER_AES_CBC:
+ session->cipher_key.alg = OP_PCL_IPSEC_AES_CBC;
+ session->cipher_key.algmode = OP_ALG_AAI_CBC;
+ break;
+ case RTE_CRYPTO_CIPHER_3DES_CBC:
+ session->cipher_key.alg = OP_PCL_IPSEC_3DES;
+ session->cipher_key.algmode = OP_ALG_AAI_CBC;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_CTR:
+ session->cipher_key.alg = OP_PCL_IPSEC_AES_CTR;
+ session->cipher_key.algmode = OP_ALG_AAI_CTR;
+ if (session->dir == DIR_ENC) {
+ session->encap_pdb.ctr.ctr_initial = 0x00000001;
+ session->encap_pdb.ctr.ctr_nonce = ipsec_xform->salt;
+ } else {
+ session->decap_pdb.ctr.ctr_initial = 0x00000001;
+ session->decap_pdb.ctr.ctr_nonce = ipsec_xform->salt;
+ }
+ break;
+ case RTE_CRYPTO_CIPHER_NULL:
+ session->cipher_key.alg = OP_PCL_IPSEC_NULL;
+ break;
+ case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
+ case RTE_CRYPTO_CIPHER_ZUC_EEA3:
+ case RTE_CRYPTO_CIPHER_3DES_ECB:
+ case RTE_CRYPTO_CIPHER_AES_ECB:
+ case RTE_CRYPTO_CIPHER_KASUMI_F8:
+ DPAA_SEC_ERR("Crypto: Unsupported Cipher alg %u",
+ session->cipher_alg);
+ return -ENOTSUP;
+ default:
+ DPAA_SEC_ERR("Crypto: Undefined Cipher specified %u",
+ session->cipher_alg);
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+static int
+dpaa_sec_set_ipsec_session(__rte_unused struct rte_cryptodev *dev,
+ struct rte_security_session_conf *conf,
+ void *sess)
+{
+ struct dpaa_sec_dev_private *internals = dev->data->dev_private;
+ struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
+ struct rte_crypto_auth_xform *auth_xform = NULL;
+ struct rte_crypto_cipher_xform *cipher_xform = NULL;
+ struct rte_crypto_aead_xform *aead_xform = NULL;
+ dpaa_sec_session *session = (dpaa_sec_session *)sess;
+ uint32_t i;
+ int ret;
+
+ PMD_INIT_FUNC_TRACE();
+
+ memset(session, 0, sizeof(dpaa_sec_session));
+ session->proto_alg = conf->protocol;
+ session->ctxt = DPAA_SEC_IPSEC;
+
+ if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
+ session->dir = DIR_ENC;
+ else
+ session->dir = DIR_DEC;
+
+ if (conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
+ cipher_xform = &conf->crypto_xform->cipher;
+ if (conf->crypto_xform->next)
+ auth_xform = &conf->crypto_xform->next->auth;
+ ret = dpaa_sec_ipsec_proto_init(cipher_xform, auth_xform,
+ ipsec_xform, session);
+ } else if (conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+ auth_xform = &conf->crypto_xform->auth;
+ if (conf->crypto_xform->next)
+ cipher_xform = &conf->crypto_xform->next->cipher;
+ ret = dpaa_sec_ipsec_proto_init(cipher_xform, auth_xform,
+ ipsec_xform, session);
+ } else if (conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+ aead_xform = &conf->crypto_xform->aead;
+ ret = dpaa_sec_ipsec_aead_init(aead_xform,
+ ipsec_xform, session);
+ } else {
+ DPAA_SEC_ERR("XFORM not specified");
+ ret = -EINVAL;
+ goto out;
+ }
+ if (ret) {
+ DPAA_SEC_ERR("Failed to process xform");
+ goto out;
+ }
+
+ if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
+ if (ipsec_xform->tunnel.type ==
+ RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
+ session->ip4_hdr.ip_v = IPVERSION;
+ session->ip4_hdr.ip_hl = 5;
+ session->ip4_hdr.ip_len = rte_cpu_to_be_16(
+ sizeof(session->ip4_hdr));
+ session->ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp;
+ session->ip4_hdr.ip_id = 0;
+ session->ip4_hdr.ip_off = 0;
+ session->ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl;
+ session->ip4_hdr.ip_p = (ipsec_xform->proto ==
+ RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
+ IPPROTO_ESP : IPPROTO_AH;
+ session->ip4_hdr.ip_sum = 0;
+ session->ip4_hdr.ip_src =
+ ipsec_xform->tunnel.ipv4.src_ip;
+ session->ip4_hdr.ip_dst =
+ ipsec_xform->tunnel.ipv4.dst_ip;
+ session->ip4_hdr.ip_sum = calc_chksum((uint16_t *)
+ (void *)&session->ip4_hdr,
+ sizeof(struct ip));
+ session->encap_pdb.ip_hdr_len = sizeof(struct ip);
+ } else if (ipsec_xform->tunnel.type ==
+ RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
+ session->ip6_hdr.vtc_flow = rte_cpu_to_be_32(
+ DPAA_IPv6_DEFAULT_VTC_FLOW |
+ ((ipsec_xform->tunnel.ipv6.dscp <<
+ RTE_IPV6_HDR_TC_SHIFT) &
+ RTE_IPV6_HDR_TC_MASK) |
+ ((ipsec_xform->tunnel.ipv6.flabel <<
+ RTE_IPV6_HDR_FL_SHIFT) &
+ RTE_IPV6_HDR_FL_MASK));
+ /* Payload length will be updated by HW */
+ session->ip6_hdr.payload_len = 0;
+ session->ip6_hdr.hop_limits =
+ ipsec_xform->tunnel.ipv6.hlimit;
+ session->ip6_hdr.proto = (ipsec_xform->proto ==
+ RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
+ IPPROTO_ESP : IPPROTO_AH;
+ memcpy(&session->ip6_hdr.src_addr,
+ &ipsec_xform->tunnel.ipv6.src_addr, 16);
+ memcpy(&session->ip6_hdr.dst_addr,
+ &ipsec_xform->tunnel.ipv6.dst_addr, 16);
+ session->encap_pdb.ip_hdr_len =
+ sizeof(struct rte_ipv6_hdr);
+ }
+ session->encap_pdb.options =
+ (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) |
+ PDBOPTS_ESP_OIHI_PDB_INL |
+ PDBOPTS_ESP_IVSRC |
+ PDBHMO_ESP_ENCAP_DTTL |
+ PDBHMO_ESP_SNR;
+ if (ipsec_xform->options.esn)
+ session->encap_pdb.options |= PDBOPTS_ESP_ESN;
+ session->encap_pdb.spi = ipsec_xform->spi;
+
+ } else if (ipsec_xform->direction ==
+ RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+ if (ipsec_xform->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
+ session->decap_pdb.options = sizeof(struct ip) << 16;
+ else
+ session->decap_pdb.options =
+ sizeof(struct rte_ipv6_hdr) << 16;
+ if (ipsec_xform->options.esn)
+ session->decap_pdb.options |= PDBOPTS_ESP_ESN;
+ if (ipsec_xform->replay_win_sz) {
+ uint32_t win_sz;
+ win_sz = rte_align32pow2(ipsec_xform->replay_win_sz);
+
+ switch (win_sz) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ session->decap_pdb.options |= PDBOPTS_ESP_ARS32;
+ break;
+ case 64:
+ session->decap_pdb.options |= PDBOPTS_ESP_ARS64;
+ break;
+ default:
+ session->decap_pdb.options |=
+ PDBOPTS_ESP_ARS128;
+ }
+ }
+ } else
+ goto out;
+ rte_spinlock_lock(&internals->lock);
+ for (i = 0; i < MAX_DPAA_CORES; i++) {
+ session->inq[i] = dpaa_sec_attach_rxq(internals);
+ if (session->inq[i] == NULL) {
+ DPAA_SEC_ERR("unable to attach sec queue");
+ rte_spinlock_unlock(&internals->lock);
+ goto out;
+ }
+ }
+ rte_spinlock_unlock(&internals->lock);
+
+ return 0;
+out:
+ free_session_data(session);
+ return -1;
+}
+
+static int
+dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev,
+ struct rte_security_session_conf *conf,
+ void *sess)
+{
+ struct rte_security_pdcp_xform *pdcp_xform = &conf->pdcp;
+ struct rte_crypto_sym_xform *xform = conf->crypto_xform;
+ struct rte_crypto_auth_xform *auth_xform = NULL;
+ struct rte_crypto_cipher_xform *cipher_xform = NULL;
+ dpaa_sec_session *session = (dpaa_sec_session *)sess;
+ struct dpaa_sec_dev_private *dev_priv = dev->data->dev_private;
+ uint32_t i;
+ int ret;