xref: /dpdk/drivers/crypto/bcmfs/bcmfs_sym_session.c (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
14ed19f0dSVikas Gupta /* SPDX-License-Identifier: BSD-3-Clause
24ed19f0dSVikas Gupta  * Copyright(c) 2020 Broadcom
34ed19f0dSVikas Gupta  * All rights reserved.
44ed19f0dSVikas Gupta  */
54ed19f0dSVikas Gupta 
64ed19f0dSVikas Gupta #include <rte_crypto.h>
74ed19f0dSVikas Gupta #include <rte_crypto_sym.h>
84ed19f0dSVikas Gupta #include <rte_log.h>
94ed19f0dSVikas Gupta 
104ed19f0dSVikas Gupta #include "bcmfs_logs.h"
114ed19f0dSVikas Gupta #include "bcmfs_sym_defs.h"
124ed19f0dSVikas Gupta #include "bcmfs_sym_pmd.h"
134ed19f0dSVikas Gupta #include "bcmfs_sym_session.h"
144ed19f0dSVikas Gupta 
154ed19f0dSVikas Gupta /** Configure the session from a crypto xform chain */
164ed19f0dSVikas Gupta static enum bcmfs_sym_chain_order
174ed19f0dSVikas Gupta crypto_get_chain_order(const struct rte_crypto_sym_xform *xform)
184ed19f0dSVikas Gupta {
194ed19f0dSVikas Gupta 	enum bcmfs_sym_chain_order res = BCMFS_SYM_CHAIN_NOT_SUPPORTED;
204ed19f0dSVikas Gupta 
214ed19f0dSVikas Gupta 	if (xform != NULL) {
224ed19f0dSVikas Gupta 		if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
234ed19f0dSVikas Gupta 			res = BCMFS_SYM_CHAIN_AEAD;
244ed19f0dSVikas Gupta 
254ed19f0dSVikas Gupta 		if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
264ed19f0dSVikas Gupta 			if (xform->next == NULL)
274ed19f0dSVikas Gupta 				res =  BCMFS_SYM_CHAIN_ONLY_AUTH;
284ed19f0dSVikas Gupta 			else if (xform->next->type ==
294ed19f0dSVikas Gupta 					RTE_CRYPTO_SYM_XFORM_CIPHER)
304ed19f0dSVikas Gupta 				res = BCMFS_SYM_CHAIN_AUTH_CIPHER;
314ed19f0dSVikas Gupta 		}
324ed19f0dSVikas Gupta 		if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
334ed19f0dSVikas Gupta 			if (xform->next == NULL)
344ed19f0dSVikas Gupta 				res =  BCMFS_SYM_CHAIN_ONLY_CIPHER;
354ed19f0dSVikas Gupta 			else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
364ed19f0dSVikas Gupta 				res =  BCMFS_SYM_CHAIN_CIPHER_AUTH;
374ed19f0dSVikas Gupta 		}
384ed19f0dSVikas Gupta 	}
394ed19f0dSVikas Gupta 
404ed19f0dSVikas Gupta 	return res;
414ed19f0dSVikas Gupta }
424ed19f0dSVikas Gupta 
434ed19f0dSVikas Gupta /* Get session cipher key from input cipher key */
444ed19f0dSVikas Gupta static void
454ed19f0dSVikas Gupta get_key(const uint8_t *input_key, int keylen, uint8_t *session_key)
464ed19f0dSVikas Gupta {
474ed19f0dSVikas Gupta 	memcpy(session_key, input_key, keylen);
484ed19f0dSVikas Gupta }
494ed19f0dSVikas Gupta 
504ed19f0dSVikas Gupta /* Set session cipher parameters */
514ed19f0dSVikas Gupta static int
524ed19f0dSVikas Gupta crypto_set_session_cipher_parameters(struct bcmfs_sym_session *sess,
534ed19f0dSVikas Gupta 			 const struct rte_crypto_cipher_xform *cipher_xform)
544ed19f0dSVikas Gupta {
554ed19f0dSVikas Gupta 	if (cipher_xform->key.length > BCMFS_MAX_KEY_SIZE) {
564ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "key length not supported");
574ed19f0dSVikas Gupta 		return -EINVAL;
584ed19f0dSVikas Gupta 	}
594ed19f0dSVikas Gupta 
604ed19f0dSVikas Gupta 	sess->cipher.key.length = cipher_xform->key.length;
614ed19f0dSVikas Gupta 	sess->cipher.iv.offset = cipher_xform->iv.offset;
624ed19f0dSVikas Gupta 	sess->cipher.iv.length = cipher_xform->iv.length;
634ed19f0dSVikas Gupta 	sess->cipher.op = cipher_xform->op;
644ed19f0dSVikas Gupta 	sess->cipher.algo = cipher_xform->algo;
654ed19f0dSVikas Gupta 
664ed19f0dSVikas Gupta 	get_key(cipher_xform->key.data,
674ed19f0dSVikas Gupta 		sess->cipher.key.length,
684ed19f0dSVikas Gupta 		sess->cipher.key.data);
694ed19f0dSVikas Gupta 
704ed19f0dSVikas Gupta 	return 0;
714ed19f0dSVikas Gupta }
724ed19f0dSVikas Gupta 
734ed19f0dSVikas Gupta /* Set session auth parameters */
744ed19f0dSVikas Gupta static int
754ed19f0dSVikas Gupta crypto_set_session_auth_parameters(struct bcmfs_sym_session *sess,
764ed19f0dSVikas Gupta 			const struct rte_crypto_auth_xform *auth_xform)
774ed19f0dSVikas Gupta {
784ed19f0dSVikas Gupta 	if (auth_xform->key.length > BCMFS_MAX_KEY_SIZE) {
794ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "key length not supported");
804ed19f0dSVikas Gupta 		return -EINVAL;
814ed19f0dSVikas Gupta 	}
824ed19f0dSVikas Gupta 
834ed19f0dSVikas Gupta 	sess->auth.op = auth_xform->op;
844ed19f0dSVikas Gupta 	sess->auth.key.length = auth_xform->key.length;
854ed19f0dSVikas Gupta 	sess->auth.digest_length = auth_xform->digest_length;
864ed19f0dSVikas Gupta 	sess->auth.iv.length = auth_xform->iv.length;
874ed19f0dSVikas Gupta 	sess->auth.iv.offset = auth_xform->iv.offset;
884ed19f0dSVikas Gupta 	sess->auth.algo = auth_xform->algo;
894ed19f0dSVikas Gupta 
904ed19f0dSVikas Gupta 	get_key(auth_xform->key.data,
914ed19f0dSVikas Gupta 		auth_xform->key.length,
924ed19f0dSVikas Gupta 		sess->auth.key.data);
934ed19f0dSVikas Gupta 
944ed19f0dSVikas Gupta 	return 0;
954ed19f0dSVikas Gupta }
964ed19f0dSVikas Gupta 
974ed19f0dSVikas Gupta /* Set session aead parameters */
984ed19f0dSVikas Gupta static int
994ed19f0dSVikas Gupta crypto_set_session_aead_parameters(struct bcmfs_sym_session *sess,
1004ed19f0dSVikas Gupta 			const struct rte_crypto_sym_xform *aead_xform)
1014ed19f0dSVikas Gupta {
1024ed19f0dSVikas Gupta 	if (aead_xform->aead.key.length > BCMFS_MAX_KEY_SIZE) {
1034ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "key length not supported");
1044ed19f0dSVikas Gupta 		return -EINVAL;
1054ed19f0dSVikas Gupta 	}
1064ed19f0dSVikas Gupta 
1074ed19f0dSVikas Gupta 	sess->aead.iv.offset = aead_xform->aead.iv.offset;
1084ed19f0dSVikas Gupta 	sess->aead.iv.length = aead_xform->aead.iv.length;
1094ed19f0dSVikas Gupta 	sess->aead.aad_length = aead_xform->aead.aad_length;
1104ed19f0dSVikas Gupta 	sess->aead.key.length = aead_xform->aead.key.length;
1114ed19f0dSVikas Gupta 	sess->aead.digest_length = aead_xform->aead.digest_length;
1124ed19f0dSVikas Gupta 	sess->aead.op = aead_xform->aead.op;
1134ed19f0dSVikas Gupta 	sess->aead.algo = aead_xform->aead.algo;
1144ed19f0dSVikas Gupta 
1154ed19f0dSVikas Gupta 	get_key(aead_xform->aead.key.data,
1164ed19f0dSVikas Gupta 		aead_xform->aead.key.length,
1174ed19f0dSVikas Gupta 		sess->aead.key.data);
1184ed19f0dSVikas Gupta 
1194ed19f0dSVikas Gupta 	return 0;
1204ed19f0dSVikas Gupta }
1214ed19f0dSVikas Gupta 
1224ed19f0dSVikas Gupta static struct rte_crypto_auth_xform *
1234ed19f0dSVikas Gupta crypto_get_auth_xform(struct rte_crypto_sym_xform *xform)
1244ed19f0dSVikas Gupta {
1254ed19f0dSVikas Gupta 	do {
1264ed19f0dSVikas Gupta 		if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
1274ed19f0dSVikas Gupta 			return &xform->auth;
1284ed19f0dSVikas Gupta 
1294ed19f0dSVikas Gupta 		xform = xform->next;
1304ed19f0dSVikas Gupta 	} while (xform);
1314ed19f0dSVikas Gupta 
1324ed19f0dSVikas Gupta 	return NULL;
1334ed19f0dSVikas Gupta }
1344ed19f0dSVikas Gupta 
1354ed19f0dSVikas Gupta static struct rte_crypto_cipher_xform *
1364ed19f0dSVikas Gupta crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform)
1374ed19f0dSVikas Gupta {
1384ed19f0dSVikas Gupta 	do {
1394ed19f0dSVikas Gupta 		if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
1404ed19f0dSVikas Gupta 			return &xform->cipher;
1414ed19f0dSVikas Gupta 
1424ed19f0dSVikas Gupta 		xform = xform->next;
1434ed19f0dSVikas Gupta 	} while (xform);
1444ed19f0dSVikas Gupta 
1454ed19f0dSVikas Gupta 	return NULL;
1464ed19f0dSVikas Gupta }
1474ed19f0dSVikas Gupta 
1484ed19f0dSVikas Gupta /** Parse crypto xform chain and set private session parameters */
1494ed19f0dSVikas Gupta static int
1504ed19f0dSVikas Gupta crypto_set_session_parameters(struct bcmfs_sym_session *sess,
1514ed19f0dSVikas Gupta 			      struct rte_crypto_sym_xform *xform)
1524ed19f0dSVikas Gupta {
1534ed19f0dSVikas Gupta 	int rc = 0;
1544ed19f0dSVikas Gupta 	struct rte_crypto_cipher_xform *cipher_xform =
1554ed19f0dSVikas Gupta 			crypto_get_cipher_xform(xform);
1564ed19f0dSVikas Gupta 	struct rte_crypto_auth_xform *auth_xform =
1574ed19f0dSVikas Gupta 			crypto_get_auth_xform(xform);
1584ed19f0dSVikas Gupta 
1594ed19f0dSVikas Gupta 	sess->chain_order = crypto_get_chain_order(xform);
1604ed19f0dSVikas Gupta 
1614ed19f0dSVikas Gupta 	switch (sess->chain_order) {
1624ed19f0dSVikas Gupta 	case BCMFS_SYM_CHAIN_ONLY_CIPHER:
1634ed19f0dSVikas Gupta 		if (crypto_set_session_cipher_parameters(sess, cipher_xform))
1644ed19f0dSVikas Gupta 			rc = -EINVAL;
1654ed19f0dSVikas Gupta 		break;
1664ed19f0dSVikas Gupta 	case BCMFS_SYM_CHAIN_ONLY_AUTH:
1674ed19f0dSVikas Gupta 		if (crypto_set_session_auth_parameters(sess, auth_xform))
1684ed19f0dSVikas Gupta 			rc = -EINVAL;
1694ed19f0dSVikas Gupta 		break;
1704ed19f0dSVikas Gupta 	case BCMFS_SYM_CHAIN_AUTH_CIPHER:
1714ed19f0dSVikas Gupta 		sess->cipher_first = false;
1724ed19f0dSVikas Gupta 		if (crypto_set_session_auth_parameters(sess, auth_xform)) {
1734ed19f0dSVikas Gupta 			rc = -EINVAL;
1744ed19f0dSVikas Gupta 			goto error;
1754ed19f0dSVikas Gupta 		}
1764ed19f0dSVikas Gupta 
1774ed19f0dSVikas Gupta 		if (crypto_set_session_cipher_parameters(sess, cipher_xform))
1784ed19f0dSVikas Gupta 			rc = -EINVAL;
1794ed19f0dSVikas Gupta 		break;
1804ed19f0dSVikas Gupta 	case BCMFS_SYM_CHAIN_CIPHER_AUTH:
1814ed19f0dSVikas Gupta 		sess->cipher_first = true;
1824ed19f0dSVikas Gupta 		if (crypto_set_session_auth_parameters(sess, auth_xform)) {
1834ed19f0dSVikas Gupta 			rc = -EINVAL;
1844ed19f0dSVikas Gupta 			goto error;
1854ed19f0dSVikas Gupta 		}
1864ed19f0dSVikas Gupta 
1874ed19f0dSVikas Gupta 		if (crypto_set_session_cipher_parameters(sess, cipher_xform))
1884ed19f0dSVikas Gupta 			rc = -EINVAL;
1894ed19f0dSVikas Gupta 		break;
1904ed19f0dSVikas Gupta 	case BCMFS_SYM_CHAIN_AEAD:
1914ed19f0dSVikas Gupta 		if (crypto_set_session_aead_parameters(sess, xform))
1924ed19f0dSVikas Gupta 			rc = -EINVAL;
1934ed19f0dSVikas Gupta 		break;
1944ed19f0dSVikas Gupta 	default:
195*f665790aSDavid Marchand 		BCMFS_DP_LOG(ERR, "Invalid chain order");
1964ed19f0dSVikas Gupta 		rc = -EINVAL;
1974ed19f0dSVikas Gupta 		break;
1984ed19f0dSVikas Gupta 	}
1994ed19f0dSVikas Gupta 
2004ed19f0dSVikas Gupta error:
2014ed19f0dSVikas Gupta 	return rc;
2024ed19f0dSVikas Gupta }
2034ed19f0dSVikas Gupta 
2044ed19f0dSVikas Gupta struct bcmfs_sym_session *
2054ed19f0dSVikas Gupta bcmfs_sym_get_session(struct rte_crypto_op *op)
2064ed19f0dSVikas Gupta {
2074ed19f0dSVikas Gupta 	struct bcmfs_sym_session *sess = NULL;
2084ed19f0dSVikas Gupta 
2094ed19f0dSVikas Gupta 	if (unlikely(op->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
2104ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "operations op(%p) is sessionless", op);
2114ed19f0dSVikas Gupta 	} else if (likely(op->sym->session != NULL)) {
2124ed19f0dSVikas Gupta 		/* get existing session */
2132a440d6aSAkhil Goyal 		sess = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session);
2144ed19f0dSVikas Gupta 	}
2154ed19f0dSVikas Gupta 
2164ed19f0dSVikas Gupta 	if (sess == NULL)
2174ed19f0dSVikas Gupta 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
2184ed19f0dSVikas Gupta 
2194ed19f0dSVikas Gupta 	return sess;
2204ed19f0dSVikas Gupta }
2214ed19f0dSVikas Gupta 
2224ed19f0dSVikas Gupta int
223bdce2564SAkhil Goyal bcmfs_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
2244ed19f0dSVikas Gupta 			    struct rte_crypto_sym_xform *xform,
225bdce2564SAkhil Goyal 			    struct rte_cryptodev_sym_session *sess)
2264ed19f0dSVikas Gupta {
2274ed19f0dSVikas Gupta 	void *sess_private_data;
2284ed19f0dSVikas Gupta 	int ret;
2294ed19f0dSVikas Gupta 
2304ed19f0dSVikas Gupta 	if (unlikely(sess == NULL)) {
2314ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "Invalid session struct");
2324ed19f0dSVikas Gupta 		return -EINVAL;
2334ed19f0dSVikas Gupta 	}
2344ed19f0dSVikas Gupta 
2352a440d6aSAkhil Goyal 	sess_private_data = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
2364ed19f0dSVikas Gupta 
2374ed19f0dSVikas Gupta 	ret = crypto_set_session_parameters(sess_private_data, xform);
2384ed19f0dSVikas Gupta 
2394ed19f0dSVikas Gupta 	if (ret != 0) {
2404ed19f0dSVikas Gupta 		BCMFS_DP_LOG(ERR, "Failed configure session parameters");
2414ed19f0dSVikas Gupta 		return ret;
2424ed19f0dSVikas Gupta 	}
2434ed19f0dSVikas Gupta 
2444ed19f0dSVikas Gupta 	return 0;
2454ed19f0dSVikas Gupta }
2464ed19f0dSVikas Gupta 
2474ed19f0dSVikas Gupta /* Clear the memory of session so it doesn't leave key material behind */
2484ed19f0dSVikas Gupta void
249bdce2564SAkhil Goyal bcmfs_sym_session_clear(struct rte_cryptodev *dev __rte_unused,
250bdce2564SAkhil Goyal 			struct rte_cryptodev_sym_session  *sess __rte_unused)
251bdce2564SAkhil Goyal {}
2524ed19f0dSVikas Gupta 
2534ed19f0dSVikas Gupta unsigned int
2544ed19f0dSVikas Gupta bcmfs_sym_session_get_private_size(struct rte_cryptodev *dev __rte_unused)
2554ed19f0dSVikas Gupta {
2564ed19f0dSVikas Gupta 	return sizeof(struct bcmfs_sym_session);
2574ed19f0dSVikas Gupta }
258