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