1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2017 Intel Corporation
5 #define OPENSSL_API_COMPAT 0x10100000L
9 #include <rte_common.h>
10 #include <rte_malloc.h>
11 #include <cryptodev_pmd.h>
13 #include "openssl_pmd_private.h"
17 static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
19 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
21 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
23 .algo = RTE_CRYPTO_AUTH_MD5_HMAC,
40 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
42 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
44 .algo = RTE_CRYPTO_AUTH_MD5,
61 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
63 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
65 .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
82 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
84 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
86 .algo = RTE_CRYPTO_AUTH_SHA1,
103 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
105 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
107 .algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
124 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
126 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
128 .algo = RTE_CRYPTO_AUTH_SHA224,
145 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
147 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
149 .algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
166 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
168 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
170 .algo = RTE_CRYPTO_AUTH_SHA256,
187 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
189 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
191 .algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
208 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
210 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
212 .algo = RTE_CRYPTO_AUTH_SHA384,
229 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
231 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
233 .algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
250 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
252 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
254 .algo = RTE_CRYPTO_AUTH_SHA512,
271 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
273 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
275 .algo = RTE_CRYPTO_CIPHER_AES_CBC,
291 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
293 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
295 .algo = RTE_CRYPTO_CIPHER_AES_CTR,
311 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
313 .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
315 .algo = RTE_CRYPTO_AEAD_AES_GCM,
341 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
343 .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
345 .algo = RTE_CRYPTO_AEAD_AES_CCM,
370 { /* AES GMAC (AUTH) */
371 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
373 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
375 .algo = RTE_CRYPTO_AUTH_AES_GMAC,
396 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
398 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
400 .algo = RTE_CRYPTO_CIPHER_3DES_CBC,
416 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
418 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
420 .algo = RTE_CRYPTO_CIPHER_3DES_CTR,
436 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
438 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
440 .algo = RTE_CRYPTO_CIPHER_DES_CBC,
455 { /* DES DOCSIS BPI */
456 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
458 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
460 .algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI,
476 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
479 .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
480 .op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
481 (1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
482 (1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
483 (1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
486 /* min length is based on openssl rsa keygen */
488 /* value 0 symbolizes no limit on max length */
497 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
500 .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
504 /* value 0 symbolizes no limit on min length */
506 /* value 0 symbolizes no limit on max length */
515 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
518 .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
522 /* value 0 symbolizes no limit on min length */
524 /* value 0 symbolizes no limit on max length */
533 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
536 .xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
538 ((1<<RTE_CRYPTO_ASYM_KE_PRIV_KEY_GENERATE) |
539 (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE |
541 RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
544 /* value 0 symbolizes no limit on min length */
546 /* value 0 symbolizes no limit on max length */
555 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
558 .xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
560 ((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
561 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
564 /* value 0 symbolizes no limit on min length */
566 /* value 0 symbolizes no limit on max length */
575 RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
579 /** Configure device */
581 openssl_pmd_config(__rte_unused struct rte_cryptodev *dev,
582 __rte_unused struct rte_cryptodev_config *config)
589 openssl_pmd_start(__rte_unused struct rte_cryptodev *dev)
596 openssl_pmd_stop(__rte_unused struct rte_cryptodev *dev)
602 openssl_pmd_close(__rte_unused struct rte_cryptodev *dev)
608 /** Get device statistics */
610 openssl_pmd_stats_get(struct rte_cryptodev *dev,
611 struct rte_cryptodev_stats *stats)
615 for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
616 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
618 stats->enqueued_count += qp->stats.enqueued_count;
619 stats->dequeued_count += qp->stats.dequeued_count;
621 stats->enqueue_err_count += qp->stats.enqueue_err_count;
622 stats->dequeue_err_count += qp->stats.dequeue_err_count;
626 /** Reset device statistics */
628 openssl_pmd_stats_reset(struct rte_cryptodev *dev)
632 for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
633 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
635 memset(&qp->stats, 0, sizeof(qp->stats));
640 /** Get device info */
642 openssl_pmd_info_get(struct rte_cryptodev *dev,
643 struct rte_cryptodev_info *dev_info)
645 struct openssl_private *internals = dev->data->dev_private;
647 if (dev_info != NULL) {
648 dev_info->driver_id = dev->driver_id;
649 dev_info->feature_flags = dev->feature_flags;
650 dev_info->capabilities = openssl_pmd_capabilities;
651 dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
652 /* No limit of number of sessions */
653 dev_info->sym.max_nb_sessions = 0;
657 /** Release queue pair */
659 openssl_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
661 if (dev->data->queue_pairs[qp_id] != NULL) {
662 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
664 rte_ring_free(qp->processed_ops);
666 rte_free(dev->data->queue_pairs[qp_id]);
667 dev->data->queue_pairs[qp_id] = NULL;
672 /** set a unique name for the queue pair based on it's name, dev_id and qp_id */
674 openssl_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
675 struct openssl_qp *qp)
677 unsigned int n = snprintf(qp->name, sizeof(qp->name),
678 "openssl_pmd_%u_qp_%u",
679 dev->data->dev_id, qp->id);
681 if (n >= sizeof(qp->name))
688 /** Create a ring to place processed operations on */
689 static struct rte_ring *
690 openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
691 unsigned int ring_size, int socket_id)
695 r = rte_ring_lookup(qp->name);
697 if (rte_ring_get_size(r) >= ring_size) {
699 "Reusing existing ring %s for processed ops",
705 "Unable to reuse existing ring %s for processed ops",
710 return rte_ring_create(qp->name, ring_size, socket_id,
711 RING_F_SP_ENQ | RING_F_SC_DEQ);
715 /** Setup a queue pair */
717 openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
718 const struct rte_cryptodev_qp_conf *qp_conf,
721 struct openssl_qp *qp = NULL;
723 /* Free memory prior to re-allocation if needed. */
724 if (dev->data->queue_pairs[qp_id] != NULL)
725 openssl_pmd_qp_release(dev, qp_id);
727 /* Allocate the queue pair data structure. */
728 qp = rte_zmalloc_socket("OPENSSL PMD Queue Pair", sizeof(*qp),
729 RTE_CACHE_LINE_SIZE, socket_id);
734 dev->data->queue_pairs[qp_id] = qp;
736 if (openssl_pmd_qp_set_unique_name(dev, qp))
737 goto qp_setup_cleanup;
739 qp->processed_ops = openssl_pmd_qp_create_processed_ops_ring(qp,
740 qp_conf->nb_descriptors, socket_id);
741 if (qp->processed_ops == NULL)
742 goto qp_setup_cleanup;
744 qp->sess_mp = qp_conf->mp_session;
745 qp->sess_mp_priv = qp_conf->mp_session_private;
747 memset(&qp->stats, 0, sizeof(qp->stats));
757 /** Returns the size of the symmetric session structure */
759 openssl_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
761 return sizeof(struct openssl_session);
764 /** Returns the size of the asymmetric session structure */
766 openssl_pmd_asym_session_get_size(struct rte_cryptodev *dev __rte_unused)
768 return sizeof(struct openssl_asym_session);
771 /** Configure the session from a crypto xform chain */
773 openssl_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
774 struct rte_crypto_sym_xform *xform,
775 struct rte_cryptodev_sym_session *sess,
776 struct rte_mempool *mempool)
778 void *sess_private_data;
781 if (unlikely(sess == NULL)) {
782 OPENSSL_LOG(ERR, "invalid session struct");
786 if (rte_mempool_get(mempool, &sess_private_data)) {
788 "Couldn't get object from session mempool");
792 ret = openssl_set_session_parameters(sess_private_data, xform);
794 OPENSSL_LOG(ERR, "failed configure session parameters");
796 /* Return session to mempool */
797 rte_mempool_put(mempool, sess_private_data);
801 set_sym_session_private_data(sess, dev->driver_id,
807 static int openssl_set_asym_session_parameters(
808 struct openssl_asym_session *asym_session,
809 struct rte_crypto_asym_xform *xform)
813 if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) &&
814 (xform->next != NULL)) {
815 OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
816 rte_crypto_asym_xform_strings[xform->xform_type]);
820 switch (xform->xform_type) {
821 case RTE_CRYPTO_ASYM_XFORM_RSA:
826 BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL;
827 BIGNUM *iqmp = NULL, *dmq1 = NULL;
829 /* copy xfrm data into rsa struct */
830 n = BN_bin2bn((const unsigned char *)xform->rsa.n.data,
831 xform->rsa.n.length, n);
832 e = BN_bin2bn((const unsigned char *)xform->rsa.e.data,
833 xform->rsa.e.length, e);
838 RSA *rsa = RSA_new();
842 if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_EXP) {
844 (const unsigned char *)xform->rsa.d.data,
852 p = BN_bin2bn((const unsigned char *)
853 xform->rsa.qt.p.data,
854 xform->rsa.qt.p.length,
856 q = BN_bin2bn((const unsigned char *)
857 xform->rsa.qt.q.data,
858 xform->rsa.qt.q.length,
860 dmp1 = BN_bin2bn((const unsigned char *)
861 xform->rsa.qt.dP.data,
862 xform->rsa.qt.dP.length,
864 dmq1 = BN_bin2bn((const unsigned char *)
865 xform->rsa.qt.dQ.data,
866 xform->rsa.qt.dQ.length,
868 iqmp = BN_bin2bn((const unsigned char *)
869 xform->rsa.qt.qInv.data,
870 xform->rsa.qt.qInv.length,
873 if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
877 ret = set_rsa_params(rsa, p, q);
880 "failed to set rsa params\n");
884 ret = set_rsa_crt_params(rsa, dmp1, dmq1, iqmp);
887 "failed to set crt params\n");
890 * set already populated params to NULL
891 * as its freed by call to RSA_free
898 ret = set_rsa_keys(rsa, n, e, d);
900 OPENSSL_LOG(ERR, "Failed to load rsa keys\n");
904 asym_session->u.r.rsa = rsa;
905 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA;
919 case RTE_CRYPTO_ASYM_XFORM_MODEX:
921 struct rte_crypto_modex_xform *xfrm = &(xform->modex);
923 BN_CTX *ctx = BN_CTX_new();
926 " failed to allocate resources\n");
930 BIGNUM *mod = BN_CTX_get(ctx);
931 BIGNUM *exp = BN_CTX_get(ctx);
932 if (mod == NULL || exp == NULL) {
938 mod = BN_bin2bn((const unsigned char *)
940 xfrm->modulus.length, mod);
941 exp = BN_bin2bn((const unsigned char *)
943 xfrm->exponent.length, exp);
944 asym_session->u.e.ctx = ctx;
945 asym_session->u.e.mod = mod;
946 asym_session->u.e.exp = exp;
947 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODEX;
950 case RTE_CRYPTO_ASYM_XFORM_MODINV:
952 struct rte_crypto_modinv_xform *xfrm = &(xform->modinv);
954 BN_CTX *ctx = BN_CTX_new();
957 " failed to allocate resources\n");
961 BIGNUM *mod = BN_CTX_get(ctx);
968 mod = BN_bin2bn((const unsigned char *)
970 xfrm->modulus.length,
972 asym_session->u.m.ctx = ctx;
973 asym_session->u.m.modulus = mod;
974 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV;
977 case RTE_CRYPTO_ASYM_XFORM_DH:
982 p = BN_bin2bn((const unsigned char *)
986 g = BN_bin2bn((const unsigned char *)
996 "failed to allocate resources\n");
999 ret = set_dh_params(dh, p, g);
1004 asym_session->u.dh.dh_key = dh;
1005 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DH;
1009 OPENSSL_LOG(ERR, " failed to set dh params\n");
1014 case RTE_CRYPTO_ASYM_XFORM_DSA:
1016 BIGNUM *p = NULL, *g = NULL;
1017 BIGNUM *q = NULL, *priv_key = NULL;
1018 BIGNUM *pub_key = BN_new();
1021 p = BN_bin2bn((const unsigned char *)
1023 xform->dsa.p.length,
1026 g = BN_bin2bn((const unsigned char *)
1028 xform->dsa.g.length,
1031 q = BN_bin2bn((const unsigned char *)
1033 xform->dsa.q.length,
1038 priv_key = BN_bin2bn((const unsigned char *)
1040 xform->dsa.x.length,
1042 if (priv_key == NULL)
1045 DSA *dsa = DSA_new();
1048 " failed to allocate resources\n");
1052 ret = set_dsa_params(dsa, p, q, g);
1055 OPENSSL_LOG(ERR, "Failed to dsa params\n");
1060 * openssl 1.1.0 mandate that public key can't be
1061 * NULL in very first call. so set a dummy pub key.
1062 * to keep consistency, lets follow same approach for
1065 /* just set dummy public for very 1st call */
1066 ret = set_dsa_keys(dsa, pub_key, priv_key);
1069 OPENSSL_LOG(ERR, "Failed to set keys\n");
1072 asym_session->u.s.dsa = dsa;
1073 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
1091 /** Configure the session from a crypto xform chain */
1093 openssl_pmd_asym_session_configure(struct rte_cryptodev *dev __rte_unused,
1094 struct rte_crypto_asym_xform *xform,
1095 struct rte_cryptodev_asym_session *sess)
1097 void *asym_sess_private_data;
1100 if (unlikely(sess == NULL)) {
1101 OPENSSL_LOG(ERR, "invalid asymmetric session struct");
1105 asym_sess_private_data = sess->sess_private_data;
1106 ret = openssl_set_asym_session_parameters(asym_sess_private_data,
1109 OPENSSL_LOG(ERR, "failed configure session parameters");
1116 /** Clear the memory of session so it doesn't leave key material behind */
1118 openssl_pmd_sym_session_clear(struct rte_cryptodev *dev,
1119 struct rte_cryptodev_sym_session *sess)
1121 uint8_t index = dev->driver_id;
1122 void *sess_priv = get_sym_session_private_data(sess, index);
1124 /* Zero out the whole structure */
1126 openssl_reset_session(sess_priv);
1127 memset(sess_priv, 0, sizeof(struct openssl_session));
1128 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
1129 set_sym_session_private_data(sess, index, NULL);
1130 rte_mempool_put(sess_mp, sess_priv);
1134 static void openssl_reset_asym_session(struct openssl_asym_session *sess)
1136 switch (sess->xfrm_type) {
1137 case RTE_CRYPTO_ASYM_XFORM_RSA:
1139 RSA_free(sess->u.r.rsa);
1141 case RTE_CRYPTO_ASYM_XFORM_MODEX:
1142 if (sess->u.e.ctx) {
1143 BN_CTX_end(sess->u.e.ctx);
1144 BN_CTX_free(sess->u.e.ctx);
1147 case RTE_CRYPTO_ASYM_XFORM_MODINV:
1148 if (sess->u.m.ctx) {
1149 BN_CTX_end(sess->u.m.ctx);
1150 BN_CTX_free(sess->u.m.ctx);
1153 case RTE_CRYPTO_ASYM_XFORM_DH:
1154 if (sess->u.dh.dh_key)
1155 DH_free(sess->u.dh.dh_key);
1157 case RTE_CRYPTO_ASYM_XFORM_DSA:
1159 DSA_free(sess->u.s.dsa);
1166 /** Clear the memory of asymmetric session
1167 * so it doesn't leave key material behind
1170 openssl_pmd_asym_session_clear(struct rte_cryptodev *dev __rte_unused,
1171 struct rte_cryptodev_asym_session *sess)
1173 void *sess_priv = sess->sess_private_data;
1175 /* Zero out the whole structure */
1177 openssl_reset_asym_session(sess_priv);
1178 memset(sess_priv, 0, sizeof(struct openssl_asym_session));
1182 struct rte_cryptodev_ops openssl_pmd_ops = {
1183 .dev_configure = openssl_pmd_config,
1184 .dev_start = openssl_pmd_start,
1185 .dev_stop = openssl_pmd_stop,
1186 .dev_close = openssl_pmd_close,
1188 .stats_get = openssl_pmd_stats_get,
1189 .stats_reset = openssl_pmd_stats_reset,
1191 .dev_infos_get = openssl_pmd_info_get,
1193 .queue_pair_setup = openssl_pmd_qp_setup,
1194 .queue_pair_release = openssl_pmd_qp_release,
1196 .sym_session_get_size = openssl_pmd_sym_session_get_size,
1197 .asym_session_get_size = openssl_pmd_asym_session_get_size,
1198 .sym_session_configure = openssl_pmd_sym_session_configure,
1199 .asym_session_configure = openssl_pmd_asym_session_configure,
1200 .sym_session_clear = openssl_pmd_sym_session_clear,
1201 .asym_session_clear = openssl_pmd_asym_session_clear
1204 struct rte_cryptodev_ops *rte_openssl_pmd_ops = &openssl_pmd_ops;