diff options
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r-- | drivers/crypto/caam/caamalg_qi.c | 120 |
1 files changed, 52 insertions, 68 deletions
diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index 8ae129f..26546db 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -58,27 +58,14 @@ static inline void append_dec_op1(u32 *desc, u32 type) } /* - * Wait for completion of class 1 key loading before allowing - * error propagation - */ -static inline void append_dec_shr_done(u32 *desc) -{ - u32 *jump_cmd; - - jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TEST_ALL); - set_jump_tgt_here(desc, jump_cmd); - append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD); -} - -/* * For aead functions, read payload and write payload, * both of which are specified in req->src and req->dst */ static inline void aead_append_src_dst(u32 *desc, u32 msg_type) { + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH); - append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); } /* @@ -158,9 +145,6 @@ static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx, append_key_aead(desc, ctx, keys_fit_inline); set_jump_tgt_here(desc, key_jump_cmd); - - /* Propagate errors from shared to job descriptor */ - append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD); } static int aead_set_sh_desc(struct crypto_aead *aead) @@ -168,7 +152,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead) struct aead_tfm *tfm = &aead->base.crt_aead; struct caam_ctx *ctx = crypto_aead_ctx(aead); bool keys_fit_inline; - u32 *key_jump_cmd, *jump_cmd; + u32 *key_jump_cmd; u32 geniv, moveiv; u32 *desc; @@ -251,11 +235,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead) append_key_aead(desc, ctx, keys_fit_inline); - /* Only propagate error immediately if shared */ - jump_cmd = append_jump(desc, JUMP_TEST_ALL); set_jump_tgt_here(desc, key_jump_cmd); - append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD); - set_jump_tgt_here(desc, jump_cmd); /* Class 2 operation */ append_operation(desc, ctx->class2_alg_type | @@ -284,7 +264,6 @@ static int aead_set_sh_desc(struct crypto_aead *aead) /* Load ICV */ append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); - append_dec_shr_done(desc); #ifdef DEBUG print_hex_dump(KERN_ERR, "aead dec shdesc@" @@ -971,7 +950,7 @@ static void aead_unmap(struct device *dev, edesc->qm_sg_dma, edesc->qm_sg_bytes); } -static inline void aead_done(struct caam_drv_req *drv_req, u32 status) +static void aead_done(struct caam_drv_req *drv_req, u32 status) { struct device *qidev; struct aead_edesc *edesc; @@ -982,7 +961,7 @@ static inline void aead_done(struct caam_drv_req *drv_req, u32 status) qidev = caam_ctx->qidev; - if (status) { + if (unlikely(status)) { caam_jr_strstatus(qidev, status); ecode = -EIO; } @@ -1074,8 +1053,7 @@ out: * allocate and map the aead extended descriptor */ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, - bool *all_contig_ptr, bool encrypt, - bool strip_icv) + bool encrypt, bool strip_icv) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct caam_ctx *ctx = crypto_aead_ctx(aead); @@ -1094,12 +1072,20 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; struct qm_sg_entry *sg_table, *fd_sgt; struct caam_drv_req *drv_req; + bool src_is_dst = true; assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); - if (unlikely(req->dst != req->src)) { + if (likely(req->dst == req->src)) { + src_nents = sg_count(req->src, + req->cryptlen + + (encrypt ? authsize : 0), + &src_chained); + sgc = dma_map_sg_chained(qidev, req->src, src_nents ? : 1, + DMA_BIDIRECTIONAL, src_chained); + } else { int extralen; - + src_is_dst = false; src_nents = sg_count(req->src, req->cryptlen, &src_chained); if (encrypt) @@ -1108,25 +1094,17 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, extralen = strip_icv ? (-authsize) : 0; dst_nents = sg_count(req->dst, req->cryptlen + extralen, &dst_chained); - } else { - src_nents = sg_count(req->src, - req->cryptlen + - (encrypt ? authsize : 0), - &src_chained); - } - sgc = dma_map_sg_chained(qidev, req->assoc, assoc_nents ? : 1, - DMA_TO_DEVICE, assoc_chained); - if (likely(req->src == req->dst)) { - sgc = dma_map_sg_chained(qidev, req->src, src_nents ? : 1, - DMA_BIDIRECTIONAL, src_chained); - } else { sgc = dma_map_sg_chained(qidev, req->src, src_nents ? : 1, DMA_TO_DEVICE, src_chained); sgc = dma_map_sg_chained(qidev, req->dst, dst_nents ? : 1, DMA_FROM_DEVICE, dst_chained); + } + sgc = dma_map_sg_chained(qidev, req->assoc, assoc_nents ? : 1, + DMA_TO_DEVICE, assoc_chained); + /* Check if data are contiguous */ iv_dma = dma_map_single(qidev, req->iv, ivsize, DMA_TO_DEVICE); if (assoc_nents || @@ -1167,8 +1145,6 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, edesc->qm_sg_dma = qm_sg_dma; edesc->qm_sg_bytes = qm_sg_bytes; - *all_contig_ptr = all_contig; - fd_sgt[0].final = 0; fd_sgt[0].__reserved2 = 0; fd_sgt[0].bpid = 0; @@ -1204,7 +1180,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, sg_to_qm_sg_last(req->dst, dst_nents, sg_table + qm_sg_index, 0); - if (req->dst == req->src) { + if (likely(src_is_dst)) { if (src_nents <= 1) { fd_sgt[0].addr = sg_dma_address(req->src); fd_sgt[0].extension = 0; @@ -1273,7 +1249,6 @@ static int aead_encrypt(struct aead_request *req) struct device *qidev = ctx->qidev; struct caam_drv_ctx *drv_ctx; struct caam_drv_req *drv_req; - bool all_contig; int ret; drv_ctx = get_drv_ctx(ctx, ENCRYPT); @@ -1284,7 +1259,7 @@ static int aead_encrypt(struct aead_request *req) return -EAGAIN; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, &all_contig, true, true); + edesc = aead_edesc_alloc(req, true, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1316,7 +1291,6 @@ static int aead_decrypt(struct aead_request *req) struct device *qidev = ctx->qidev; struct caam_drv_ctx *drv_ctx; struct caam_drv_req *drv_req; - bool all_contig; int ret = 0; drv_ctx = get_drv_ctx(ctx, DECRYPT); @@ -1327,7 +1301,7 @@ static int aead_decrypt(struct aead_request *req) return -EAGAIN; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, &all_contig, false, true); + edesc = aead_edesc_alloc(req, false, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1359,7 +1333,6 @@ static int tls_encrypt(struct aead_request *req) struct device *qidev = ctx->qidev; struct caam_drv_ctx *drv_ctx; struct caam_drv_req *drv_req; - bool all_contig; int ret; unsigned int blocksize = crypto_aead_blocksize(aead); unsigned int padsize; @@ -1380,7 +1353,7 @@ static int tls_encrypt(struct aead_request *req) * ctx->authsize is temporary set to include also padlen */ ctx->authsize += padsize; - edesc = aead_edesc_alloc(req, &all_contig, true, true); + edesc = aead_edesc_alloc(req, true, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); ctx->authsize -= padsize; @@ -1413,7 +1386,6 @@ static int tls_decrypt(struct aead_request *req) struct device *qidev = ctx->qidev; struct caam_drv_ctx *drv_ctx; struct caam_drv_req *drv_req; - bool all_contig; int ret = 0; drv_ctx = get_drv_ctx(ctx, DECRYPT); @@ -1431,7 +1403,7 @@ static int tls_decrypt(struct aead_request *req) * checks padding), req->dst has to be big enough to hold payloadlen + * padlen + icvlen. */ - edesc = aead_edesc_alloc(req, &all_contig, false, false); + edesc = aead_edesc_alloc(req, false, false); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1462,7 +1434,7 @@ static int tls_decrypt(struct aead_request *req) * allocate and map the aead extended descriptor for aead givencrypt */ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request - *greq, u32 *contig_ptr) + *greq) { struct aead_request *req = &greq->areq; struct crypto_aead *aead = crypto_aead_reqtfm(req); @@ -1482,19 +1454,22 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request struct qm_sg_entry *sg_table, *fd_sgt; struct caam_drv_req *drv_req; + bool src_is_dst = true; + assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); src_nents = sg_count(req->src, req->cryptlen, &src_chained); - - if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize, - &dst_chained); - sgc = dma_map_sg_chained(qidev, req->assoc, assoc_nents ? : 1, DMA_TO_DEVICE, assoc_chained); + if (likely(req->src == req->dst)) { sgc = dma_map_sg_chained(qidev, req->src, src_nents ? : 1, DMA_BIDIRECTIONAL, src_chained); } else { + src_is_dst = false; + + dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize, + &dst_chained); + sgc = dma_map_sg_chained(qidev, req->src, src_nents ? : 1, DMA_TO_DEVICE, src_chained); sgc = dma_map_sg_chained(qidev, req->dst, dst_nents ? : 1, @@ -1512,7 +1487,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request if (dst_nents || iv_dma + ivsize != sg_dma_address(req->dst)) contig &= ~GIV_DST_CONTIG; - if (unlikely(req->src != req->dst)) { + if (unlikely(!src_is_dst)) { dst_nents = dst_nents ? : 1; qm_sg_ents += 1; } @@ -1521,7 +1496,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; qm_sg_ents += assoc_nents + 1 + src_nents; - if (likely(req->src == req->dst)) + if (likely(src_is_dst)) contig &= ~GIV_DST_CONTIG; } @@ -1554,10 +1529,19 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request edesc->qm_sg_bytes = qm_sg_bytes; edesc->qm_sg_dma = qm_sg_dma; - *contig_ptr = contig; + fd_sgt[0].final = 0; + fd_sgt[0].extension = 0; + fd_sgt[0].__reserved2 = 0; + fd_sgt[0].bpid = 0; + fd_sgt[0].__reserved3 = 0; + fd_sgt[0].offset = 0; - memset(&fd_sgt[0], 0, 2 * sizeof(fd_sgt[0])); fd_sgt[1].final = 1; + fd_sgt[1].extension = 0; + fd_sgt[1].__reserved2 = 0; + fd_sgt[1].bpid = 0; + fd_sgt[1].__reserved3 = 0; + fd_sgt[1].offset = 0; qm_sg_index = 0; if (unlikely(!(contig & GIV_SRC_CONTIG))) { @@ -1582,7 +1566,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request fd_sgt[1].addr = sg_dma_address(req->assoc); } - if (unlikely(req->src != req->dst && !(contig & GIV_DST_CONTIG))) { + if (unlikely(!src_is_dst && !(contig & GIV_DST_CONTIG))) { fd_sgt[0].addr = qm_sg_dma + (sizeof(struct qm_sg_entry) * qm_sg_index); fd_sgt[0].extension = 1; @@ -1592,7 +1576,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request sg_to_qm_sg_last(req->dst, dst_nents, sg_table + qm_sg_index, 0); } else { - if (req->src == req->dst && !(contig & GIV_DST_CONTIG)) { + if (src_is_dst && !(contig & GIV_DST_CONTIG)) { fd_sgt[0].extension = 1; fd_sgt[0].addr = edesc->qm_sg_dma + sizeof(struct qm_sg_entry) * @@ -1615,7 +1599,6 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq) struct caam_drv_req *drv_req; int ivsize = crypto_aead_ivsize(aead); struct aead_edesc *edesc; - u32 contig; int ret; drv_ctx = get_drv_ctx(ctx, GIVENCRYPT); @@ -1626,7 +1609,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq) return -EAGAIN; /* allocate extended descriptor */ - edesc = aead_giv_edesc_alloc(areq, &contig); + edesc = aead_giv_edesc_alloc(areq); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -2119,8 +2102,9 @@ static int caam_cra_init(struct crypto_tfm *tfm) if (op_id < ARRAY_SIZE(digest_size)) { ctx->authsize = digest_size[op_id]; } else { - dev_err(ctx->jrdev, "incorrect op_id %d; must be less than %d\n", - op_id, ARRAY_SIZE(digest_size)); + dev_err(ctx->jrdev, + "incorrect op_id %d; must be less than %zu\n", + op_id, ARRAY_SIZE(digest_size)); caam_jr_free(ctx->jrdev); return -EINVAL; } |