Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afc2dc13 authored by Tero Kristo's avatar Tero Kristo Committed by Herbert Xu
Browse files

crypto: omap-aes - use base omap crypto support library



Use the SG alignment APIs from the OMAP crypto support library instead
of using own implementations.

Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 9765e768
Loading
Loading
Loading
Loading
+28 −92
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#include <crypto/engine.h>
#include <crypto/internal/skcipher.h>

#include "omap-crypto.h"

#define DST_MAXBURST			4
#define DMA_MIN				(DST_MAXBURST * sizeof(u32))

@@ -98,6 +100,9 @@
#define FLAGS_FAST		BIT(5)
#define FLAGS_BUSY		BIT(6)

#define FLAGS_IN_DATA_ST_SHIFT	8
#define FLAGS_OUT_DATA_ST_SHIFT	10

#define AES_BLOCK_WORDS		(AES_BLOCK_SIZE >> 2)

struct omap_aes_ctx {
@@ -173,7 +178,6 @@ struct omap_aes_dev {
	struct scatterlist		in_sgl;
	struct scatterlist		out_sgl;
	struct scatterlist		*orig_out;
	int				sgs_copied;

	struct scatter_walk		in_walk;
	struct scatter_walk		out_walk;
@@ -385,20 +389,6 @@ static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
	dma_release_channel(dd->dma_lch_in);
}

static void sg_copy_buf(void *buf, struct scatterlist *sg,
			      unsigned int start, unsigned int nbytes, int out)
{
	struct scatter_walk walk;

	if (!nbytes)
		return;

	scatterwalk_start(&walk, sg);
	scatterwalk_advance(&walk, start);
	scatterwalk_copychunks(buf, &walk, nbytes, out);
	scatterwalk_done(&walk, out, 0);
}

static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
			      struct scatterlist *in_sg,
			      struct scatterlist *out_sg,
@@ -534,62 +524,6 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
	return 0;
}

static int omap_aes_check_aligned(struct scatterlist *sg, int total)
{
	int len = 0;

	if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
		return -EINVAL;

	while (sg) {
		if (!IS_ALIGNED(sg->offset, 4))
			return -1;
		if (!IS_ALIGNED(sg->length, AES_BLOCK_SIZE))
			return -1;

		len += sg->length;
		sg = sg_next(sg);
	}

	if (len != total)
		return -1;

	return 0;
}

static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
{
	void *buf_in, *buf_out;
	int pages, total;

	total = ALIGN(dd->total, AES_BLOCK_SIZE);
	pages = get_order(total);

	buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
	buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);

	if (!buf_in || !buf_out) {
		pr_err("Couldn't allocated pages for unaligned cases.\n");
		return -1;
	}

	dd->orig_out = dd->out_sg;

	sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0);

	sg_init_table(&dd->in_sgl, 1);
	sg_set_buf(&dd->in_sgl, buf_in, total);
	dd->in_sg = &dd->in_sgl;
	dd->in_sg_len = 1;

	sg_init_table(&dd->out_sgl, 1);
	sg_set_buf(&dd->out_sgl, buf_out, total);
	dd->out_sg = &dd->out_sgl;
	dd->out_sg_len = 1;

	return 0;
}

static int omap_aes_handle_queue(struct omap_aes_dev *dd,
				 struct ablkcipher_request *req)
{
@@ -606,6 +540,8 @@ static int omap_aes_prepare_req(struct crypto_engine *engine,
			crypto_ablkcipher_reqtfm(req));
	struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
	struct omap_aes_dev *dd = rctx->dd;
	int ret;
	u16 flags;

	if (!dd)
		return -ENODEV;
@@ -616,6 +552,23 @@ static int omap_aes_prepare_req(struct crypto_engine *engine,
	dd->total_save = req->nbytes;
	dd->in_sg = req->src;
	dd->out_sg = req->dst;
	dd->orig_out = req->dst;

	flags = OMAP_CRYPTO_COPY_DATA;
	if (req->src == req->dst)
		flags |= OMAP_CRYPTO_FORCE_COPY;

	ret = omap_crypto_align_sg(&dd->in_sg, dd->total, AES_BLOCK_SIZE,
				   &dd->in_sgl, flags,
				   FLAGS_IN_DATA_ST_SHIFT, &dd->flags);
	if (ret)
		return ret;

	ret = omap_crypto_align_sg(&dd->out_sg, dd->total, AES_BLOCK_SIZE,
				   &dd->out_sgl, 0,
				   FLAGS_OUT_DATA_ST_SHIFT, &dd->flags);
	if (ret)
		return ret;

	dd->in_sg_len = sg_nents_for_len(dd->in_sg, dd->total);
	if (dd->in_sg_len < 0)
@@ -625,15 +578,6 @@ static int omap_aes_prepare_req(struct crypto_engine *engine,
	if (dd->out_sg_len < 0)
		return dd->out_sg_len;

	if (omap_aes_check_aligned(dd->in_sg, dd->total) ||
	    omap_aes_check_aligned(dd->out_sg, dd->total)) {
		if (omap_aes_copy_sgs(dd))
			pr_err("Failed to copy SGs for unaligned cases\n");
		dd->sgs_copied = 1;
	} else {
		dd->sgs_copied = 0;
	}

	rctx->mode &= FLAGS_MODE_MASK;
	dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;

@@ -658,8 +602,6 @@ static int omap_aes_crypt_req(struct crypto_engine *engine,
static void omap_aes_done_task(unsigned long data)
{
	struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
	void *buf_in, *buf_out;
	int pages, len;

	pr_debug("enter done_task\n");

@@ -672,17 +614,11 @@ static void omap_aes_done_task(unsigned long data)
		omap_aes_crypt_dma_stop(dd);
	}

	if (dd->sgs_copied) {
		buf_in = sg_virt(&dd->in_sgl);
		buf_out = sg_virt(&dd->out_sgl);
	omap_crypto_cleanup(&dd->in_sgl, NULL, 0, dd->total_save,
			    FLAGS_IN_DATA_ST_SHIFT, dd->flags);

		sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1);

		len = ALIGN(dd->total_save, AES_BLOCK_SIZE);
		pages = get_order(len);
		free_pages((unsigned long)buf_in, pages);
		free_pages((unsigned long)buf_out, pages);
	}
	omap_crypto_cleanup(&dd->out_sgl, dd->orig_out, 0, dd->total_save,
			    FLAGS_OUT_DATA_ST_SHIFT, dd->flags);

	omap_aes_finish_req(dd, 0);