X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Fqat%2Fqat_sym.c;h=5ff4aa1e5ab8500af8c08de6b0c727f2466a3c09;hb=21ecbde99b2f0772d36eef8276a686f3135e5de9;hp=887d4ebcd0dedf4303163c0d51eae44509547377;hpb=91614c73b67cad33750b04b9904dd99666b9a91e;p=dpdk.git diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c index 887d4ebcd0..5ff4aa1e5a 100644 --- a/drivers/crypto/qat/qat_sym.c +++ b/drivers/crypto/qat/qat_sym.c @@ -1,19 +1,18 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2018 Intel Corporation + * Copyright(c) 2015-2019 Intel Corporation */ #include #include #include -#include #include #include #include -#include "qat_logs.h" #include "qat_sym.h" + /** Decrypt a single partial block * Depends on openssl libcrypto * Uses ECB+XOR to do CFB encryption, same result, more performant @@ -39,7 +38,7 @@ bpi_cipher_decrypt(uint8_t *src, uint8_t *dst, return 0; cipher_decrypt_err: - PMD_DRV_LOG(ERR, "libcrypto ECB cipher decrypt for BPI IV failed"); + QAT_DP_LOG(ERR, "libcrypto ECB cipher decrypt for BPI IV failed"); return -EINVAL; } @@ -78,21 +77,21 @@ qat_bpicipher_preprocess(struct qat_sym_session *ctx, iv = rte_crypto_op_ctod_offset(op, uint8_t *, ctx->cipher_iv.offset); -#ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX - rte_hexdump(stdout, "BPI: src before pre-process:", last_block, - last_block_len); +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "BPI: src before pre-process:", + last_block, last_block_len); if (sym_op->m_dst != NULL) - rte_hexdump(stdout, "BPI: dst before pre-process:", dst, - last_block_len); + QAT_DP_HEXDUMP_LOG(DEBUG, "BPI:dst before pre-process:", + dst, last_block_len); #endif bpi_cipher_decrypt(last_block, dst, iv, block_len, last_block_len, ctx->bpi_ctx); -#ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX - rte_hexdump(stdout, "BPI: src after pre-process:", last_block, - last_block_len); +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "BPI: src after pre-process:", + last_block, last_block_len); if (sym_op->m_dst != NULL) - rte_hexdump(stdout, "BPI: dst after pre-process:", dst, - last_block_len); + QAT_DP_HEXDUMP_LOG(DEBUG, "BPI: dst after pre-process:", + dst, last_block_len); #endif } @@ -158,35 +157,37 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, uint32_t auth_len = 0, auth_ofs = 0; uint32_t min_ofs = 0; uint64_t src_buf_start = 0, dst_buf_start = 0; + uint64_t auth_data_end = 0; uint8_t do_sgl = 0; + uint8_t in_place = 1; + int alignment_adjustment = 0; struct rte_crypto_op *op = (struct rte_crypto_op *)in_op; struct qat_sym_op_cookie *cookie = (struct qat_sym_op_cookie *)op_cookie; -#ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) { - PMD_DRV_LOG(ERR, "QAT PMD only supports symmetric crypto " + QAT_DP_LOG(ERR, "QAT PMD only supports symmetric crypto " "operation requests, op (%p) is not a " "symmetric operation.", op); return -EINVAL; } -#endif + if (unlikely(op->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) { - PMD_DRV_LOG(ERR, "QAT PMD only supports session oriented" + QAT_DP_LOG(ERR, "QAT PMD only supports session oriented" " requests, op (%p) is sessionless.", op); return -EINVAL; } - ctx = (struct qat_sym_session *)get_session_private_data( + ctx = (struct qat_sym_session *)get_sym_session_private_data( op->sym->session, cryptodev_qat_driver_id); if (unlikely(ctx == NULL)) { - PMD_DRV_LOG(ERR, "Session was not created for this device"); + QAT_DP_LOG(ERR, "Session was not created for this device"); return -EINVAL; } if (unlikely(ctx->min_qat_dev_gen > qat_dev_gen)) { - PMD_DRV_LOG(ERR, "Session alg not supported on this device gen"); + QAT_DP_LOG(ERR, "Session alg not supported on this device gen"); op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; return -EINVAL; } @@ -195,7 +196,8 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, rte_mov128((uint8_t *)qat_req, (const uint8_t *)&(ctx->fw_req)); qat_req->comn_mid.opaque_data = (uint64_t)(uintptr_t)op; cipher_param = (void *)&qat_req->serv_specif_rqpars; - auth_param = (void *)((uint8_t *)cipher_param + sizeof(*cipher_param)); + auth_param = (void *)((uint8_t *)cipher_param + + ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET); if (ctx->qat_cmd == ICP_QAT_FW_LA_CMD_HASH_CIPHER || ctx->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_HASH) { @@ -228,10 +230,9 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) { if (unlikely( - (cipher_param->cipher_length % BYTE_LENGTH != 0) - || (cipher_param->cipher_offset - % BYTE_LENGTH != 0))) { - PMD_DRV_LOG(ERR, + (op->sym->cipher.data.length % BYTE_LENGTH != 0) || + (op->sym->cipher.data.offset % BYTE_LENGTH != 0))) { + QAT_DP_LOG(ERR, "SNOW3G/KASUMI/ZUC in QAT PMD only supports byte aligned values"); op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; return -EINVAL; @@ -263,9 +264,10 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 || ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3) { - if (unlikely((auth_param->auth_off % BYTE_LENGTH != 0) - || (auth_param->auth_len % BYTE_LENGTH != 0))) { - PMD_DRV_LOG(ERR, + if (unlikely( + (op->sym->auth.data.offset % BYTE_LENGTH != 0) || + (op->sym->auth.data.length % BYTE_LENGTH != 0))) { + QAT_DP_LOG(ERR, "For SNOW3G/KASUMI/ZUC, QAT PMD only supports byte aligned values"); op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; return -EINVAL; @@ -441,6 +443,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, * Don't align DMA start. DMA the minimum data-set * so as not to overwrite data in dest buffer */ + in_place = 0; src_buf_start = rte_pktmbuf_iova_offset(op->sym->m_src, min_ofs); dst_buf_start = @@ -465,6 +468,10 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, min_ofs); } dst_buf_start = src_buf_start; + + /* remember any adjustment for later, note, can be +/- */ + alignment_adjustment = src_buf_start - + rte_pktmbuf_iova_offset(op->sym->m_src, min_ofs); } if (do_cipher || do_aead) { @@ -493,15 +500,69 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, (cipher_param->cipher_offset + cipher_param->cipher_length) : (auth_param->auth_off + auth_param->auth_len); + if (do_auth && do_cipher) { + /* Handle digest-encrypted cases, i.e. + * auth-gen-then-cipher-encrypt and + * cipher-decrypt-then-auth-verify + */ + /* First find the end of the data */ + if (do_sgl) { + uint32_t remaining_off = auth_param->auth_off + + auth_param->auth_len + alignment_adjustment; + struct rte_mbuf *sgl_buf = + (in_place ? + op->sym->m_src : op->sym->m_dst); + + while (remaining_off >= rte_pktmbuf_data_len(sgl_buf) + && sgl_buf->next != NULL) { + remaining_off -= rte_pktmbuf_data_len(sgl_buf); + sgl_buf = sgl_buf->next; + } + + auth_data_end = (uint64_t)rte_pktmbuf_iova_offset( + sgl_buf, remaining_off); + } else { + auth_data_end = (in_place ? + src_buf_start : dst_buf_start) + + auth_param->auth_off + auth_param->auth_len; + } + /* Then check if digest-encrypted conditions are met */ + if ((auth_param->auth_off + auth_param->auth_len < + cipher_param->cipher_offset + + cipher_param->cipher_length) && + (op->sym->auth.digest.phys_addr == + auth_data_end)) { + /* Handle partial digest encryption */ + if (cipher_param->cipher_offset + + cipher_param->cipher_length < + auth_param->auth_off + + auth_param->auth_len + + ctx->digest_length) + qat_req->comn_mid.dst_length = + qat_req->comn_mid.src_length = + auth_param->auth_off + + auth_param->auth_len + + ctx->digest_length; + struct icp_qat_fw_comn_req_hdr *header = + &qat_req->comn_hdr; + ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET( + header->serv_specif_flags, + ICP_QAT_FW_LA_DIGEST_IN_BUFFER); + } + } + if (do_sgl) { ICP_QAT_FW_COMN_PTR_TYPE_SET(qat_req->comn_hdr.comn_req_flags, QAT_COMN_PTR_TYPE_SGL); - ret = qat_sgl_fill_array(op->sym->m_src, src_buf_start, - &cookie->qat_sgl_src, - qat_req->comn_mid.src_length); - if (ret) { - PMD_DRV_LOG(ERR, "QAT PMD Cannot fill sgl array"); + ret = qat_sgl_fill_array(op->sym->m_src, + (int64_t)(src_buf_start - rte_pktmbuf_iova(op->sym->m_src)), + &cookie->qat_sgl_src, + qat_req->comn_mid.src_length, + QAT_SYM_SGL_MAX_NUMBER); + + if (unlikely(ret)) { + QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array"); return ret; } @@ -511,13 +572,14 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, cookie->qat_sgl_src_phys_addr; else { ret = qat_sgl_fill_array(op->sym->m_dst, - dst_buf_start, - &cookie->qat_sgl_dst, - qat_req->comn_mid.dst_length); - - if (ret) { - PMD_DRV_LOG(ERR, "QAT PMD Cannot " - "fill sgl array"); + (int64_t)(dst_buf_start - + rte_pktmbuf_iova(op->sym->m_dst)), + &cookie->qat_sgl_dst, + qat_req->comn_mid.dst_length, + QAT_SYM_SGL_MAX_NUMBER); + + if (unlikely(ret)) { + QAT_DP_LOG(ERR, "QAT PMD can't fill sgl array"); return ret; } @@ -526,22 +588,31 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, qat_req->comn_mid.dest_data_addr = cookie->qat_sgl_dst_phys_addr; } + qat_req->comn_mid.src_length = 0; + qat_req->comn_mid.dst_length = 0; } else { qat_req->comn_mid.src_data_addr = src_buf_start; qat_req->comn_mid.dest_data_addr = dst_buf_start; } -#ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX - rte_hexdump(stdout, "qat_req:", qat_req, + /* Handle Single-Pass GCM */ + if (ctx->is_single_pass) { + cipher_param->spc_aad_addr = op->sym->aead.aad.phys_addr; + cipher_param->spc_auth_res_addr = + op->sym->aead.digest.phys_addr; + } + +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "qat_req:", qat_req, sizeof(struct icp_qat_fw_la_bulk_req)); - rte_hexdump(stdout, "src_data:", + QAT_DP_HEXDUMP_LOG(DEBUG, "src_data:", rte_pktmbuf_mtod(op->sym->m_src, uint8_t*), rte_pktmbuf_data_len(op->sym->m_src)); if (do_cipher) { uint8_t *cipher_iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, ctx->cipher_iv.offset); - rte_hexdump(stdout, "cipher iv:", cipher_iv_ptr, + QAT_DP_HEXDUMP_LOG(DEBUG, "cipher iv:", cipher_iv_ptr, ctx->cipher_iv.length); } @@ -550,17 +621,17 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, uint8_t *auth_iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, ctx->auth_iv.offset); - rte_hexdump(stdout, "auth iv:", auth_iv_ptr, + QAT_DP_HEXDUMP_LOG(DEBUG, "auth iv:", auth_iv_ptr, ctx->auth_iv.length); } - rte_hexdump(stdout, "digest:", op->sym->auth.digest.data, + QAT_DP_HEXDUMP_LOG(DEBUG, "digest:", op->sym->auth.digest.data, ctx->digest_length); } if (do_aead) { - rte_hexdump(stdout, "digest:", op->sym->aead.digest.data, + QAT_DP_HEXDUMP_LOG(DEBUG, "digest:", op->sym->aead.digest.data, ctx->digest_length); - rte_hexdump(stdout, "aad:", op->sym->aead.aad.data, + QAT_DP_HEXDUMP_LOG(DEBUG, "aad:", op->sym->aead.aad.data, ctx->aad_len); } #endif