Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2020 Broadcom 3 : : * All rights reserved. 4 : : */ 5 : : 6 : : #include <rte_crypto.h> 7 : : #include <rte_crypto_sym.h> 8 : : #include <rte_log.h> 9 : : 10 : : #include "bcmfs_logs.h" 11 : : #include "bcmfs_sym_defs.h" 12 : : #include "bcmfs_sym_pmd.h" 13 : : #include "bcmfs_sym_session.h" 14 : : 15 : : /** Configure the session from a crypto xform chain */ 16 : : static enum bcmfs_sym_chain_order 17 : 0 : crypto_get_chain_order(const struct rte_crypto_sym_xform *xform) 18 : : { 19 : : enum bcmfs_sym_chain_order res = BCMFS_SYM_CHAIN_NOT_SUPPORTED; 20 : : 21 [ # # ]: 0 : if (xform != NULL) { 22 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) 23 : : res = BCMFS_SYM_CHAIN_AEAD; 24 : : 25 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 26 [ # # ]: 0 : if (xform->next == NULL) 27 : : res = BCMFS_SYM_CHAIN_ONLY_AUTH; 28 [ # # ]: 0 : else if (xform->next->type == 29 : : RTE_CRYPTO_SYM_XFORM_CIPHER) 30 : : res = BCMFS_SYM_CHAIN_AUTH_CIPHER; 31 : : } 32 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 33 [ # # ]: 0 : if (xform->next == NULL) 34 : : res = BCMFS_SYM_CHAIN_ONLY_CIPHER; 35 [ # # ]: 0 : else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) 36 : : res = BCMFS_SYM_CHAIN_CIPHER_AUTH; 37 : : } 38 : : } 39 : : 40 : 0 : return res; 41 : : } 42 : : 43 : : /* Get session cipher key from input cipher key */ 44 : : static void 45 : : get_key(const uint8_t *input_key, int keylen, uint8_t *session_key) 46 : : { 47 : 0 : memcpy(session_key, input_key, keylen); 48 : : } 49 : : 50 : : /* Set session cipher parameters */ 51 : : static int 52 : 0 : crypto_set_session_cipher_parameters(struct bcmfs_sym_session *sess, 53 : : const struct rte_crypto_cipher_xform *cipher_xform) 54 : : { 55 [ # # ]: 0 : if (cipher_xform->key.length > BCMFS_MAX_KEY_SIZE) { 56 : 0 : BCMFS_DP_LOG(ERR, "key length not supported"); 57 : 0 : return -EINVAL; 58 : : } 59 : : 60 : 0 : sess->cipher.key.length = cipher_xform->key.length; 61 : 0 : sess->cipher.iv.offset = cipher_xform->iv.offset; 62 : 0 : sess->cipher.iv.length = cipher_xform->iv.length; 63 : 0 : sess->cipher.op = cipher_xform->op; 64 : 0 : sess->cipher.algo = cipher_xform->algo; 65 : : 66 : 0 : get_key(cipher_xform->key.data, 67 : : sess->cipher.key.length, 68 : 0 : sess->cipher.key.data); 69 : : 70 : 0 : return 0; 71 : : } 72 : : 73 : : /* Set session auth parameters */ 74 : : static int 75 : 0 : crypto_set_session_auth_parameters(struct bcmfs_sym_session *sess, 76 : : const struct rte_crypto_auth_xform *auth_xform) 77 : : { 78 [ # # ]: 0 : if (auth_xform->key.length > BCMFS_MAX_KEY_SIZE) { 79 : 0 : BCMFS_DP_LOG(ERR, "key length not supported"); 80 : 0 : return -EINVAL; 81 : : } 82 : : 83 : 0 : sess->auth.op = auth_xform->op; 84 : 0 : sess->auth.key.length = auth_xform->key.length; 85 : 0 : sess->auth.digest_length = auth_xform->digest_length; 86 : 0 : sess->auth.iv.length = auth_xform->iv.length; 87 : 0 : sess->auth.iv.offset = auth_xform->iv.offset; 88 : 0 : sess->auth.algo = auth_xform->algo; 89 : : 90 : 0 : get_key(auth_xform->key.data, 91 : : auth_xform->key.length, 92 : 0 : sess->auth.key.data); 93 : : 94 : 0 : return 0; 95 : : } 96 : : 97 : : /* Set session aead parameters */ 98 : : static int 99 : 0 : crypto_set_session_aead_parameters(struct bcmfs_sym_session *sess, 100 : : const struct rte_crypto_sym_xform *aead_xform) 101 : : { 102 [ # # ]: 0 : if (aead_xform->aead.key.length > BCMFS_MAX_KEY_SIZE) { 103 : 0 : BCMFS_DP_LOG(ERR, "key length not supported"); 104 : 0 : return -EINVAL; 105 : : } 106 : : 107 : 0 : sess->aead.iv.offset = aead_xform->aead.iv.offset; 108 : 0 : sess->aead.iv.length = aead_xform->aead.iv.length; 109 : 0 : sess->aead.aad_length = aead_xform->aead.aad_length; 110 : 0 : sess->aead.key.length = aead_xform->aead.key.length; 111 : 0 : sess->aead.digest_length = aead_xform->aead.digest_length; 112 : 0 : sess->aead.op = aead_xform->aead.op; 113 : 0 : sess->aead.algo = aead_xform->aead.algo; 114 : : 115 : 0 : get_key(aead_xform->aead.key.data, 116 : : aead_xform->aead.key.length, 117 : 0 : sess->aead.key.data); 118 : : 119 : 0 : return 0; 120 : : } 121 : : 122 : : static struct rte_crypto_auth_xform * 123 : : crypto_get_auth_xform(struct rte_crypto_sym_xform *xform) 124 : : { 125 : : do { 126 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 127 : 0 : return &xform->auth; 128 : : 129 : 0 : xform = xform->next; 130 [ # # ]: 0 : } while (xform); 131 : : 132 : : return NULL; 133 : : } 134 : : 135 : : static struct rte_crypto_cipher_xform * 136 : : crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform) 137 : : { 138 : : do { 139 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 140 : 0 : return &xform->cipher; 141 : : 142 : 0 : xform = xform->next; 143 [ # # ]: 0 : } while (xform); 144 : : 145 : : return NULL; 146 : : } 147 : : 148 : : /** Parse crypto xform chain and set private session parameters */ 149 : : static int 150 : 0 : crypto_set_session_parameters(struct bcmfs_sym_session *sess, 151 : : struct rte_crypto_sym_xform *xform) 152 : : { 153 : : int rc = 0; 154 : : struct rte_crypto_cipher_xform *cipher_xform = 155 : : crypto_get_cipher_xform(xform); 156 : : struct rte_crypto_auth_xform *auth_xform = 157 : : crypto_get_auth_xform(xform); 158 : : 159 : 0 : sess->chain_order = crypto_get_chain_order(xform); 160 : : 161 [ # # # # : 0 : switch (sess->chain_order) { # # ] 162 : 0 : case BCMFS_SYM_CHAIN_ONLY_CIPHER: 163 [ # # ]: 0 : if (crypto_set_session_cipher_parameters(sess, cipher_xform)) 164 : : rc = -EINVAL; 165 : : break; 166 : 0 : case BCMFS_SYM_CHAIN_ONLY_AUTH: 167 [ # # ]: 0 : if (crypto_set_session_auth_parameters(sess, auth_xform)) 168 : : rc = -EINVAL; 169 : : break; 170 : 0 : case BCMFS_SYM_CHAIN_AUTH_CIPHER: 171 : 0 : sess->cipher_first = false; 172 [ # # ]: 0 : if (crypto_set_session_auth_parameters(sess, auth_xform)) { 173 : : rc = -EINVAL; 174 : 0 : goto error; 175 : : } 176 : : 177 [ # # ]: 0 : if (crypto_set_session_cipher_parameters(sess, cipher_xform)) 178 : : rc = -EINVAL; 179 : : break; 180 : 0 : case BCMFS_SYM_CHAIN_CIPHER_AUTH: 181 : 0 : sess->cipher_first = true; 182 [ # # ]: 0 : if (crypto_set_session_auth_parameters(sess, auth_xform)) { 183 : : rc = -EINVAL; 184 : 0 : goto error; 185 : : } 186 : : 187 [ # # ]: 0 : if (crypto_set_session_cipher_parameters(sess, cipher_xform)) 188 : : rc = -EINVAL; 189 : : break; 190 : 0 : case BCMFS_SYM_CHAIN_AEAD: 191 [ # # ]: 0 : if (crypto_set_session_aead_parameters(sess, xform)) 192 : : rc = -EINVAL; 193 : : break; 194 : 0 : default: 195 : 0 : BCMFS_DP_LOG(ERR, "Invalid chain order"); 196 : : rc = -EINVAL; 197 : 0 : break; 198 : : } 199 : : 200 : 0 : error: 201 : 0 : return rc; 202 : : } 203 : : 204 : : struct bcmfs_sym_session * 205 : 0 : bcmfs_sym_get_session(struct rte_crypto_op *op) 206 : : { 207 : : struct bcmfs_sym_session *sess = NULL; 208 : : 209 [ # # ]: 0 : if (unlikely(op->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) { 210 : 0 : BCMFS_DP_LOG(ERR, "operations op(%p) is sessionless", op); 211 [ # # ]: 0 : } else if (likely(op->sym->session != NULL)) { 212 : : /* get existing session */ 213 : 0 : sess = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session); 214 : : } 215 : : 216 : : if (sess == NULL) 217 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; 218 : : 219 : 0 : return sess; 220 : : } 221 : : 222 : : int 223 : 0 : bcmfs_sym_session_configure(struct rte_cryptodev *dev __rte_unused, 224 : : struct rte_crypto_sym_xform *xform, 225 : : struct rte_cryptodev_sym_session *sess) 226 : : { 227 : : void *sess_private_data; 228 : : int ret; 229 : : 230 [ # # ]: 0 : if (unlikely(sess == NULL)) { 231 : 0 : BCMFS_DP_LOG(ERR, "Invalid session struct"); 232 : 0 : return -EINVAL; 233 : : } 234 : : 235 : 0 : sess_private_data = CRYPTODEV_GET_SYM_SESS_PRIV(sess); 236 : : 237 : 0 : ret = crypto_set_session_parameters(sess_private_data, xform); 238 : : 239 [ # # ]: 0 : if (ret != 0) { 240 : 0 : BCMFS_DP_LOG(ERR, "Failed configure session parameters"); 241 : 0 : return ret; 242 : : } 243 : : 244 : : return 0; 245 : : } 246 : : 247 : : /* Clear the memory of session so it doesn't leave key material behind */ 248 : : void 249 : 0 : bcmfs_sym_session_clear(struct rte_cryptodev *dev __rte_unused, 250 : : struct rte_cryptodev_sym_session *sess __rte_unused) 251 : 0 : {} 252 : : 253 : : unsigned int 254 : 0 : bcmfs_sym_session_get_private_size(struct rte_cryptodev *dev __rte_unused) 255 : : { 256 : 0 : return sizeof(struct bcmfs_sym_session); 257 : : }