X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Faesni_gcm%2Faesni_gcm_pmd.c;h=ebdf7c35a8e487fcd43cdad7da313981f332f646;hb=815037b92b3437754183fb256a967a7e82d3820a;hp=80360dd9c29bd20bff0bb0e84d5ebaf3a9baeb9e;hpb=a106fcce2cfed0fdee7922594e3199d28dfcce59;p=dpdk.git diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c index 80360dd9c2..ebdf7c35a8 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c @@ -23,7 +23,6 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, { const struct rte_crypto_sym_xform *auth_xform; const struct rte_crypto_sym_xform *aead_xform; - uint16_t digest_length; uint8_t key_length; uint8_t *key; @@ -31,8 +30,8 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { auth_xform = xform; if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_AES_GMAC) { - GCM_LOG_ERR("Only AES GMAC is supported as an " - "authentication only algorithm"); + AESNI_GCM_LOG(ERR, "Only AES GMAC is supported as an " + "authentication only algorithm"); return -ENOTSUP; } /* Set IV parameters */ @@ -47,14 +46,14 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, key_length = auth_xform->auth.key.length; key = auth_xform->auth.key.data; - digest_length = auth_xform->auth.digest_length; + sess->req_digest_length = auth_xform->auth.digest_length; /* AES-GCM */ } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { aead_xform = xform; if (aead_xform->aead.algo != RTE_CRYPTO_AEAD_AES_GCM) { - GCM_LOG_ERR("The only combined operation " + AESNI_GCM_LOG(ERR, "The only combined operation " "supported is AES GCM"); return -ENOTSUP; } @@ -73,9 +72,9 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, key = aead_xform->aead.key.data; sess->aad_length = aead_xform->aead.aad_length; - digest_length = aead_xform->aead.digest_length; + sess->req_digest_length = aead_xform->aead.digest_length; } else { - GCM_LOG_ERR("Wrong xform type, has to be AEAD or authentication"); + AESNI_GCM_LOG(ERR, "Wrong xform type, has to be AEAD or authentication"); return -ENOTSUP; } @@ -83,7 +82,7 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, /* IV check */ if (sess->iv.length != 16 && sess->iv.length != 12 && sess->iv.length != 0) { - GCM_LOG_ERR("Wrong IV length"); + AESNI_GCM_LOG(ERR, "Wrong IV length"); return -EINVAL; } @@ -99,20 +98,35 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, sess->key = AESNI_GCM_KEY_256; break; default: - GCM_LOG_ERR("Invalid key length"); + AESNI_GCM_LOG(ERR, "Invalid key length"); return -EINVAL; } gcm_ops[sess->key].precomp(key, &sess->gdata_key); /* Digest check */ - if (digest_length != 16 && - digest_length != 12 && - digest_length != 8) { - GCM_LOG_ERR("digest"); + if (sess->req_digest_length > 16) { + AESNI_GCM_LOG(ERR, "Invalid digest length"); return -EINVAL; } - sess->digest_length = digest_length; + /* + * Multi-buffer lib supports digest sizes from 4 to 16 bytes + * in version 0.50 and sizes of 8, 12 and 16 bytes, + * in version 0.49. + * If size requested is different, generate the full digest + * (16 bytes) in a temporary location and then memcpy + * the requested number of bytes. + */ +#if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0) + if (sess->req_digest_length < 4) +#else + if (sess->req_digest_length != 16 && + sess->req_digest_length != 12 && + sess->req_digest_length != 8) +#endif + sess->gen_digest_length = 16; + else + sess->gen_digest_length = sess->req_digest_length; return 0; } @@ -127,7 +141,7 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op) if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { if (likely(sym_op->session != NULL)) sess = (struct aesni_gcm_session *) - get_session_private_data( + get_sym_session_private_data( sym_op->session, cryptodev_driver_id); } else { @@ -149,8 +163,8 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op) sess = NULL; } sym_op->session = (struct rte_cryptodev_sym_session *)_sess; - set_session_private_data(sym_op->session, cryptodev_driver_id, - _sess_private_data); + set_sym_session_private_data(sym_op->session, + cryptodev_driver_id, _sess_private_data); } if (unlikely(sess == NULL)) @@ -180,6 +194,7 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, struct rte_mbuf *m_src = sym_op->m_src; uint32_t offset, data_offset, data_length; uint32_t part_len, total_len, data_len; + uint8_t *tag; if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION || session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) { @@ -225,17 +240,8 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, session->iv.offset); - /* - * GCM working in 12B IV mode => 16B pre-counter block we need - * to set BE LSB to 1, driver expects that 16B is allocated - */ - if (session->iv.length == 12) { - uint32_t *iv_padd = (uint32_t *)&(iv_ptr[12]); - *iv_padd = rte_bswap32(1); - } if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) { - qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, @@ -263,13 +269,16 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, total_len -= part_len; } + if (session->req_digest_length != session->gen_digest_length) + tag = qp->temp_digest; + else + tag = sym_op->aead.digest.data; + qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - sym_op->aead.digest.data, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else if (session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) { - uint8_t *auth_tag = qp->temp_digest; - qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, @@ -298,33 +307,41 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, total_len -= part_len; } + tag = qp->temp_digest; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - auth_tag, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else if (session->op == AESNI_GMAC_OP_GENERATE) { qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, src, (uint64_t)data_length); + if (session->req_digest_length != session->gen_digest_length) + tag = qp->temp_digest; + else + tag = sym_op->auth.digest.data; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - sym_op->auth.digest.data, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else { /* AESNI_GMAC_OP_VERIFY */ - uint8_t *auth_tag = qp->temp_digest; - qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, src, (uint64_t)data_length); + /* + * Generate always 16 bytes and later compare only + * the bytes passed. + */ + tag = qp->temp_digest; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - auth_tag, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } return 0; @@ -361,13 +378,22 @@ post_process_gcm_crypto_op(struct aesni_gcm_qp *qp, #ifdef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG rte_hexdump(stdout, "auth tag (orig):", - digest, session->digest_length); + digest, session->req_digest_length); rte_hexdump(stdout, "auth tag (calc):", - tag, session->digest_length); + tag, session->req_digest_length); #endif - if (memcmp(tag, digest, session->digest_length) != 0) + if (memcmp(tag, digest, session->req_digest_length) != 0) op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } else { + if (session->req_digest_length != session->gen_digest_length) { + if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) + memcpy(op->sym->aead.digest.data, qp->temp_digest, + session->req_digest_length); + else + memcpy(op->sym->auth.digest.data, qp->temp_digest, + session->req_digest_length); + } } } @@ -464,13 +490,13 @@ aesni_gcm_create(const char *name, /* Check CPU for support for AES instruction set */ if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) { - GCM_LOG_ERR("AES instructions not supported by CPU"); + AESNI_GCM_LOG(ERR, "AES instructions not supported by CPU"); return -EFAULT; } - dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params); if (dev == NULL) { - GCM_LOG_ERR("driver %s: create failed", init_params->name); + AESNI_GCM_LOG(ERR, "driver %s: create failed", + init_params->name); return -ENODEV; } @@ -492,7 +518,8 @@ aesni_gcm_create(const char *name, dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | RTE_CRYPTODEV_FF_CPU_AESNI | - RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER; + RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT | + RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT; switch (vector_mode) { case RTE_AESNI_GCM_SSE: @@ -513,7 +540,13 @@ aesni_gcm_create(const char *name, internals->vector_mode = vector_mode; internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs; - internals->max_nb_sessions = init_params->max_nb_sessions; + +#if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0) + AESNI_GCM_LOG(INFO, "IPSec Multi-buffer library version used: %s\n", + imb_get_version_str()); +#else + AESNI_GCM_LOG(INFO, "IPSec Multi-buffer library version used: 0.49.0\n"); +#endif return 0; } @@ -525,8 +558,7 @@ aesni_gcm_probe(struct rte_vdev_device *vdev) "", sizeof(struct aesni_gcm_private), rte_socket_id(), - RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS, - RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS + RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS }; const char *name; const char *input_args; @@ -568,7 +600,12 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_GCM_PMD, aesni_gcm_pmd_drv); RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_GCM_PMD, cryptodev_aesni_gcm_pmd); RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_GCM_PMD, "max_nb_queue_pairs= " - "max_nb_sessions= " "socket_id="); RTE_PMD_REGISTER_CRYPTO_DRIVER(aesni_gcm_crypto_drv, aesni_gcm_pmd_drv.driver, cryptodev_driver_id); + + +RTE_INIT(aesni_gcm_init_log) +{ + aesni_gcm_logtype_driver = rte_log_register("pmd.crypto.aesni_gcm"); +}