From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 3CF2B1B3E8 for ; Wed, 19 Dec 2018 22:42:48 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Dec 2018 13:42:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,374,1539673200"; d="scan'208";a="285107147" Received: from silpixa00398673.ir.intel.com (HELO silpixa00398673.ger.corp.intel.com) ([10.237.223.54]) by orsmga005.jf.intel.com with ESMTP; 19 Dec 2018 13:42:46 -0800 From: Fan Zhang To: dev@dpdk.org Cc: akhil.goyal@nxp.com Date: Wed, 19 Dec 2018 21:42:42 +0000 Message-Id: <20181219214244.21234-2-roy.fan.zhang@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20181219214244.21234-1-roy.fan.zhang@intel.com> References: <20181218135125.68547-1-roy.fan.zhang@intel.com> <20181219214244.21234-1-roy.fan.zhang@intel.com> Subject: [dpdk-dev] [PATCH v4 1/3] crypto/aesni_mb: add gmac support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Dec 2018 21:42:48 -0000 This patch updates the AESNI-MB PMD to add AES-GMAC support. Signed-off-by: Fan Zhang Acked-by: Damian Nowak --- drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 126 +++++++++++++++----- drivers/crypto/aesni_mb/rte_aesni_mb_pmd_compat.c | 127 ++++++++++++++++----- drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 25 ++++ .../crypto/aesni_mb/rte_aesni_mb_pmd_ops_compat.c | 25 ++++ 4 files changed, 250 insertions(+), 53 deletions(-) diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c index 2c25b7b32..d34cbc36a 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c @@ -173,6 +173,54 @@ aesni_mb_set_session_auth_parameters(const MB_MGR *mb_mgr, return 0; } + if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { + if (xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) { + sess->cipher.direction = ENCRYPT; + sess->chain_order = CIPHER_HASH; + } else + sess->cipher.direction = DECRYPT; + + sess->auth.algo = AES_GMAC; + /* + * Multi-buffer lib supports 8, 12 and 16 bytes of digest. + * If size requested is different, generate the full digest + * (16 bytes) in a temporary location and then memcpy + * the requested number of bytes. + */ + if (sess->auth.req_digest_len != 16 && + sess->auth.req_digest_len != 12 && + sess->auth.req_digest_len != 8) { + sess->auth.gen_digest_len = 16; + } else { + sess->auth.gen_digest_len = sess->auth.req_digest_len; + } + sess->iv.length = xform->auth.iv.length; + sess->iv.offset = xform->auth.iv.offset; + + switch (xform->auth.key.length) { + case AES_128_BYTES: + IMB_AES128_GCM_PRE(mb_mgr, xform->auth.key.data, + &sess->cipher.gcm_key); + sess->cipher.key_length_in_bytes = AES_128_BYTES; + break; + case AES_192_BYTES: + IMB_AES192_GCM_PRE(mb_mgr, xform->auth.key.data, + &sess->cipher.gcm_key); + sess->cipher.key_length_in_bytes = AES_192_BYTES; + break; + case AES_256_BYTES: + IMB_AES256_GCM_PRE(mb_mgr, xform->auth.key.data, + &sess->cipher.gcm_key); + sess->cipher.key_length_in_bytes = AES_256_BYTES; + break; + default: + RTE_LOG(ERR, PMD, "failed to parse test type\n"); + return -EINVAL; + } + + return 0; + } + switch (xform->auth.algo) { case RTE_CRYPTO_AUTH_MD5_HMAC: sess->auth.algo = MD5; @@ -735,8 +783,16 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, break; case AES_GMAC: - job->u.GCM.aad = op->sym->aead.aad.data; - job->u.GCM.aad_len_in_bytes = session->aead.aad_len; + if (session->cipher.mode == GCM) { + job->u.GCM.aad = op->sym->aead.aad.data; + job->u.GCM.aad_len_in_bytes = session->aead.aad_len; + } else { + /* For GMAC */ + job->u.GCM.aad = rte_pktmbuf_mtod_offset(m_src, + uint8_t *, op->sym->auth.data.offset); + job->u.GCM.aad_len_in_bytes = op->sym->auth.data.length; + job->cipher_mode = GCM; + } job->aes_enc_key_expanded = &session->cipher.gcm_key; job->aes_dec_key_expanded = &session->cipher.gcm_key; break; @@ -776,7 +832,8 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, rte_pktmbuf_data_len(op->sym->m_src)); } else { m_dst = m_src; - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) + if (job->hash_alg == AES_CCM || (job->hash_alg == AES_GMAC && + session->cipher.mode == GCM)) m_offset = op->sym->aead.data.offset; else m_offset = op->sym->cipher.data.offset; @@ -788,7 +845,8 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, job->auth_tag_output = qp->temp_digests[*digest_idx]; *digest_idx = (*digest_idx + 1) % MAX_JOBS; } else { - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) + if (job->hash_alg == AES_CCM || (job->hash_alg == AES_GMAC && + session->cipher.mode == GCM)) job->auth_tag_output = op->sym->aead.digest.data; else job->auth_tag_output = op->sym->auth.digest.data; @@ -826,11 +884,24 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, break; case AES_GMAC: - job->cipher_start_src_offset_in_bytes = - op->sym->aead.data.offset; - job->hash_start_src_offset_in_bytes = op->sym->aead.data.offset; - job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length; - job->msg_len_to_hash_in_bytes = job->msg_len_to_cipher_in_bytes; + if (session->cipher.mode == GCM) { + job->cipher_start_src_offset_in_bytes = + op->sym->aead.data.offset; + job->hash_start_src_offset_in_bytes = + op->sym->aead.data.offset; + job->msg_len_to_cipher_in_bytes = + op->sym->aead.data.length; + job->msg_len_to_hash_in_bytes = + op->sym->aead.data.length; + } else { + job->cipher_start_src_offset_in_bytes = + op->sym->auth.data.offset; + job->hash_start_src_offset_in_bytes = + op->sym->auth.data.offset; + job->msg_len_to_cipher_in_bytes = 0; + job->msg_len_to_hash_in_bytes = 0; + } + job->iv = rte_crypto_op_ctod_offset(op, uint8_t *, session->iv.offset); break; @@ -854,19 +925,11 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, } static inline void -verify_digest(JOB_AES_HMAC *job, struct rte_crypto_op *op, - struct aesni_mb_session *sess) +verify_digest(JOB_AES_HMAC *job, void *digest, uint16_t len, uint8_t *status) { /* Verify digest if required */ - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) { - if (memcmp(job->auth_tag_output, op->sym->aead.digest.data, - sess->auth.req_digest_len) != 0) - op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; - } else { - if (memcmp(job->auth_tag_output, op->sym->auth.digest.data, - sess->auth.req_digest_len) != 0) - op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; - } + if (memcmp(job->auth_tag_output, digest, len) != 0) + *status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; } static inline void @@ -908,13 +971,24 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job) case STS_COMPLETED: op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; - if (job->hash_alg != NULL_HASH) { - if (sess->auth.operation == - RTE_CRYPTO_AUTH_OP_VERIFY) - verify_digest(job, op, sess); + if (job->hash_alg == NULL_HASH) + break; + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (job->hash_alg == AES_CCM || + (job->hash_alg == AES_GMAC && + sess->cipher.mode == GCM)) + verify_digest(job, + op->sym->aead.digest.data, + sess->auth.req_digest_len, + &op->status); else - generate_digest(job, op, sess); - } + verify_digest(job, + op->sym->auth.digest.data, + sess->auth.req_digest_len, + &op->status); + } else + generate_digest(job, op, sess); break; default: op->status = RTE_CRYPTO_OP_STATUS_ERROR; diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_compat.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_compat.c index 83250e32c..56ce54946 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_compat.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_compat.c @@ -177,6 +177,54 @@ aesni_mb_set_session_auth_parameters(const struct aesni_mb_op_fns *mb_ops, return 0; } + if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { + if (xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) { + sess->cipher.direction = ENCRYPT; + sess->chain_order = CIPHER_HASH; + } else + sess->cipher.direction = DECRYPT; + + sess->auth.algo = AES_GMAC; + /* + * Multi-buffer lib supports 8, 12 and 16 bytes of digest. + * If size requested is different, generate the full digest + * (16 bytes) in a temporary location and then memcpy + * the requested number of bytes. + */ + if (sess->auth.req_digest_len != 16 && + sess->auth.req_digest_len != 12 && + sess->auth.req_digest_len != 8) { + sess->auth.gen_digest_len = 16; + } else { + sess->auth.gen_digest_len = sess->auth.req_digest_len; + } + sess->iv.length = xform->auth.iv.length; + sess->iv.offset = xform->auth.iv.offset; + + switch (xform->auth.key.length) { + case AES_128_BYTES: + sess->cipher.key_length_in_bytes = AES_128_BYTES; + (mb_ops->aux.keyexp.aes_gcm_128)(xform->auth.key.data, + &sess->cipher.gcm_key); + break; + case AES_192_BYTES: + sess->cipher.key_length_in_bytes = AES_192_BYTES; + (mb_ops->aux.keyexp.aes_gcm_192)(xform->auth.key.data, + &sess->cipher.gcm_key); + break; + case AES_256_BYTES: + sess->cipher.key_length_in_bytes = AES_256_BYTES; + (mb_ops->aux.keyexp.aes_gcm_256)(xform->auth.key.data, + &sess->cipher.gcm_key); + break; + default: + RTE_LOG(ERR, PMD, "failed to parse test type\n"); + return -EINVAL; + } + + return 0; + } + switch (xform->auth.algo) { case RTE_CRYPTO_AUTH_MD5_HMAC: sess->auth.algo = MD5; @@ -760,8 +808,16 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, break; case AES_GMAC: - job->u.GCM.aad = op->sym->aead.aad.data; - job->u.GCM.aad_len_in_bytes = session->aead.aad_len; + if (session->cipher.mode == GCM) { + job->u.GCM.aad = op->sym->aead.aad.data; + job->u.GCM.aad_len_in_bytes = session->aead.aad_len; + } else { + /* For GMAC */ + job->u.GCM.aad = rte_pktmbuf_mtod_offset(m_src, + uint8_t *, op->sym->auth.data.offset); + job->u.GCM.aad_len_in_bytes = op->sym->auth.data.length; + job->cipher_mode = GCM; + } job->aes_enc_key_expanded = &session->cipher.gcm_key; job->aes_dec_key_expanded = &session->cipher.gcm_key; break; @@ -801,7 +857,8 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, rte_pktmbuf_data_len(op->sym->m_src)); } else { m_dst = m_src; - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) + if (job->hash_alg == AES_CCM || (job->hash_alg == AES_GMAC && + session->cipher.mode == GCM)) m_offset = op->sym->aead.data.offset; else m_offset = op->sym->cipher.data.offset; @@ -813,7 +870,8 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, job->auth_tag_output = qp->temp_digests[*digest_idx]; *digest_idx = (*digest_idx + 1) % MAX_JOBS; } else { - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) + if (job->hash_alg == AES_CCM || (job->hash_alg == AES_GMAC && + session->cipher.mode == GCM)) job->auth_tag_output = op->sym->aead.digest.data; else job->auth_tag_output = op->sym->auth.digest.data; @@ -851,13 +909,26 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, break; case AES_GMAC: - job->cipher_start_src_offset_in_bytes = - op->sym->aead.data.offset; - job->hash_start_src_offset_in_bytes = op->sym->aead.data.offset; - job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length; - job->msg_len_to_hash_in_bytes = job->msg_len_to_cipher_in_bytes; + if (session->cipher.mode == GCM) { + job->cipher_start_src_offset_in_bytes = + op->sym->aead.data.offset; + job->hash_start_src_offset_in_bytes = + op->sym->aead.data.offset; + job->msg_len_to_cipher_in_bytes = + op->sym->aead.data.length; + job->msg_len_to_hash_in_bytes = + op->sym->aead.data.length; + } else { + job->cipher_start_src_offset_in_bytes = + op->sym->auth.data.offset; + job->hash_start_src_offset_in_bytes = + op->sym->auth.data.offset; + job->msg_len_to_cipher_in_bytes = 0; + job->msg_len_to_hash_in_bytes = 0; + } job->iv = rte_crypto_op_ctod_offset(op, uint8_t *, session->iv.offset); + break; default: @@ -879,19 +950,10 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp, } static inline void -verify_digest(JOB_AES_HMAC *job, struct rte_crypto_op *op, - struct aesni_mb_session *sess) +verify_digest(JOB_AES_HMAC *job, void *digest, uint16_t len, uint8_t *status) { - /* Verify digest if required */ - if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) { - if (memcmp(job->auth_tag_output, op->sym->aead.digest.data, - sess->auth.req_digest_len) != 0) - op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; - } else { - if (memcmp(job->auth_tag_output, op->sym->auth.digest.data, - sess->auth.req_digest_len) != 0) - op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; - } + if (memcmp(job->auth_tag_output, digest, len) != 0) + *status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; } static inline void @@ -933,13 +995,24 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job) case STS_COMPLETED: op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; - if (job->hash_alg != NULL_HASH) { - if (sess->auth.operation == - RTE_CRYPTO_AUTH_OP_VERIFY) - verify_digest(job, op, sess); + if (job->hash_alg == NULL_HASH) + break; + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (job->hash_alg == AES_CCM || + (job->hash_alg == AES_GMAC && + sess->cipher.mode == GCM)) + verify_digest(job, + op->sym->aead.digest.data, + sess->auth.req_digest_len, + &op->status); else - generate_digest(job, op, sess); - } + verify_digest(job, + op->sym->auth.digest.data, + sess->auth.req_digest_len, + &op->status); + } else + generate_digest(job, op, sess); break; default: op->status = RTE_CRYPTO_OP_STATUS_ERROR; diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c index 5788e37d1..56d409b4b 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c @@ -360,6 +360,31 @@ static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = { }, } }, } }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 8, + .max = 16, + .increment = 4 + }, + .iv_size = { + .min = 12, + .max = 12, + .increment = 0 + } + }, } + }, } + }, RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() }; diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops_compat.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops_compat.c index f3eff2685..1ca6baafa 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops_compat.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops_compat.c @@ -416,6 +416,31 @@ static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = { }, } }, } }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 8, + .max = 16, + .increment = 4 + }, + .iv_size = { + .min = 12, + .max = 12, + .increment = 0 + } + }, } + }, } + }, RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() }; -- 2.13.6