X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Fccp%2Fccp_crypto.c;h=db3fb6eff837117ce6fcb3b913eb3c9391a74907;hb=f593944fc988dfccebed62205fd0b88c60ed7d77;hp=53e731b7e39c3cc309ee1eb89baf70e822ba92f3;hpb=1df800f8951882ab38fe8a82ac419b9718a1b910;p=dpdk.git diff --git a/drivers/crypto/ccp/ccp_crypto.c b/drivers/crypto/ccp/ccp_crypto.c index 53e731b7e3..db3fb6eff8 100644 --- a/drivers/crypto/ccp/ccp_crypto.c +++ b/drivers/crypto/ccp/ccp_crypto.c @@ -27,6 +27,10 @@ #include "ccp_pci.h" #include "ccp_pmd_private.h" +#include +#include +#include + /* SHA initial context values */ static uint32_t ccp_sha1_init[SHA_COMMON_DIGEST_SIZE / sizeof(uint32_t)] = { SHA1_H4, SHA1_H3, @@ -760,6 +764,19 @@ ccp_configure_session_auth(struct ccp_session *sess, else sess->auth.op = CCP_AUTH_OP_VERIFY; switch (auth_xform->algo) { + case RTE_CRYPTO_AUTH_MD5_HMAC: + if (sess->auth_opt) { + sess->auth.algo = CCP_AUTH_ALGO_MD5_HMAC; + sess->auth.offset = ((CCP_SB_BYTES << 1) - + MD5_DIGEST_SIZE); + sess->auth.key_length = auth_xform->key.length; + sess->auth.block_size = MD5_BLOCK_SIZE; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else + return -1; /* HMAC MD5 not supported on CCP */ + break; case RTE_CRYPTO_AUTH_SHA1: sess->auth.engine = CCP_ENGINE_SHA; sess->auth.algo = CCP_AUTH_ALGO_SHA1; @@ -769,21 +786,34 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.offset = CCP_SB_BYTES - SHA1_DIGEST_SIZE; break; case RTE_CRYPTO_AUTH_SHA1_HMAC: - if (auth_xform->key.length > SHA1_BLOCK_SIZE) - return -1; - sess->auth.engine = CCP_ENGINE_SHA; - sess->auth.algo = CCP_AUTH_ALGO_SHA1_HMAC; - sess->auth.ut.sha_type = CCP_SHA_TYPE_1; - sess->auth.ctx_len = CCP_SB_BYTES; - sess->auth.offset = CCP_SB_BYTES - SHA1_DIGEST_SIZE; - sess->auth.block_size = SHA1_BLOCK_SIZE; - sess->auth.key_length = auth_xform->key.length; - memset(sess->auth.key, 0, sess->auth.block_size); - memset(sess->auth.pre_compute, 0, sess->auth.ctx_len << 1); - rte_memcpy(sess->auth.key, auth_xform->key.data, - auth_xform->key.length); - if (generate_partial_hash(sess)) - return -1; + if (sess->auth_opt) { + if (auth_xform->key.length > SHA1_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA1_HMAC; + sess->auth.offset = CCP_SB_BYTES - SHA1_DIGEST_SIZE; + sess->auth.block_size = SHA1_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else { + if (auth_xform->key.length > SHA1_BLOCK_SIZE) + return -1; + sess->auth.engine = CCP_ENGINE_SHA; + sess->auth.algo = CCP_AUTH_ALGO_SHA1_HMAC; + sess->auth.ut.sha_type = CCP_SHA_TYPE_1; + sess->auth.ctx_len = CCP_SB_BYTES; + sess->auth.offset = CCP_SB_BYTES - SHA1_DIGEST_SIZE; + sess->auth.block_size = SHA1_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + memset(sess->auth.pre_compute, 0, + sess->auth.ctx_len << 1); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + if (generate_partial_hash(sess)) + return -1; + } break; case RTE_CRYPTO_AUTH_SHA224: sess->auth.algo = CCP_AUTH_ALGO_SHA224; @@ -794,21 +824,34 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.offset = CCP_SB_BYTES - SHA224_DIGEST_SIZE; break; case RTE_CRYPTO_AUTH_SHA224_HMAC: - if (auth_xform->key.length > SHA224_BLOCK_SIZE) - return -1; - sess->auth.algo = CCP_AUTH_ALGO_SHA224_HMAC; - sess->auth.engine = CCP_ENGINE_SHA; - sess->auth.ut.sha_type = CCP_SHA_TYPE_224; - sess->auth.ctx_len = CCP_SB_BYTES; - sess->auth.offset = CCP_SB_BYTES - SHA224_DIGEST_SIZE; - sess->auth.block_size = SHA224_BLOCK_SIZE; - sess->auth.key_length = auth_xform->key.length; - memset(sess->auth.key, 0, sess->auth.block_size); - memset(sess->auth.pre_compute, 0, sess->auth.ctx_len << 1); - rte_memcpy(sess->auth.key, auth_xform->key.data, - auth_xform->key.length); - if (generate_partial_hash(sess)) - return -1; + if (sess->auth_opt) { + if (auth_xform->key.length > SHA224_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA224_HMAC; + sess->auth.offset = CCP_SB_BYTES - SHA224_DIGEST_SIZE; + sess->auth.block_size = SHA224_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else { + if (auth_xform->key.length > SHA224_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA224_HMAC; + sess->auth.engine = CCP_ENGINE_SHA; + sess->auth.ut.sha_type = CCP_SHA_TYPE_224; + sess->auth.ctx_len = CCP_SB_BYTES; + sess->auth.offset = CCP_SB_BYTES - SHA224_DIGEST_SIZE; + sess->auth.block_size = SHA224_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + memset(sess->auth.pre_compute, 0, + sess->auth.ctx_len << 1); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + if (generate_partial_hash(sess)) + return -1; + } break; case RTE_CRYPTO_AUTH_SHA3_224: sess->auth.algo = CCP_AUTH_ALGO_SHA3_224; @@ -843,21 +886,34 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.offset = CCP_SB_BYTES - SHA256_DIGEST_SIZE; break; case RTE_CRYPTO_AUTH_SHA256_HMAC: - if (auth_xform->key.length > SHA256_BLOCK_SIZE) - return -1; - sess->auth.algo = CCP_AUTH_ALGO_SHA256_HMAC; - sess->auth.engine = CCP_ENGINE_SHA; - sess->auth.ut.sha_type = CCP_SHA_TYPE_256; - sess->auth.ctx_len = CCP_SB_BYTES; - sess->auth.offset = CCP_SB_BYTES - SHA256_DIGEST_SIZE; - sess->auth.block_size = SHA256_BLOCK_SIZE; - sess->auth.key_length = auth_xform->key.length; - memset(sess->auth.key, 0, sess->auth.block_size); - memset(sess->auth.pre_compute, 0, sess->auth.ctx_len << 1); - rte_memcpy(sess->auth.key, auth_xform->key.data, - auth_xform->key.length); - if (generate_partial_hash(sess)) - return -1; + if (sess->auth_opt) { + if (auth_xform->key.length > SHA256_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA256_HMAC; + sess->auth.offset = CCP_SB_BYTES - SHA256_DIGEST_SIZE; + sess->auth.block_size = SHA256_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else { + if (auth_xform->key.length > SHA256_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA256_HMAC; + sess->auth.engine = CCP_ENGINE_SHA; + sess->auth.ut.sha_type = CCP_SHA_TYPE_256; + sess->auth.ctx_len = CCP_SB_BYTES; + sess->auth.offset = CCP_SB_BYTES - SHA256_DIGEST_SIZE; + sess->auth.block_size = SHA256_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + memset(sess->auth.pre_compute, 0, + sess->auth.ctx_len << 1); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + if (generate_partial_hash(sess)) + return -1; + } break; case RTE_CRYPTO_AUTH_SHA3_256: sess->auth.algo = CCP_AUTH_ALGO_SHA3_256; @@ -892,21 +948,36 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.offset = (CCP_SB_BYTES << 1) - SHA384_DIGEST_SIZE; break; case RTE_CRYPTO_AUTH_SHA384_HMAC: - if (auth_xform->key.length > SHA384_BLOCK_SIZE) - return -1; - sess->auth.algo = CCP_AUTH_ALGO_SHA384_HMAC; - sess->auth.engine = CCP_ENGINE_SHA; - sess->auth.ut.sha_type = CCP_SHA_TYPE_384; - sess->auth.ctx_len = CCP_SB_BYTES << 1; - sess->auth.offset = (CCP_SB_BYTES << 1) - SHA384_DIGEST_SIZE; - sess->auth.block_size = SHA384_BLOCK_SIZE; - sess->auth.key_length = auth_xform->key.length; - memset(sess->auth.key, 0, sess->auth.block_size); - memset(sess->auth.pre_compute, 0, sess->auth.ctx_len << 1); - rte_memcpy(sess->auth.key, auth_xform->key.data, - auth_xform->key.length); - if (generate_partial_hash(sess)) - return -1; + if (sess->auth_opt) { + if (auth_xform->key.length > SHA384_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA384_HMAC; + sess->auth.offset = ((CCP_SB_BYTES << 1) - + SHA384_DIGEST_SIZE); + sess->auth.block_size = SHA384_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else { + if (auth_xform->key.length > SHA384_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA384_HMAC; + sess->auth.engine = CCP_ENGINE_SHA; + sess->auth.ut.sha_type = CCP_SHA_TYPE_384; + sess->auth.ctx_len = CCP_SB_BYTES << 1; + sess->auth.offset = ((CCP_SB_BYTES << 1) - + SHA384_DIGEST_SIZE); + sess->auth.block_size = SHA384_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + memset(sess->auth.pre_compute, 0, + sess->auth.ctx_len << 1); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + if (generate_partial_hash(sess)) + return -1; + } break; case RTE_CRYPTO_AUTH_SHA3_384: sess->auth.algo = CCP_AUTH_ALGO_SHA3_384; @@ -941,21 +1012,36 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.offset = (CCP_SB_BYTES << 1) - SHA512_DIGEST_SIZE; break; case RTE_CRYPTO_AUTH_SHA512_HMAC: - if (auth_xform->key.length > SHA512_BLOCK_SIZE) - return -1; - sess->auth.algo = CCP_AUTH_ALGO_SHA512_HMAC; - sess->auth.engine = CCP_ENGINE_SHA; - sess->auth.ut.sha_type = CCP_SHA_TYPE_512; - sess->auth.ctx_len = CCP_SB_BYTES << 1; - sess->auth.offset = (CCP_SB_BYTES << 1) - SHA512_DIGEST_SIZE; - sess->auth.block_size = SHA512_BLOCK_SIZE; - sess->auth.key_length = auth_xform->key.length; - memset(sess->auth.key, 0, sess->auth.block_size); - memset(sess->auth.pre_compute, 0, sess->auth.ctx_len << 1); - rte_memcpy(sess->auth.key, auth_xform->key.data, - auth_xform->key.length); - if (generate_partial_hash(sess)) - return -1; + if (sess->auth_opt) { + if (auth_xform->key.length > SHA512_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA512_HMAC; + sess->auth.offset = ((CCP_SB_BYTES << 1) - + SHA512_DIGEST_SIZE); + sess->auth.block_size = SHA512_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + } else { + if (auth_xform->key.length > SHA512_BLOCK_SIZE) + return -1; + sess->auth.algo = CCP_AUTH_ALGO_SHA512_HMAC; + sess->auth.engine = CCP_ENGINE_SHA; + sess->auth.ut.sha_type = CCP_SHA_TYPE_512; + sess->auth.ctx_len = CCP_SB_BYTES << 1; + sess->auth.offset = ((CCP_SB_BYTES << 1) - + SHA512_DIGEST_SIZE); + sess->auth.block_size = SHA512_BLOCK_SIZE; + sess->auth.key_length = auth_xform->key.length; + memset(sess->auth.key, 0, sess->auth.block_size); + memset(sess->auth.pre_compute, 0, + sess->auth.ctx_len << 1); + rte_memcpy(sess->auth.key, auth_xform->key.data, + auth_xform->key.length); + if (generate_partial_hash(sess)) + return -1; + } break; case RTE_CRYPTO_AUTH_SHA3_512: sess->auth.algo = CCP_AUTH_ALGO_SHA3_512; @@ -986,7 +1072,7 @@ ccp_configure_session_auth(struct ccp_session *sess, sess->auth.engine = CCP_ENGINE_AES; sess->auth.um.aes_mode = CCP_AES_MODE_CMAC; sess->auth.key_length = auth_xform->key.length; - /**auth.ctx_len = CCP_SB_BYTES << 1; sess->auth.offset = AES_BLOCK_SIZE; sess->auth.block_size = AES_BLOCK_SIZE; @@ -1080,13 +1166,15 @@ ccp_configure_session_aead(struct ccp_session *sess, int ccp_set_session_parameters(struct ccp_session *sess, - const struct rte_crypto_sym_xform *xform) + const struct rte_crypto_sym_xform *xform, + struct ccp_private *internals) { const struct rte_crypto_sym_xform *cipher_xform = NULL; const struct rte_crypto_sym_xform *auth_xform = NULL; const struct rte_crypto_sym_xform *aead_xform = NULL; int ret = 0; + sess->auth_opt = internals->auth_opt; sess->cmd_id = ccp_get_cmd_id(xform); switch (sess->cmd_id) { @@ -1182,14 +1270,16 @@ ccp_auth_slot(struct ccp_session *session) count = 3; /**< op + lsb passthrough cpy to/from*/ break; + case CCP_AUTH_ALGO_MD5_HMAC: + break; case CCP_AUTH_ALGO_SHA1_HMAC: case CCP_AUTH_ALGO_SHA224_HMAC: case CCP_AUTH_ALGO_SHA256_HMAC: - count = 6; + if (session->auth_opt == 0) + count = 6; break; case CCP_AUTH_ALGO_SHA384_HMAC: case CCP_AUTH_ALGO_SHA512_HMAC: - count = 7; /** * 1. Load PHash1 = H(k ^ ipad); to LSB * 2. generate IHash = H(hash on meassage with PHash1 @@ -1200,6 +1290,8 @@ ccp_auth_slot(struct ccp_session *session) * as init value); * 6. Retrieve HMAC output from LSB to host memory */ + if (session->auth_opt == 0) + count = 7; break; case CCP_AUTH_ALGO_SHA3_224: case CCP_AUTH_ALGO_SHA3_256: @@ -1296,6 +1388,120 @@ ccp_compute_slot_count(struct ccp_session *session) return count; } +static uint8_t +algo_select(int sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + switch (sessalgo) { + case CCP_AUTH_ALGO_MD5_HMAC: + *algo = EVP_md5(); + break; + case CCP_AUTH_ALGO_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case CCP_AUTH_ALGO_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case CCP_AUTH_ALGO_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case CCP_AUTH_ALGO_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case CCP_AUTH_ALGO_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + return res; +} + +static int +process_cpu_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, + EVP_PKEY *pkey, + int srclen, + EVP_MD_CTX *ctx, + const EVP_MD *algo, + uint16_t d_len) +{ + size_t dstlen; + unsigned char temp_dst[64]; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, temp_dst, &dstlen) <= 0) + goto process_auth_err; + + memcpy(dst, temp_dst, d_len); + return 0; +process_auth_err: + CCP_LOG_ERR("Process cpu auth failed"); + return -EINVAL; +} + +static int cpu_crypto_auth(struct ccp_qp *qp, + struct rte_crypto_op *op, + struct ccp_session *sess, + EVP_MD_CTX *ctx) +{ + uint8_t *src, *dst; + int srclen, status; + struct rte_mbuf *mbuf_src, *mbuf_dst; + const EVP_MD *algo = NULL; + EVP_PKEY *pkey; + + algo_select(sess->auth.algo, &algo); + pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sess->auth.key, + sess->auth.key_length); + mbuf_src = op->sym->m_src; + mbuf_dst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + + if (sess->auth.op == CCP_AUTH_OP_VERIFY) { + dst = qp->temp_digest; + } else { + dst = op->sym->auth.digest.data; + if (dst == NULL) { + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + sess->auth.digest_length); + } + } + status = process_cpu_auth_hmac(src, dst, NULL, + pkey, srclen, + ctx, + algo, + sess->auth.digest_length); + if (status) { + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + return status; + } + + if (sess->auth.op == CCP_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + sess->auth.digest_length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } else { + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + } + } else { + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + } + EVP_PKEY_free(pkey); + return 0; +} + static void ccp_perform_passthru(struct ccp_passthru *pst, struct ccp_queue *cmd_q) @@ -1360,12 +1566,12 @@ ccp_perform_hmac(struct rte_crypto_op *op, void *append_ptr; uint8_t *addr; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); addr = session->auth.pre_compute; - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->auth.data.offset); append_ptr = (void *)rte_pktmbuf_append(op->sym->m_src, session->auth.ctx_len); @@ -1533,11 +1739,11 @@ ccp_perform_sha(struct rte_crypto_op *op, void *append_ptr; uint64_t auth_msg_bits; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->auth.data.offset); append_ptr = (void *)rte_pktmbuf_append(op->sym->m_src, @@ -1622,11 +1828,11 @@ ccp_perform_sha3_hmac(struct rte_crypto_op *op, uint32_t tail; phys_addr_t src_addr, dest_addr, ctx_paddr, dest_addr_t; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->auth.data.offset); append_ptr = (uint8_t *)rte_pktmbuf_append(op->sym->m_src, session->auth.ctx_len); @@ -1762,11 +1968,11 @@ ccp_perform_sha3(struct rte_crypto_op *op, uint32_t tail; phys_addr_t src_addr, dest_addr, ctx_paddr; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->auth.data.offset); append_ptr = (uint8_t *)rte_pktmbuf_append(op->sym->m_src, session->auth.ctx_len); @@ -1830,12 +2036,12 @@ ccp_perform_aes_cmac(struct rte_crypto_op *op, phys_addr_t src_addr, dest_addr, key_addr; int length, non_align_len; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); key_addr = rte_mem_virt2phy(session->auth.key_ccp); - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->auth.data.offset); append_ptr = (uint8_t *)rte_pktmbuf_append(op->sym->m_src, session->auth.ctx_len); @@ -1982,7 +2188,7 @@ ccp_perform_aes(struct rte_crypto_op *op, phys_addr_t src_addr, dest_addr, key_addr; uint8_t *iv; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); function.raw = 0; @@ -2015,10 +2221,10 @@ ccp_perform_aes(struct rte_crypto_op *op, desc = &cmd_q->qbase_desc[cmd_q->qidx]; - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->cipher.data.offset); if (likely(op->sym->m_dst != NULL)) - dest_addr = rte_pktmbuf_mtophys_offset(op->sym->m_dst, + dest_addr = rte_pktmbuf_iova_offset(op->sym->m_dst, op->sym->cipher.data.offset); else dest_addr = src_addr; @@ -2070,7 +2276,7 @@ ccp_perform_3des(struct rte_crypto_op *op, uint8_t *iv; phys_addr_t src_addr, dest_addr, key_addr; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); @@ -2097,11 +2303,11 @@ ccp_perform_3des(struct rte_crypto_op *op, return -ENOTSUP; } - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->cipher.data.offset); if (unlikely(op->sym->m_dst != NULL)) dest_addr = - rte_pktmbuf_mtophys_offset(op->sym->m_dst, + rte_pktmbuf_iova_offset(op->sym->m_dst, op->sym->cipher.data.offset); else dest_addr = src_addr; @@ -2173,16 +2379,16 @@ ccp_perform_aes_gcm(struct rte_crypto_op *op, struct ccp_queue *cmd_q) phys_addr_t digest_dest_addr; int length, non_align_len; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); iv = rte_crypto_op_ctod_offset(op, uint8_t *, session->iv.offset); key_addr = session->cipher.key_phys; - src_addr = rte_pktmbuf_mtophys_offset(op->sym->m_src, + src_addr = rte_pktmbuf_iova_offset(op->sym->m_src, op->sym->aead.data.offset); if (unlikely(op->sym->m_dst != NULL)) - dest_addr = rte_pktmbuf_mtophys_offset(op->sym->m_dst, + dest_addr = rte_pktmbuf_iova_offset(op->sym->m_dst, op->sym->aead.data.offset); else dest_addr = src_addr; @@ -2340,7 +2546,7 @@ ccp_crypto_cipher(struct rte_crypto_op *op, int result = 0; struct ccp_session *session; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); @@ -2378,7 +2584,7 @@ ccp_crypto_auth(struct rte_crypto_op *op, int result = 0; struct ccp_session *session; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); @@ -2391,16 +2597,24 @@ ccp_crypto_auth(struct rte_crypto_op *op, result = ccp_perform_sha(op, cmd_q); b_info->desccnt += 3; break; + case CCP_AUTH_ALGO_MD5_HMAC: + if (session->auth_opt == 0) + result = -1; + break; case CCP_AUTH_ALGO_SHA1_HMAC: case CCP_AUTH_ALGO_SHA224_HMAC: case CCP_AUTH_ALGO_SHA256_HMAC: - result = ccp_perform_hmac(op, cmd_q); - b_info->desccnt += 6; + if (session->auth_opt == 0) { + result = ccp_perform_hmac(op, cmd_q); + b_info->desccnt += 6; + } break; case CCP_AUTH_ALGO_SHA384_HMAC: case CCP_AUTH_ALGO_SHA512_HMAC: - result = ccp_perform_hmac(op, cmd_q); - b_info->desccnt += 7; + if (session->auth_opt == 0) { + result = ccp_perform_hmac(op, cmd_q); + b_info->desccnt += 7; + } break; case CCP_AUTH_ALGO_SHA3_224: case CCP_AUTH_ALGO_SHA3_256: @@ -2440,7 +2654,7 @@ ccp_crypto_aead(struct rte_crypto_op *op, int result = 0; struct ccp_session *session; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); @@ -2462,22 +2676,34 @@ ccp_crypto_aead(struct rte_crypto_op *op, } int -process_ops_to_enqueue(const struct ccp_qp *qp, +process_ops_to_enqueue(struct ccp_qp *qp, struct rte_crypto_op **op, struct ccp_queue *cmd_q, uint16_t nb_ops, - int slots_req) + uint16_t total_nb_ops, + int slots_req, + uint16_t b_idx) { int i, result = 0; struct ccp_batch_info *b_info; struct ccp_session *session; + EVP_MD_CTX *auth_ctx = NULL; if (rte_mempool_get(qp->batch_mp, (void **)&b_info)) { CCP_LOG_ERR("batch info allocation failed"); return 0; } + + auth_ctx = EVP_MD_CTX_create(); + if (unlikely(!auth_ctx)) { + CCP_LOG_ERR("Unable to create auth ctx"); + return 0; + } + b_info->auth_ctr = 0; + /* populate batch info necessary for dequeue */ b_info->op_idx = 0; + b_info->b_idx = 0; b_info->lsb_buf_idx = 0; b_info->desccnt = 0; b_info->cmd_q = cmd_q; @@ -2487,8 +2713,8 @@ process_ops_to_enqueue(const struct ccp_qp *qp, b_info->head_offset = (uint32_t)(cmd_q->qbase_phys_addr + cmd_q->qidx * Q_DESC_SIZE); - for (i = 0; i < nb_ops; i++) { - session = (struct ccp_session *)get_session_private_data( + for (i = b_idx; i < (nb_ops+b_idx); i++) { + session = (struct ccp_session *)get_sym_session_private_data( op[i]->sym->session, ccp_cryptodev_driver_id); switch (session->cmd_id) { @@ -2496,7 +2722,12 @@ process_ops_to_enqueue(const struct ccp_qp *qp, result = ccp_crypto_cipher(op[i], cmd_q, b_info); break; case CCP_CMD_AUTH: - result = ccp_crypto_auth(op[i], cmd_q, b_info); + if (session->auth_opt) { + b_info->auth_ctr++; + result = cpu_crypto_auth(qp, op[i], + session, auth_ctx); + } else + result = ccp_crypto_auth(op[i], cmd_q, b_info); break; case CCP_CMD_CIPHER_HASH: result = ccp_crypto_cipher(op[i], cmd_q, b_info); @@ -2505,7 +2736,15 @@ process_ops_to_enqueue(const struct ccp_qp *qp, result = ccp_crypto_auth(op[i], cmd_q, b_info); break; case CCP_CMD_HASH_CIPHER: - result = ccp_crypto_auth(op[i], cmd_q, b_info); + if (session->auth_opt) { + result = cpu_crypto_auth(qp, op[i], + session, auth_ctx); + if (op[i]->status != + RTE_CRYPTO_OP_STATUS_SUCCESS) + CCP_LOG_ERR("RTE_CRYPTO_OP_STATUS_AUTH_FAILED"); + } else + result = ccp_crypto_auth(op[i], cmd_q, b_info); + if (result) break; result = ccp_crypto_cipher(op[i], cmd_q, b_info); @@ -2526,6 +2765,8 @@ process_ops_to_enqueue(const struct ccp_qp *qp, } b_info->opcnt = i; + b_info->b_idx = b_idx; + b_info->total_nb_ops = total_nb_ops; b_info->tail_offset = (uint32_t)(cmd_q->qbase_phys_addr + cmd_q->qidx * Q_DESC_SIZE); @@ -2539,7 +2780,8 @@ process_ops_to_enqueue(const struct ccp_qp *qp, rte_ring_enqueue(qp->processed_pkts, (void *)b_info); - return i; + EVP_MD_CTX_destroy(auth_ctx); + return i-b_idx; } static inline void ccp_auth_dq_prepare(struct rte_crypto_op *op) @@ -2550,7 +2792,7 @@ static inline void ccp_auth_dq_prepare(struct rte_crypto_op *op) int offset, digest_offset; uint8_t digest_le[64]; - session = (struct ccp_session *)get_session_private_data( + session = (struct ccp_session *)get_sym_session_private_data( op->sym->session, ccp_cryptodev_driver_id); @@ -2607,18 +2849,26 @@ static inline void ccp_auth_dq_prepare(struct rte_crypto_op *op) } static int -ccp_prepare_ops(struct rte_crypto_op **op_d, +ccp_prepare_ops(struct ccp_qp *qp, + struct rte_crypto_op **op_d, struct ccp_batch_info *b_info, uint16_t nb_ops) { int i, min_ops; struct ccp_session *session; + EVP_MD_CTX *auth_ctx = NULL; + + auth_ctx = EVP_MD_CTX_create(); + if (unlikely(!auth_ctx)) { + CCP_LOG_ERR("Unable to create auth ctx"); + return 0; + } min_ops = RTE_MIN(nb_ops, b_info->opcnt); - for (i = 0; i < min_ops; i++) { - op_d[i] = b_info->op[b_info->op_idx++]; - session = (struct ccp_session *)get_session_private_data( + for (i = b_info->b_idx; i < min_ops; i++) { + op_d[i] = b_info->op[b_info->b_idx + b_info->op_idx++]; + session = (struct ccp_session *)get_sym_session_private_data( op_d[i]->sym->session, ccp_cryptodev_driver_id); switch (session->cmd_id) { @@ -2626,8 +2876,22 @@ ccp_prepare_ops(struct rte_crypto_op **op_d, op_d[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS; break; case CCP_CMD_AUTH: + if (session->auth_opt == 0) + ccp_auth_dq_prepare(op_d[i]); + break; case CCP_CMD_CIPHER_HASH: + if (session->auth_opt) + cpu_crypto_auth(qp, op_d[i], + session, auth_ctx); + else + ccp_auth_dq_prepare(op_d[i]); + break; case CCP_CMD_HASH_CIPHER: + if (session->auth_opt) + op_d[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + else + ccp_auth_dq_prepare(op_d[i]); + break; case CCP_CMD_COMBINED: ccp_auth_dq_prepare(op_d[i]); break; @@ -2636,6 +2900,7 @@ ccp_prepare_ops(struct rte_crypto_op **op_d, } } + EVP_MD_CTX_destroy(auth_ctx); b_info->opcnt -= min_ops; return min_ops; } @@ -2643,7 +2908,8 @@ ccp_prepare_ops(struct rte_crypto_op **op_d, int process_ops_to_dequeue(struct ccp_qp *qp, struct rte_crypto_op **op, - uint16_t nb_ops) + uint16_t nb_ops, + uint16_t *total_nb_ops) { struct ccp_batch_info *b_info; uint32_t cur_head_offset; @@ -2655,6 +2921,10 @@ process_ops_to_dequeue(struct ccp_qp *qp, } else if (rte_ring_dequeue(qp->processed_pkts, (void **)&b_info)) return 0; + + if (b_info->auth_ctr == b_info->opcnt) + goto success; + *total_nb_ops = b_info->total_nb_ops; cur_head_offset = CCP_READ_REG(b_info->cmd_q->reg_base, CMD_Q_HEAD_LO_BASE); @@ -2664,7 +2934,7 @@ process_ops_to_dequeue(struct ccp_qp *qp, qp->b_info = b_info; return 0; } - } else { + } else if (b_info->tail_offset != b_info->head_offset) { if ((cur_head_offset >= b_info->head_offset) || (cur_head_offset < b_info->tail_offset)) { qp->b_info = b_info; @@ -2674,7 +2944,8 @@ process_ops_to_dequeue(struct ccp_qp *qp, success: - nb_ops = ccp_prepare_ops(op, b_info, nb_ops); + *total_nb_ops = b_info->total_nb_ops; + nb_ops = ccp_prepare_ops(qp, op, b_info, nb_ops); rte_atomic64_add(&b_info->cmd_q->free_slots, b_info->desccnt); b_info->desccnt = 0; if (b_info->opcnt > 0) {