1*416d8220SZaibo Xu // SPDX-License-Identifier: GPL-2.0 2*416d8220SZaibo Xu /* Copyright (c) 2019 HiSilicon Limited. */ 3*416d8220SZaibo Xu 4*416d8220SZaibo Xu #include <crypto/aes.h> 5*416d8220SZaibo Xu #include <crypto/algapi.h> 6*416d8220SZaibo Xu #include <crypto/des.h> 7*416d8220SZaibo Xu #include <crypto/skcipher.h> 8*416d8220SZaibo Xu #include <crypto/xts.h> 9*416d8220SZaibo Xu #include <linux/crypto.h> 10*416d8220SZaibo Xu #include <linux/dma-mapping.h> 11*416d8220SZaibo Xu #include <linux/idr.h> 12*416d8220SZaibo Xu 13*416d8220SZaibo Xu #include "sec.h" 14*416d8220SZaibo Xu #include "sec_crypto.h" 15*416d8220SZaibo Xu 16*416d8220SZaibo Xu #define SEC_PRIORITY 4001 17*416d8220SZaibo Xu #define SEC_XTS_MIN_KEY_SIZE (2 * AES_MIN_KEY_SIZE) 18*416d8220SZaibo Xu #define SEC_XTS_MAX_KEY_SIZE (2 * AES_MAX_KEY_SIZE) 19*416d8220SZaibo Xu #define SEC_DES3_2KEY_SIZE (2 * DES_KEY_SIZE) 20*416d8220SZaibo Xu #define SEC_DES3_3KEY_SIZE (3 * DES_KEY_SIZE) 21*416d8220SZaibo Xu 22*416d8220SZaibo Xu /* SEC sqe(bd) bit operational relative MACRO */ 23*416d8220SZaibo Xu #define SEC_DE_OFFSET 1 24*416d8220SZaibo Xu #define SEC_CIPHER_OFFSET 4 25*416d8220SZaibo Xu #define SEC_SCENE_OFFSET 3 26*416d8220SZaibo Xu #define SEC_DST_SGL_OFFSET 2 27*416d8220SZaibo Xu #define SEC_SRC_SGL_OFFSET 7 28*416d8220SZaibo Xu #define SEC_CKEY_OFFSET 9 29*416d8220SZaibo Xu #define SEC_CMODE_OFFSET 12 30*416d8220SZaibo Xu #define SEC_FLAG_OFFSET 7 31*416d8220SZaibo Xu #define SEC_FLAG_MASK 0x0780 32*416d8220SZaibo Xu #define SEC_TYPE_MASK 0x0F 33*416d8220SZaibo Xu #define SEC_DONE_MASK 0x0001 34*416d8220SZaibo Xu 35*416d8220SZaibo Xu #define SEC_TOTAL_IV_SZ (SEC_IV_SIZE * QM_Q_DEPTH) 36*416d8220SZaibo Xu #define SEC_SGL_SGE_NR 128 37*416d8220SZaibo Xu #define SEC_CTX_DEV(ctx) (&(ctx)->sec->qm.pdev->dev) 38*416d8220SZaibo Xu 39*416d8220SZaibo Xu static DEFINE_MUTEX(sec_algs_lock); 40*416d8220SZaibo Xu static unsigned int sec_active_devs; 41*416d8220SZaibo Xu 42*416d8220SZaibo Xu /* Get an en/de-cipher queue cyclically to balance load over queues of TFM */ 43*416d8220SZaibo Xu static inline int sec_get_queue_id(struct sec_ctx *ctx, struct sec_req *req) 44*416d8220SZaibo Xu { 45*416d8220SZaibo Xu if (req->c_req.encrypt) 46*416d8220SZaibo Xu return (u32)atomic_inc_return(&ctx->enc_qcyclic) % 47*416d8220SZaibo Xu ctx->hlf_q_num; 48*416d8220SZaibo Xu 49*416d8220SZaibo Xu return (u32)atomic_inc_return(&ctx->dec_qcyclic) % ctx->hlf_q_num + 50*416d8220SZaibo Xu ctx->hlf_q_num; 51*416d8220SZaibo Xu } 52*416d8220SZaibo Xu 53*416d8220SZaibo Xu static inline void sec_put_queue_id(struct sec_ctx *ctx, struct sec_req *req) 54*416d8220SZaibo Xu { 55*416d8220SZaibo Xu if (req->c_req.encrypt) 56*416d8220SZaibo Xu atomic_dec(&ctx->enc_qcyclic); 57*416d8220SZaibo Xu else 58*416d8220SZaibo Xu atomic_dec(&ctx->dec_qcyclic); 59*416d8220SZaibo Xu } 60*416d8220SZaibo Xu 61*416d8220SZaibo Xu static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx) 62*416d8220SZaibo Xu { 63*416d8220SZaibo Xu int req_id; 64*416d8220SZaibo Xu 65*416d8220SZaibo Xu mutex_lock(&qp_ctx->req_lock); 66*416d8220SZaibo Xu 67*416d8220SZaibo Xu req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL, 68*416d8220SZaibo Xu 0, QM_Q_DEPTH, GFP_ATOMIC); 69*416d8220SZaibo Xu mutex_unlock(&qp_ctx->req_lock); 70*416d8220SZaibo Xu if (req_id < 0) { 71*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(req->ctx), "alloc req id fail!\n"); 72*416d8220SZaibo Xu return req_id; 73*416d8220SZaibo Xu } 74*416d8220SZaibo Xu 75*416d8220SZaibo Xu req->qp_ctx = qp_ctx; 76*416d8220SZaibo Xu qp_ctx->req_list[req_id] = req; 77*416d8220SZaibo Xu return req_id; 78*416d8220SZaibo Xu } 79*416d8220SZaibo Xu 80*416d8220SZaibo Xu static void sec_free_req_id(struct sec_req *req) 81*416d8220SZaibo Xu { 82*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 83*416d8220SZaibo Xu int req_id = req->req_id; 84*416d8220SZaibo Xu 85*416d8220SZaibo Xu if (req_id < 0 || req_id >= QM_Q_DEPTH) { 86*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(req->ctx), "free request id invalid!\n"); 87*416d8220SZaibo Xu return; 88*416d8220SZaibo Xu } 89*416d8220SZaibo Xu 90*416d8220SZaibo Xu qp_ctx->req_list[req_id] = NULL; 91*416d8220SZaibo Xu req->qp_ctx = NULL; 92*416d8220SZaibo Xu 93*416d8220SZaibo Xu mutex_lock(&qp_ctx->req_lock); 94*416d8220SZaibo Xu idr_remove(&qp_ctx->req_idr, req_id); 95*416d8220SZaibo Xu mutex_unlock(&qp_ctx->req_lock); 96*416d8220SZaibo Xu } 97*416d8220SZaibo Xu 98*416d8220SZaibo Xu static void sec_req_cb(struct hisi_qp *qp, void *resp) 99*416d8220SZaibo Xu { 100*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = qp->qp_ctx; 101*416d8220SZaibo Xu struct sec_sqe *bd = resp; 102*416d8220SZaibo Xu u16 done, flag; 103*416d8220SZaibo Xu u8 type; 104*416d8220SZaibo Xu struct sec_req *req; 105*416d8220SZaibo Xu 106*416d8220SZaibo Xu type = bd->type_cipher_auth & SEC_TYPE_MASK; 107*416d8220SZaibo Xu if (type == SEC_BD_TYPE2) { 108*416d8220SZaibo Xu req = qp_ctx->req_list[le16_to_cpu(bd->type2.tag)]; 109*416d8220SZaibo Xu req->err_type = bd->type2.error_type; 110*416d8220SZaibo Xu 111*416d8220SZaibo Xu done = le16_to_cpu(bd->type2.done_flag) & SEC_DONE_MASK; 112*416d8220SZaibo Xu flag = (le16_to_cpu(bd->type2.done_flag) & 113*416d8220SZaibo Xu SEC_FLAG_MASK) >> SEC_FLAG_OFFSET; 114*416d8220SZaibo Xu if (req->err_type || done != 0x1 || flag != 0x2) 115*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(req->ctx), 116*416d8220SZaibo Xu "err_type[%d],done[%d],flag[%d]\n", 117*416d8220SZaibo Xu req->err_type, done, flag); 118*416d8220SZaibo Xu } else { 119*416d8220SZaibo Xu pr_err("err bd type [%d]\n", type); 120*416d8220SZaibo Xu return; 121*416d8220SZaibo Xu } 122*416d8220SZaibo Xu 123*416d8220SZaibo Xu req->ctx->req_op->buf_unmap(req->ctx, req); 124*416d8220SZaibo Xu 125*416d8220SZaibo Xu req->ctx->req_op->callback(req->ctx, req); 126*416d8220SZaibo Xu } 127*416d8220SZaibo Xu 128*416d8220SZaibo Xu static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req) 129*416d8220SZaibo Xu { 130*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 131*416d8220SZaibo Xu int ret; 132*416d8220SZaibo Xu 133*416d8220SZaibo Xu mutex_lock(&qp_ctx->req_lock); 134*416d8220SZaibo Xu ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe); 135*416d8220SZaibo Xu mutex_unlock(&qp_ctx->req_lock); 136*416d8220SZaibo Xu 137*416d8220SZaibo Xu if (ret == -EBUSY) 138*416d8220SZaibo Xu return -ENOBUFS; 139*416d8220SZaibo Xu 140*416d8220SZaibo Xu if (!ret) { 141*416d8220SZaibo Xu if (req->fake_busy) 142*416d8220SZaibo Xu ret = -EBUSY; 143*416d8220SZaibo Xu else 144*416d8220SZaibo Xu ret = -EINPROGRESS; 145*416d8220SZaibo Xu } 146*416d8220SZaibo Xu 147*416d8220SZaibo Xu return ret; 148*416d8220SZaibo Xu } 149*416d8220SZaibo Xu 150*416d8220SZaibo Xu static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, 151*416d8220SZaibo Xu int qp_ctx_id, int alg_type) 152*416d8220SZaibo Xu { 153*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 154*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx; 155*416d8220SZaibo Xu struct hisi_qp *qp; 156*416d8220SZaibo Xu int ret = -ENOMEM; 157*416d8220SZaibo Xu 158*416d8220SZaibo Xu qp = hisi_qm_create_qp(qm, alg_type); 159*416d8220SZaibo Xu if (IS_ERR(qp)) 160*416d8220SZaibo Xu return PTR_ERR(qp); 161*416d8220SZaibo Xu 162*416d8220SZaibo Xu qp_ctx = &ctx->qp_ctx[qp_ctx_id]; 163*416d8220SZaibo Xu qp->req_type = 0; 164*416d8220SZaibo Xu qp->qp_ctx = qp_ctx; 165*416d8220SZaibo Xu qp->req_cb = sec_req_cb; 166*416d8220SZaibo Xu qp_ctx->qp = qp; 167*416d8220SZaibo Xu qp_ctx->ctx = ctx; 168*416d8220SZaibo Xu 169*416d8220SZaibo Xu mutex_init(&qp_ctx->req_lock); 170*416d8220SZaibo Xu atomic_set(&qp_ctx->pending_reqs, 0); 171*416d8220SZaibo Xu idr_init(&qp_ctx->req_idr); 172*416d8220SZaibo Xu 173*416d8220SZaibo Xu qp_ctx->req_list = kcalloc(QM_Q_DEPTH, sizeof(void *), GFP_ATOMIC); 174*416d8220SZaibo Xu if (!qp_ctx->req_list) 175*416d8220SZaibo Xu goto err_destroy_idr; 176*416d8220SZaibo Xu 177*416d8220SZaibo Xu qp_ctx->c_in_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH, 178*416d8220SZaibo Xu SEC_SGL_SGE_NR); 179*416d8220SZaibo Xu if (!qp_ctx->c_in_pool) { 180*416d8220SZaibo Xu dev_err(dev, "fail to create sgl pool for input!\n"); 181*416d8220SZaibo Xu goto err_free_req_list; 182*416d8220SZaibo Xu } 183*416d8220SZaibo Xu 184*416d8220SZaibo Xu qp_ctx->c_out_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH, 185*416d8220SZaibo Xu SEC_SGL_SGE_NR); 186*416d8220SZaibo Xu if (!qp_ctx->c_out_pool) { 187*416d8220SZaibo Xu dev_err(dev, "fail to create sgl pool for output!\n"); 188*416d8220SZaibo Xu goto err_free_c_in_pool; 189*416d8220SZaibo Xu } 190*416d8220SZaibo Xu 191*416d8220SZaibo Xu ret = ctx->req_op->resource_alloc(ctx, qp_ctx); 192*416d8220SZaibo Xu if (ret) 193*416d8220SZaibo Xu goto err_free_c_out_pool; 194*416d8220SZaibo Xu 195*416d8220SZaibo Xu ret = hisi_qm_start_qp(qp, 0); 196*416d8220SZaibo Xu if (ret < 0) 197*416d8220SZaibo Xu goto err_queue_free; 198*416d8220SZaibo Xu 199*416d8220SZaibo Xu return 0; 200*416d8220SZaibo Xu 201*416d8220SZaibo Xu err_queue_free: 202*416d8220SZaibo Xu ctx->req_op->resource_free(ctx, qp_ctx); 203*416d8220SZaibo Xu err_free_c_out_pool: 204*416d8220SZaibo Xu hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool); 205*416d8220SZaibo Xu err_free_c_in_pool: 206*416d8220SZaibo Xu hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool); 207*416d8220SZaibo Xu err_free_req_list: 208*416d8220SZaibo Xu kfree(qp_ctx->req_list); 209*416d8220SZaibo Xu err_destroy_idr: 210*416d8220SZaibo Xu idr_destroy(&qp_ctx->req_idr); 211*416d8220SZaibo Xu hisi_qm_release_qp(qp); 212*416d8220SZaibo Xu 213*416d8220SZaibo Xu return ret; 214*416d8220SZaibo Xu } 215*416d8220SZaibo Xu 216*416d8220SZaibo Xu static void sec_release_qp_ctx(struct sec_ctx *ctx, 217*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx) 218*416d8220SZaibo Xu { 219*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 220*416d8220SZaibo Xu 221*416d8220SZaibo Xu hisi_qm_stop_qp(qp_ctx->qp); 222*416d8220SZaibo Xu ctx->req_op->resource_free(ctx, qp_ctx); 223*416d8220SZaibo Xu 224*416d8220SZaibo Xu hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool); 225*416d8220SZaibo Xu hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool); 226*416d8220SZaibo Xu 227*416d8220SZaibo Xu idr_destroy(&qp_ctx->req_idr); 228*416d8220SZaibo Xu kfree(qp_ctx->req_list); 229*416d8220SZaibo Xu hisi_qm_release_qp(qp_ctx->qp); 230*416d8220SZaibo Xu } 231*416d8220SZaibo Xu 232*416d8220SZaibo Xu static int sec_skcipher_init(struct crypto_skcipher *tfm) 233*416d8220SZaibo Xu { 234*416d8220SZaibo Xu struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); 235*416d8220SZaibo Xu struct sec_cipher_ctx *c_ctx; 236*416d8220SZaibo Xu struct sec_dev *sec; 237*416d8220SZaibo Xu struct device *dev; 238*416d8220SZaibo Xu struct hisi_qm *qm; 239*416d8220SZaibo Xu int i, ret; 240*416d8220SZaibo Xu 241*416d8220SZaibo Xu crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req)); 242*416d8220SZaibo Xu 243*416d8220SZaibo Xu sec = sec_find_device(cpu_to_node(smp_processor_id())); 244*416d8220SZaibo Xu if (!sec) { 245*416d8220SZaibo Xu pr_err("find no Hisilicon SEC device!\n"); 246*416d8220SZaibo Xu return -ENODEV; 247*416d8220SZaibo Xu } 248*416d8220SZaibo Xu ctx->sec = sec; 249*416d8220SZaibo Xu qm = &sec->qm; 250*416d8220SZaibo Xu dev = &qm->pdev->dev; 251*416d8220SZaibo Xu ctx->hlf_q_num = sec->ctx_q_num >> 0x1; 252*416d8220SZaibo Xu 253*416d8220SZaibo Xu /* Half of queue depth is taken as fake requests limit in the queue. */ 254*416d8220SZaibo Xu ctx->fake_req_limit = QM_Q_DEPTH >> 0x1; 255*416d8220SZaibo Xu ctx->qp_ctx = kcalloc(sec->ctx_q_num, sizeof(struct sec_qp_ctx), 256*416d8220SZaibo Xu GFP_KERNEL); 257*416d8220SZaibo Xu if (!ctx->qp_ctx) 258*416d8220SZaibo Xu return -ENOMEM; 259*416d8220SZaibo Xu 260*416d8220SZaibo Xu for (i = 0; i < sec->ctx_q_num; i++) { 261*416d8220SZaibo Xu ret = sec_create_qp_ctx(qm, ctx, i, 0); 262*416d8220SZaibo Xu if (ret) 263*416d8220SZaibo Xu goto err_sec_release_qp_ctx; 264*416d8220SZaibo Xu } 265*416d8220SZaibo Xu 266*416d8220SZaibo Xu c_ctx = &ctx->c_ctx; 267*416d8220SZaibo Xu c_ctx->ivsize = crypto_skcipher_ivsize(tfm); 268*416d8220SZaibo Xu if (c_ctx->ivsize > SEC_IV_SIZE) { 269*416d8220SZaibo Xu dev_err(dev, "get error iv size!\n"); 270*416d8220SZaibo Xu ret = -EINVAL; 271*416d8220SZaibo Xu goto err_sec_release_qp_ctx; 272*416d8220SZaibo Xu } 273*416d8220SZaibo Xu c_ctx->c_key = dma_alloc_coherent(dev, SEC_MAX_KEY_SIZE, 274*416d8220SZaibo Xu &c_ctx->c_key_dma, GFP_KERNEL); 275*416d8220SZaibo Xu if (!c_ctx->c_key) { 276*416d8220SZaibo Xu ret = -ENOMEM; 277*416d8220SZaibo Xu goto err_sec_release_qp_ctx; 278*416d8220SZaibo Xu } 279*416d8220SZaibo Xu 280*416d8220SZaibo Xu return 0; 281*416d8220SZaibo Xu 282*416d8220SZaibo Xu err_sec_release_qp_ctx: 283*416d8220SZaibo Xu for (i = i - 1; i >= 0; i--) 284*416d8220SZaibo Xu sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]); 285*416d8220SZaibo Xu 286*416d8220SZaibo Xu kfree(ctx->qp_ctx); 287*416d8220SZaibo Xu return ret; 288*416d8220SZaibo Xu } 289*416d8220SZaibo Xu 290*416d8220SZaibo Xu static void sec_skcipher_exit(struct crypto_skcipher *tfm) 291*416d8220SZaibo Xu { 292*416d8220SZaibo Xu struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); 293*416d8220SZaibo Xu struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; 294*416d8220SZaibo Xu int i = 0; 295*416d8220SZaibo Xu 296*416d8220SZaibo Xu if (c_ctx->c_key) { 297*416d8220SZaibo Xu dma_free_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE, 298*416d8220SZaibo Xu c_ctx->c_key, c_ctx->c_key_dma); 299*416d8220SZaibo Xu c_ctx->c_key = NULL; 300*416d8220SZaibo Xu } 301*416d8220SZaibo Xu 302*416d8220SZaibo Xu for (i = 0; i < ctx->sec->ctx_q_num; i++) 303*416d8220SZaibo Xu sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]); 304*416d8220SZaibo Xu 305*416d8220SZaibo Xu kfree(ctx->qp_ctx); 306*416d8220SZaibo Xu } 307*416d8220SZaibo Xu 308*416d8220SZaibo Xu static int sec_skcipher_3des_setkey(struct sec_cipher_ctx *c_ctx, 309*416d8220SZaibo Xu const u32 keylen, 310*416d8220SZaibo Xu const enum sec_cmode c_mode) 311*416d8220SZaibo Xu { 312*416d8220SZaibo Xu switch (keylen) { 313*416d8220SZaibo Xu case SEC_DES3_2KEY_SIZE: 314*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_3DES_2KEY; 315*416d8220SZaibo Xu break; 316*416d8220SZaibo Xu case SEC_DES3_3KEY_SIZE: 317*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_3DES_3KEY; 318*416d8220SZaibo Xu break; 319*416d8220SZaibo Xu default: 320*416d8220SZaibo Xu return -EINVAL; 321*416d8220SZaibo Xu } 322*416d8220SZaibo Xu 323*416d8220SZaibo Xu return 0; 324*416d8220SZaibo Xu } 325*416d8220SZaibo Xu 326*416d8220SZaibo Xu static int sec_skcipher_aes_sm4_setkey(struct sec_cipher_ctx *c_ctx, 327*416d8220SZaibo Xu const u32 keylen, 328*416d8220SZaibo Xu const enum sec_cmode c_mode) 329*416d8220SZaibo Xu { 330*416d8220SZaibo Xu if (c_mode == SEC_CMODE_XTS) { 331*416d8220SZaibo Xu switch (keylen) { 332*416d8220SZaibo Xu case SEC_XTS_MIN_KEY_SIZE: 333*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_128BIT; 334*416d8220SZaibo Xu break; 335*416d8220SZaibo Xu case SEC_XTS_MAX_KEY_SIZE: 336*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_256BIT; 337*416d8220SZaibo Xu break; 338*416d8220SZaibo Xu default: 339*416d8220SZaibo Xu pr_err("hisi_sec2: xts mode key error!\n"); 340*416d8220SZaibo Xu return -EINVAL; 341*416d8220SZaibo Xu } 342*416d8220SZaibo Xu } else { 343*416d8220SZaibo Xu switch (keylen) { 344*416d8220SZaibo Xu case AES_KEYSIZE_128: 345*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_128BIT; 346*416d8220SZaibo Xu break; 347*416d8220SZaibo Xu case AES_KEYSIZE_192: 348*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_192BIT; 349*416d8220SZaibo Xu break; 350*416d8220SZaibo Xu case AES_KEYSIZE_256: 351*416d8220SZaibo Xu c_ctx->c_key_len = SEC_CKEY_256BIT; 352*416d8220SZaibo Xu break; 353*416d8220SZaibo Xu default: 354*416d8220SZaibo Xu pr_err("hisi_sec2: aes key error!\n"); 355*416d8220SZaibo Xu return -EINVAL; 356*416d8220SZaibo Xu } 357*416d8220SZaibo Xu } 358*416d8220SZaibo Xu 359*416d8220SZaibo Xu return 0; 360*416d8220SZaibo Xu } 361*416d8220SZaibo Xu 362*416d8220SZaibo Xu static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, 363*416d8220SZaibo Xu const u32 keylen, const enum sec_calg c_alg, 364*416d8220SZaibo Xu const enum sec_cmode c_mode) 365*416d8220SZaibo Xu { 366*416d8220SZaibo Xu struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); 367*416d8220SZaibo Xu struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; 368*416d8220SZaibo Xu int ret; 369*416d8220SZaibo Xu 370*416d8220SZaibo Xu if (c_mode == SEC_CMODE_XTS) { 371*416d8220SZaibo Xu ret = xts_verify_key(tfm, key, keylen); 372*416d8220SZaibo Xu if (ret) { 373*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(ctx), "xts mode key err!\n"); 374*416d8220SZaibo Xu return ret; 375*416d8220SZaibo Xu } 376*416d8220SZaibo Xu } 377*416d8220SZaibo Xu 378*416d8220SZaibo Xu c_ctx->c_alg = c_alg; 379*416d8220SZaibo Xu c_ctx->c_mode = c_mode; 380*416d8220SZaibo Xu 381*416d8220SZaibo Xu switch (c_alg) { 382*416d8220SZaibo Xu case SEC_CALG_3DES: 383*416d8220SZaibo Xu ret = sec_skcipher_3des_setkey(c_ctx, keylen, c_mode); 384*416d8220SZaibo Xu break; 385*416d8220SZaibo Xu case SEC_CALG_AES: 386*416d8220SZaibo Xu case SEC_CALG_SM4: 387*416d8220SZaibo Xu ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode); 388*416d8220SZaibo Xu break; 389*416d8220SZaibo Xu default: 390*416d8220SZaibo Xu return -EINVAL; 391*416d8220SZaibo Xu } 392*416d8220SZaibo Xu 393*416d8220SZaibo Xu if (ret) { 394*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(ctx), "set sec key err!\n"); 395*416d8220SZaibo Xu return ret; 396*416d8220SZaibo Xu } 397*416d8220SZaibo Xu 398*416d8220SZaibo Xu memcpy(c_ctx->c_key, key, keylen); 399*416d8220SZaibo Xu 400*416d8220SZaibo Xu return 0; 401*416d8220SZaibo Xu } 402*416d8220SZaibo Xu 403*416d8220SZaibo Xu #define GEN_SEC_SETKEY_FUNC(name, c_alg, c_mode) \ 404*416d8220SZaibo Xu static int sec_setkey_##name(struct crypto_skcipher *tfm, const u8 *key,\ 405*416d8220SZaibo Xu u32 keylen) \ 406*416d8220SZaibo Xu { \ 407*416d8220SZaibo Xu return sec_skcipher_setkey(tfm, key, keylen, c_alg, c_mode); \ 408*416d8220SZaibo Xu } 409*416d8220SZaibo Xu 410*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_ecb, SEC_CALG_AES, SEC_CMODE_ECB) 411*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_cbc, SEC_CALG_AES, SEC_CMODE_CBC) 412*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_xts, SEC_CALG_AES, SEC_CMODE_XTS) 413*416d8220SZaibo Xu 414*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(3des_ecb, SEC_CALG_3DES, SEC_CMODE_ECB) 415*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(3des_cbc, SEC_CALG_3DES, SEC_CMODE_CBC) 416*416d8220SZaibo Xu 417*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(sm4_xts, SEC_CALG_SM4, SEC_CMODE_XTS) 418*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(sm4_cbc, SEC_CALG_SM4, SEC_CMODE_CBC) 419*416d8220SZaibo Xu 420*416d8220SZaibo Xu static int sec_skcipher_get_res(struct sec_ctx *ctx, 421*416d8220SZaibo Xu struct sec_req *req) 422*416d8220SZaibo Xu { 423*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 424*416d8220SZaibo Xu struct sec_cipher_res *c_res = qp_ctx->alg_meta_data; 425*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 426*416d8220SZaibo Xu int req_id = req->req_id; 427*416d8220SZaibo Xu 428*416d8220SZaibo Xu c_req->c_ivin = c_res[req_id].c_ivin; 429*416d8220SZaibo Xu c_req->c_ivin_dma = c_res[req_id].c_ivin_dma; 430*416d8220SZaibo Xu 431*416d8220SZaibo Xu return 0; 432*416d8220SZaibo Xu } 433*416d8220SZaibo Xu 434*416d8220SZaibo Xu static int sec_skcipher_resource_alloc(struct sec_ctx *ctx, 435*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx) 436*416d8220SZaibo Xu { 437*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 438*416d8220SZaibo Xu struct sec_cipher_res *res; 439*416d8220SZaibo Xu int i; 440*416d8220SZaibo Xu 441*416d8220SZaibo Xu res = kcalloc(QM_Q_DEPTH, sizeof(struct sec_cipher_res), GFP_KERNEL); 442*416d8220SZaibo Xu if (!res) 443*416d8220SZaibo Xu return -ENOMEM; 444*416d8220SZaibo Xu 445*416d8220SZaibo Xu res->c_ivin = dma_alloc_coherent(dev, SEC_TOTAL_IV_SZ, 446*416d8220SZaibo Xu &res->c_ivin_dma, GFP_KERNEL); 447*416d8220SZaibo Xu if (!res->c_ivin) { 448*416d8220SZaibo Xu kfree(res); 449*416d8220SZaibo Xu return -ENOMEM; 450*416d8220SZaibo Xu } 451*416d8220SZaibo Xu 452*416d8220SZaibo Xu for (i = 1; i < QM_Q_DEPTH; i++) { 453*416d8220SZaibo Xu res[i].c_ivin_dma = res->c_ivin_dma + i * SEC_IV_SIZE; 454*416d8220SZaibo Xu res[i].c_ivin = res->c_ivin + i * SEC_IV_SIZE; 455*416d8220SZaibo Xu } 456*416d8220SZaibo Xu qp_ctx->alg_meta_data = res; 457*416d8220SZaibo Xu 458*416d8220SZaibo Xu return 0; 459*416d8220SZaibo Xu } 460*416d8220SZaibo Xu 461*416d8220SZaibo Xu static void sec_skcipher_resource_free(struct sec_ctx *ctx, 462*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx) 463*416d8220SZaibo Xu { 464*416d8220SZaibo Xu struct sec_cipher_res *res = qp_ctx->alg_meta_data; 465*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 466*416d8220SZaibo Xu 467*416d8220SZaibo Xu if (!res) 468*416d8220SZaibo Xu return; 469*416d8220SZaibo Xu 470*416d8220SZaibo Xu dma_free_coherent(dev, SEC_TOTAL_IV_SZ, res->c_ivin, res->c_ivin_dma); 471*416d8220SZaibo Xu kfree(res); 472*416d8220SZaibo Xu } 473*416d8220SZaibo Xu 474*416d8220SZaibo Xu static int sec_skcipher_map(struct device *dev, struct sec_req *req, 475*416d8220SZaibo Xu struct scatterlist *src, struct scatterlist *dst) 476*416d8220SZaibo Xu { 477*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 478*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 479*416d8220SZaibo Xu 480*416d8220SZaibo Xu c_req->c_in = hisi_acc_sg_buf_map_to_hw_sgl(dev, src, 481*416d8220SZaibo Xu qp_ctx->c_in_pool, 482*416d8220SZaibo Xu req->req_id, 483*416d8220SZaibo Xu &c_req->c_in_dma); 484*416d8220SZaibo Xu 485*416d8220SZaibo Xu if (IS_ERR(c_req->c_in)) { 486*416d8220SZaibo Xu dev_err(dev, "fail to dma map input sgl buffers!\n"); 487*416d8220SZaibo Xu return PTR_ERR(c_req->c_in); 488*416d8220SZaibo Xu } 489*416d8220SZaibo Xu 490*416d8220SZaibo Xu if (dst == src) { 491*416d8220SZaibo Xu c_req->c_out = c_req->c_in; 492*416d8220SZaibo Xu c_req->c_out_dma = c_req->c_in_dma; 493*416d8220SZaibo Xu } else { 494*416d8220SZaibo Xu c_req->c_out = hisi_acc_sg_buf_map_to_hw_sgl(dev, dst, 495*416d8220SZaibo Xu qp_ctx->c_out_pool, 496*416d8220SZaibo Xu req->req_id, 497*416d8220SZaibo Xu &c_req->c_out_dma); 498*416d8220SZaibo Xu 499*416d8220SZaibo Xu if (IS_ERR(c_req->c_out)) { 500*416d8220SZaibo Xu dev_err(dev, "fail to dma map output sgl buffers!\n"); 501*416d8220SZaibo Xu hisi_acc_sg_buf_unmap(dev, src, c_req->c_in); 502*416d8220SZaibo Xu return PTR_ERR(c_req->c_out); 503*416d8220SZaibo Xu } 504*416d8220SZaibo Xu } 505*416d8220SZaibo Xu 506*416d8220SZaibo Xu return 0; 507*416d8220SZaibo Xu } 508*416d8220SZaibo Xu 509*416d8220SZaibo Xu static int sec_skcipher_sgl_map(struct sec_ctx *ctx, struct sec_req *req) 510*416d8220SZaibo Xu { 511*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 512*416d8220SZaibo Xu 513*416d8220SZaibo Xu return sec_skcipher_map(SEC_CTX_DEV(ctx), req, 514*416d8220SZaibo Xu c_req->sk_req->src, c_req->sk_req->dst); 515*416d8220SZaibo Xu } 516*416d8220SZaibo Xu 517*416d8220SZaibo Xu static void sec_skcipher_sgl_unmap(struct sec_ctx *ctx, struct sec_req *req) 518*416d8220SZaibo Xu { 519*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 520*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 521*416d8220SZaibo Xu struct skcipher_request *sk_req = c_req->sk_req; 522*416d8220SZaibo Xu 523*416d8220SZaibo Xu if (sk_req->dst != sk_req->src) 524*416d8220SZaibo Xu hisi_acc_sg_buf_unmap(dev, sk_req->src, c_req->c_in); 525*416d8220SZaibo Xu 526*416d8220SZaibo Xu hisi_acc_sg_buf_unmap(dev, sk_req->dst, c_req->c_out); 527*416d8220SZaibo Xu } 528*416d8220SZaibo Xu 529*416d8220SZaibo Xu static int sec_request_transfer(struct sec_ctx *ctx, struct sec_req *req) 530*416d8220SZaibo Xu { 531*416d8220SZaibo Xu int ret; 532*416d8220SZaibo Xu 533*416d8220SZaibo Xu ret = ctx->req_op->buf_map(ctx, req); 534*416d8220SZaibo Xu if (ret) 535*416d8220SZaibo Xu return ret; 536*416d8220SZaibo Xu 537*416d8220SZaibo Xu ctx->req_op->do_transfer(ctx, req); 538*416d8220SZaibo Xu 539*416d8220SZaibo Xu ret = ctx->req_op->bd_fill(ctx, req); 540*416d8220SZaibo Xu if (ret) 541*416d8220SZaibo Xu goto unmap_req_buf; 542*416d8220SZaibo Xu 543*416d8220SZaibo Xu return ret; 544*416d8220SZaibo Xu 545*416d8220SZaibo Xu unmap_req_buf: 546*416d8220SZaibo Xu ctx->req_op->buf_unmap(ctx, req); 547*416d8220SZaibo Xu 548*416d8220SZaibo Xu return ret; 549*416d8220SZaibo Xu } 550*416d8220SZaibo Xu 551*416d8220SZaibo Xu static void sec_request_untransfer(struct sec_ctx *ctx, struct sec_req *req) 552*416d8220SZaibo Xu { 553*416d8220SZaibo Xu ctx->req_op->buf_unmap(ctx, req); 554*416d8220SZaibo Xu } 555*416d8220SZaibo Xu 556*416d8220SZaibo Xu static void sec_skcipher_copy_iv(struct sec_ctx *ctx, struct sec_req *req) 557*416d8220SZaibo Xu { 558*416d8220SZaibo Xu struct skcipher_request *sk_req = req->c_req.sk_req; 559*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 560*416d8220SZaibo Xu 561*416d8220SZaibo Xu c_req->c_len = sk_req->cryptlen; 562*416d8220SZaibo Xu memcpy(c_req->c_ivin, sk_req->iv, ctx->c_ctx.ivsize); 563*416d8220SZaibo Xu } 564*416d8220SZaibo Xu 565*416d8220SZaibo Xu static int sec_skcipher_bd_fill(struct sec_ctx *ctx, struct sec_req *req) 566*416d8220SZaibo Xu { 567*416d8220SZaibo Xu struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; 568*416d8220SZaibo Xu struct sec_cipher_req *c_req = &req->c_req; 569*416d8220SZaibo Xu struct sec_sqe *sec_sqe = &req->sec_sqe; 570*416d8220SZaibo Xu u8 de = 0; 571*416d8220SZaibo Xu u8 scene, sa_type, da_type; 572*416d8220SZaibo Xu u8 bd_type, cipher; 573*416d8220SZaibo Xu 574*416d8220SZaibo Xu memset(sec_sqe, 0, sizeof(struct sec_sqe)); 575*416d8220SZaibo Xu 576*416d8220SZaibo Xu sec_sqe->type2.c_key_addr = cpu_to_le64(c_ctx->c_key_dma); 577*416d8220SZaibo Xu sec_sqe->type2.c_ivin_addr = cpu_to_le64(c_req->c_ivin_dma); 578*416d8220SZaibo Xu sec_sqe->type2.data_src_addr = cpu_to_le64(c_req->c_in_dma); 579*416d8220SZaibo Xu sec_sqe->type2.data_dst_addr = cpu_to_le64(c_req->c_out_dma); 580*416d8220SZaibo Xu 581*416d8220SZaibo Xu sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_mode) << 582*416d8220SZaibo Xu SEC_CMODE_OFFSET); 583*416d8220SZaibo Xu sec_sqe->type2.c_alg = c_ctx->c_alg; 584*416d8220SZaibo Xu sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_key_len) << 585*416d8220SZaibo Xu SEC_CKEY_OFFSET); 586*416d8220SZaibo Xu 587*416d8220SZaibo Xu bd_type = SEC_BD_TYPE2; 588*416d8220SZaibo Xu if (c_req->encrypt) 589*416d8220SZaibo Xu cipher = SEC_CIPHER_ENC << SEC_CIPHER_OFFSET; 590*416d8220SZaibo Xu else 591*416d8220SZaibo Xu cipher = SEC_CIPHER_DEC << SEC_CIPHER_OFFSET; 592*416d8220SZaibo Xu sec_sqe->type_cipher_auth = bd_type | cipher; 593*416d8220SZaibo Xu 594*416d8220SZaibo Xu sa_type = SEC_SGL << SEC_SRC_SGL_OFFSET; 595*416d8220SZaibo Xu scene = SEC_COMM_SCENE << SEC_SCENE_OFFSET; 596*416d8220SZaibo Xu if (c_req->c_in_dma != c_req->c_out_dma) 597*416d8220SZaibo Xu de = 0x1 << SEC_DE_OFFSET; 598*416d8220SZaibo Xu 599*416d8220SZaibo Xu sec_sqe->sds_sa_type = (de | scene | sa_type); 600*416d8220SZaibo Xu 601*416d8220SZaibo Xu /* Just set DST address type */ 602*416d8220SZaibo Xu da_type = SEC_SGL << SEC_DST_SGL_OFFSET; 603*416d8220SZaibo Xu sec_sqe->sdm_addr_type |= da_type; 604*416d8220SZaibo Xu 605*416d8220SZaibo Xu sec_sqe->type2.clen_ivhlen |= cpu_to_le32(c_req->c_len); 606*416d8220SZaibo Xu sec_sqe->type2.tag = cpu_to_le16((u16)req->req_id); 607*416d8220SZaibo Xu 608*416d8220SZaibo Xu return 0; 609*416d8220SZaibo Xu } 610*416d8220SZaibo Xu 611*416d8220SZaibo Xu static void sec_update_iv(struct sec_req *req) 612*416d8220SZaibo Xu { 613*416d8220SZaibo Xu struct skcipher_request *sk_req = req->c_req.sk_req; 614*416d8220SZaibo Xu u32 iv_size = req->ctx->c_ctx.ivsize; 615*416d8220SZaibo Xu struct scatterlist *sgl; 616*416d8220SZaibo Xu size_t sz; 617*416d8220SZaibo Xu 618*416d8220SZaibo Xu if (req->c_req.encrypt) 619*416d8220SZaibo Xu sgl = sk_req->dst; 620*416d8220SZaibo Xu else 621*416d8220SZaibo Xu sgl = sk_req->src; 622*416d8220SZaibo Xu 623*416d8220SZaibo Xu sz = sg_pcopy_to_buffer(sgl, sg_nents(sgl), sk_req->iv, 624*416d8220SZaibo Xu iv_size, sk_req->cryptlen - iv_size); 625*416d8220SZaibo Xu if (sz != iv_size) 626*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(req->ctx), "copy output iv error!\n"); 627*416d8220SZaibo Xu } 628*416d8220SZaibo Xu 629*416d8220SZaibo Xu static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req) 630*416d8220SZaibo Xu { 631*416d8220SZaibo Xu struct skcipher_request *sk_req = req->c_req.sk_req; 632*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 633*416d8220SZaibo Xu 634*416d8220SZaibo Xu atomic_dec(&qp_ctx->pending_reqs); 635*416d8220SZaibo Xu sec_free_req_id(req); 636*416d8220SZaibo Xu 637*416d8220SZaibo Xu /* IV output at encrypto of CBC mode */ 638*416d8220SZaibo Xu if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && req->c_req.encrypt) 639*416d8220SZaibo Xu sec_update_iv(req); 640*416d8220SZaibo Xu 641*416d8220SZaibo Xu if (__sync_bool_compare_and_swap(&req->fake_busy, 1, 0)) 642*416d8220SZaibo Xu sk_req->base.complete(&sk_req->base, -EINPROGRESS); 643*416d8220SZaibo Xu 644*416d8220SZaibo Xu sk_req->base.complete(&sk_req->base, req->err_type); 645*416d8220SZaibo Xu } 646*416d8220SZaibo Xu 647*416d8220SZaibo Xu static void sec_request_uninit(struct sec_ctx *ctx, struct sec_req *req) 648*416d8220SZaibo Xu { 649*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx = req->qp_ctx; 650*416d8220SZaibo Xu 651*416d8220SZaibo Xu atomic_dec(&qp_ctx->pending_reqs); 652*416d8220SZaibo Xu sec_free_req_id(req); 653*416d8220SZaibo Xu sec_put_queue_id(ctx, req); 654*416d8220SZaibo Xu } 655*416d8220SZaibo Xu 656*416d8220SZaibo Xu static int sec_request_init(struct sec_ctx *ctx, struct sec_req *req) 657*416d8220SZaibo Xu { 658*416d8220SZaibo Xu struct sec_qp_ctx *qp_ctx; 659*416d8220SZaibo Xu int issue_id, ret; 660*416d8220SZaibo Xu 661*416d8220SZaibo Xu /* To load balance */ 662*416d8220SZaibo Xu issue_id = sec_get_queue_id(ctx, req); 663*416d8220SZaibo Xu qp_ctx = &ctx->qp_ctx[issue_id]; 664*416d8220SZaibo Xu 665*416d8220SZaibo Xu req->req_id = sec_alloc_req_id(req, qp_ctx); 666*416d8220SZaibo Xu if (req->req_id < 0) { 667*416d8220SZaibo Xu sec_put_queue_id(ctx, req); 668*416d8220SZaibo Xu return req->req_id; 669*416d8220SZaibo Xu } 670*416d8220SZaibo Xu 671*416d8220SZaibo Xu if (ctx->fake_req_limit <= atomic_inc_return(&qp_ctx->pending_reqs)) 672*416d8220SZaibo Xu req->fake_busy = 1; 673*416d8220SZaibo Xu else 674*416d8220SZaibo Xu req->fake_busy = 0; 675*416d8220SZaibo Xu 676*416d8220SZaibo Xu ret = ctx->req_op->get_res(ctx, req); 677*416d8220SZaibo Xu if (ret) { 678*416d8220SZaibo Xu atomic_dec(&qp_ctx->pending_reqs); 679*416d8220SZaibo Xu sec_request_uninit(ctx, req); 680*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(ctx), "get resources failed!\n"); 681*416d8220SZaibo Xu } 682*416d8220SZaibo Xu 683*416d8220SZaibo Xu return ret; 684*416d8220SZaibo Xu } 685*416d8220SZaibo Xu 686*416d8220SZaibo Xu static int sec_process(struct sec_ctx *ctx, struct sec_req *req) 687*416d8220SZaibo Xu { 688*416d8220SZaibo Xu int ret; 689*416d8220SZaibo Xu 690*416d8220SZaibo Xu ret = sec_request_init(ctx, req); 691*416d8220SZaibo Xu if (ret) 692*416d8220SZaibo Xu return ret; 693*416d8220SZaibo Xu 694*416d8220SZaibo Xu ret = sec_request_transfer(ctx, req); 695*416d8220SZaibo Xu if (ret) 696*416d8220SZaibo Xu goto err_uninit_req; 697*416d8220SZaibo Xu 698*416d8220SZaibo Xu /* Output IV as decrypto */ 699*416d8220SZaibo Xu if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt) 700*416d8220SZaibo Xu sec_update_iv(req); 701*416d8220SZaibo Xu 702*416d8220SZaibo Xu ret = ctx->req_op->bd_send(ctx, req); 703*416d8220SZaibo Xu if (ret != -EBUSY && ret != -EINPROGRESS) { 704*416d8220SZaibo Xu dev_err(SEC_CTX_DEV(ctx), "send sec request failed!\n"); 705*416d8220SZaibo Xu goto err_send_req; 706*416d8220SZaibo Xu } 707*416d8220SZaibo Xu 708*416d8220SZaibo Xu return ret; 709*416d8220SZaibo Xu 710*416d8220SZaibo Xu err_send_req: 711*416d8220SZaibo Xu /* As failing, restore the IV from user */ 712*416d8220SZaibo Xu if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt) 713*416d8220SZaibo Xu memcpy(req->c_req.sk_req->iv, req->c_req.c_ivin, 714*416d8220SZaibo Xu ctx->c_ctx.ivsize); 715*416d8220SZaibo Xu 716*416d8220SZaibo Xu sec_request_untransfer(ctx, req); 717*416d8220SZaibo Xu err_uninit_req: 718*416d8220SZaibo Xu sec_request_uninit(ctx, req); 719*416d8220SZaibo Xu 720*416d8220SZaibo Xu return ret; 721*416d8220SZaibo Xu } 722*416d8220SZaibo Xu 723*416d8220SZaibo Xu static struct sec_req_op sec_req_ops_tbl = { 724*416d8220SZaibo Xu .get_res = sec_skcipher_get_res, 725*416d8220SZaibo Xu .resource_alloc = sec_skcipher_resource_alloc, 726*416d8220SZaibo Xu .resource_free = sec_skcipher_resource_free, 727*416d8220SZaibo Xu .buf_map = sec_skcipher_sgl_map, 728*416d8220SZaibo Xu .buf_unmap = sec_skcipher_sgl_unmap, 729*416d8220SZaibo Xu .do_transfer = sec_skcipher_copy_iv, 730*416d8220SZaibo Xu .bd_fill = sec_skcipher_bd_fill, 731*416d8220SZaibo Xu .bd_send = sec_bd_send, 732*416d8220SZaibo Xu .callback = sec_skcipher_callback, 733*416d8220SZaibo Xu .process = sec_process, 734*416d8220SZaibo Xu }; 735*416d8220SZaibo Xu 736*416d8220SZaibo Xu static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm) 737*416d8220SZaibo Xu { 738*416d8220SZaibo Xu struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); 739*416d8220SZaibo Xu 740*416d8220SZaibo Xu ctx->req_op = &sec_req_ops_tbl; 741*416d8220SZaibo Xu 742*416d8220SZaibo Xu return sec_skcipher_init(tfm); 743*416d8220SZaibo Xu } 744*416d8220SZaibo Xu 745*416d8220SZaibo Xu static void sec_skcipher_ctx_exit(struct crypto_skcipher *tfm) 746*416d8220SZaibo Xu { 747*416d8220SZaibo Xu sec_skcipher_exit(tfm); 748*416d8220SZaibo Xu } 749*416d8220SZaibo Xu 750*416d8220SZaibo Xu static int sec_skcipher_param_check(struct sec_ctx *ctx, 751*416d8220SZaibo Xu struct skcipher_request *sk_req) 752*416d8220SZaibo Xu { 753*416d8220SZaibo Xu u8 c_alg = ctx->c_ctx.c_alg; 754*416d8220SZaibo Xu struct device *dev = SEC_CTX_DEV(ctx); 755*416d8220SZaibo Xu 756*416d8220SZaibo Xu if (!sk_req->src || !sk_req->dst) { 757*416d8220SZaibo Xu dev_err(dev, "skcipher input param error!\n"); 758*416d8220SZaibo Xu return -EINVAL; 759*416d8220SZaibo Xu } 760*416d8220SZaibo Xu 761*416d8220SZaibo Xu if (c_alg == SEC_CALG_3DES) { 762*416d8220SZaibo Xu if (sk_req->cryptlen & (DES3_EDE_BLOCK_SIZE - 1)) { 763*416d8220SZaibo Xu dev_err(dev, "skcipher 3des input length error!\n"); 764*416d8220SZaibo Xu return -EINVAL; 765*416d8220SZaibo Xu } 766*416d8220SZaibo Xu return 0; 767*416d8220SZaibo Xu } else if (c_alg == SEC_CALG_AES || c_alg == SEC_CALG_SM4) { 768*416d8220SZaibo Xu if (sk_req->cryptlen & (AES_BLOCK_SIZE - 1)) { 769*416d8220SZaibo Xu dev_err(dev, "skcipher aes input length error!\n"); 770*416d8220SZaibo Xu return -EINVAL; 771*416d8220SZaibo Xu } 772*416d8220SZaibo Xu return 0; 773*416d8220SZaibo Xu } 774*416d8220SZaibo Xu 775*416d8220SZaibo Xu dev_err(dev, "skcipher algorithm error!\n"); 776*416d8220SZaibo Xu return -EINVAL; 777*416d8220SZaibo Xu } 778*416d8220SZaibo Xu 779*416d8220SZaibo Xu static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt) 780*416d8220SZaibo Xu { 781*416d8220SZaibo Xu struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(sk_req); 782*416d8220SZaibo Xu struct sec_req *req = skcipher_request_ctx(sk_req); 783*416d8220SZaibo Xu struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); 784*416d8220SZaibo Xu int ret; 785*416d8220SZaibo Xu 786*416d8220SZaibo Xu if (!sk_req->cryptlen) 787*416d8220SZaibo Xu return 0; 788*416d8220SZaibo Xu 789*416d8220SZaibo Xu ret = sec_skcipher_param_check(ctx, sk_req); 790*416d8220SZaibo Xu if (ret) 791*416d8220SZaibo Xu return ret; 792*416d8220SZaibo Xu 793*416d8220SZaibo Xu req->c_req.sk_req = sk_req; 794*416d8220SZaibo Xu req->c_req.encrypt = encrypt; 795*416d8220SZaibo Xu req->ctx = ctx; 796*416d8220SZaibo Xu 797*416d8220SZaibo Xu return ctx->req_op->process(ctx, req); 798*416d8220SZaibo Xu } 799*416d8220SZaibo Xu 800*416d8220SZaibo Xu static int sec_skcipher_encrypt(struct skcipher_request *sk_req) 801*416d8220SZaibo Xu { 802*416d8220SZaibo Xu return sec_skcipher_crypto(sk_req, true); 803*416d8220SZaibo Xu } 804*416d8220SZaibo Xu 805*416d8220SZaibo Xu static int sec_skcipher_decrypt(struct skcipher_request *sk_req) 806*416d8220SZaibo Xu { 807*416d8220SZaibo Xu return sec_skcipher_crypto(sk_req, false); 808*416d8220SZaibo Xu } 809*416d8220SZaibo Xu 810*416d8220SZaibo Xu #define SEC_SKCIPHER_GEN_ALG(sec_cra_name, sec_set_key, sec_min_key_size, \ 811*416d8220SZaibo Xu sec_max_key_size, ctx_init, ctx_exit, blk_size, iv_size)\ 812*416d8220SZaibo Xu {\ 813*416d8220SZaibo Xu .base = {\ 814*416d8220SZaibo Xu .cra_name = sec_cra_name,\ 815*416d8220SZaibo Xu .cra_driver_name = "hisi_sec_"sec_cra_name,\ 816*416d8220SZaibo Xu .cra_priority = SEC_PRIORITY,\ 817*416d8220SZaibo Xu .cra_flags = CRYPTO_ALG_ASYNC,\ 818*416d8220SZaibo Xu .cra_blocksize = blk_size,\ 819*416d8220SZaibo Xu .cra_ctxsize = sizeof(struct sec_ctx),\ 820*416d8220SZaibo Xu .cra_module = THIS_MODULE,\ 821*416d8220SZaibo Xu },\ 822*416d8220SZaibo Xu .init = ctx_init,\ 823*416d8220SZaibo Xu .exit = ctx_exit,\ 824*416d8220SZaibo Xu .setkey = sec_set_key,\ 825*416d8220SZaibo Xu .decrypt = sec_skcipher_decrypt,\ 826*416d8220SZaibo Xu .encrypt = sec_skcipher_encrypt,\ 827*416d8220SZaibo Xu .min_keysize = sec_min_key_size,\ 828*416d8220SZaibo Xu .max_keysize = sec_max_key_size,\ 829*416d8220SZaibo Xu .ivsize = iv_size,\ 830*416d8220SZaibo Xu }, 831*416d8220SZaibo Xu 832*416d8220SZaibo Xu #define SEC_SKCIPHER_ALG(name, key_func, min_key_size, \ 833*416d8220SZaibo Xu max_key_size, blk_size, iv_size) \ 834*416d8220SZaibo Xu SEC_SKCIPHER_GEN_ALG(name, key_func, min_key_size, max_key_size, \ 835*416d8220SZaibo Xu sec_skcipher_ctx_init, sec_skcipher_ctx_exit, blk_size, iv_size) 836*416d8220SZaibo Xu 837*416d8220SZaibo Xu static struct skcipher_alg sec_algs[] = { 838*416d8220SZaibo Xu SEC_SKCIPHER_ALG("ecb(aes)", sec_setkey_aes_ecb, 839*416d8220SZaibo Xu AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE, 840*416d8220SZaibo Xu AES_BLOCK_SIZE, 0) 841*416d8220SZaibo Xu 842*416d8220SZaibo Xu SEC_SKCIPHER_ALG("cbc(aes)", sec_setkey_aes_cbc, 843*416d8220SZaibo Xu AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE, 844*416d8220SZaibo Xu AES_BLOCK_SIZE, AES_BLOCK_SIZE) 845*416d8220SZaibo Xu 846*416d8220SZaibo Xu SEC_SKCIPHER_ALG("xts(aes)", sec_setkey_aes_xts, 847*416d8220SZaibo Xu SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MAX_KEY_SIZE, 848*416d8220SZaibo Xu AES_BLOCK_SIZE, AES_BLOCK_SIZE) 849*416d8220SZaibo Xu 850*416d8220SZaibo Xu SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb, 851*416d8220SZaibo Xu SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, 852*416d8220SZaibo Xu DES3_EDE_BLOCK_SIZE, 0) 853*416d8220SZaibo Xu 854*416d8220SZaibo Xu SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc, 855*416d8220SZaibo Xu SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, 856*416d8220SZaibo Xu DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE) 857*416d8220SZaibo Xu 858*416d8220SZaibo Xu SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts, 859*416d8220SZaibo Xu SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MIN_KEY_SIZE, 860*416d8220SZaibo Xu AES_BLOCK_SIZE, AES_BLOCK_SIZE) 861*416d8220SZaibo Xu 862*416d8220SZaibo Xu SEC_SKCIPHER_ALG("cbc(sm4)", sec_setkey_sm4_cbc, 863*416d8220SZaibo Xu AES_MIN_KEY_SIZE, AES_MIN_KEY_SIZE, 864*416d8220SZaibo Xu AES_BLOCK_SIZE, AES_BLOCK_SIZE) 865*416d8220SZaibo Xu }; 866*416d8220SZaibo Xu 867*416d8220SZaibo Xu int sec_register_to_crypto(void) 868*416d8220SZaibo Xu { 869*416d8220SZaibo Xu int ret = 0; 870*416d8220SZaibo Xu 871*416d8220SZaibo Xu /* To avoid repeat register */ 872*416d8220SZaibo Xu mutex_lock(&sec_algs_lock); 873*416d8220SZaibo Xu if (++sec_active_devs == 1) 874*416d8220SZaibo Xu ret = crypto_register_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); 875*416d8220SZaibo Xu mutex_unlock(&sec_algs_lock); 876*416d8220SZaibo Xu 877*416d8220SZaibo Xu return ret; 878*416d8220SZaibo Xu } 879*416d8220SZaibo Xu 880*416d8220SZaibo Xu void sec_unregister_from_crypto(void) 881*416d8220SZaibo Xu { 882*416d8220SZaibo Xu mutex_lock(&sec_algs_lock); 883*416d8220SZaibo Xu if (--sec_active_devs == 0) 884*416d8220SZaibo Xu crypto_unregister_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); 885*416d8220SZaibo Xu mutex_unlock(&sec_algs_lock); 886*416d8220SZaibo Xu } 887