- src[i] = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
- (ops[i]->sym->cipher.data.offset >> 3);
- dst[i] = ops[i]->sym->m_dst ?
- rte_pktmbuf_mtod(ops[i]->sym->m_dst, uint8_t *) +
- (ops[i]->sym->cipher.data.offset >> 3) :
- rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
- (ops[i]->sym->cipher.data.offset >> 3);
+
+ cipher_off = ops[i]->sym->cipher.data.offset >> 3;
+ cipher_len = ops[i]->sym->cipher.data.length >> 3;
+ src[i] = rte_pktmbuf_mtod_offset(
+ ops[i]->sym->m_src, uint8_t *, cipher_off);
+
+ /* If out-of-place operation */
+ if (ops[i]->sym->m_dst &&
+ ops[i]->sym->m_src != ops[i]->sym->m_dst) {
+ dst[i] = rte_pktmbuf_mtod_offset(
+ ops[i]->sym->m_dst, uint8_t *, cipher_off);
+
+ /* In case of out-of-place, auth-cipher operation
+ * with partial encryption of the digest, copy
+ * the remaining, unencrypted part.
+ */
+ if (session->op == IPSEC_MB_OP_HASH_VERIFY_THEN_DECRYPT
+ || session->op == IPSEC_MB_OP_HASH_GEN_THEN_ENCRYPT)
+ unencrypted_bytes =
+ (ops[i]->sym->auth.data.offset >> 3) +
+ (ops[i]->sym->auth.data.length >> 3) +
+ (SNOW3G_DIGEST_LENGTH) -
+ cipher_off - cipher_len;
+ if (unencrypted_bytes > 0)
+ rte_memcpy(
+ rte_pktmbuf_mtod_offset(
+ ops[i]->sym->m_dst, uint8_t *,
+ cipher_off + cipher_len),
+ rte_pktmbuf_mtod_offset(
+ ops[i]->sym->m_src, uint8_t *,
+ cipher_off + cipher_len),
+ unencrypted_bytes);
+ } else
+ dst[i] = rte_pktmbuf_mtod_offset(ops[i]->sym->m_src,
+ uint8_t *, cipher_off);
+