Commit e8acf011 authored by Corentin Labbe's avatar Corentin Labbe Committed by Herbert Xu
Browse files

crypto: ixp4xx - update IV after requests



Crypto selftests fail on ixp4xx since it do not update IV after skcipher
requests.

Fixes: 81bef015 ("crypto: ixp4xx - Hardware crypto support for IXP4xx CPUs")
Signed-off-by: default avatarCorentin Labbe <clabbe@baylibre.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 9395c58f
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ struct crypt_ctl {
struct ablk_ctx {
	struct buffer_desc *src;
	struct buffer_desc *dst;
	u8 iv[MAX_IVLEN];
	bool encrypt;
};

struct aead_ctx {
@@ -381,6 +383,20 @@ static void one_packet(dma_addr_t phys)
	case CTL_FLAG_PERFORM_ABLK: {
		struct skcipher_request *req = crypt->data.ablk_req;
		struct ablk_ctx *req_ctx = skcipher_request_ctx(req);
		struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
		unsigned int ivsize = crypto_skcipher_ivsize(tfm);
		unsigned int offset;

		if (ivsize > 0) {
			offset = req->cryptlen - ivsize;
			if (req_ctx->encrypt) {
				scatterwalk_map_and_copy(req->iv, req->dst,
							 offset, ivsize, 0);
			} else {
				memcpy(req->iv, req_ctx->iv, ivsize);
				memzero_explicit(req_ctx->iv, ivsize);
			}
		}

		if (req_ctx->dst) {
			free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
@@ -876,6 +892,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
	struct ablk_ctx *req_ctx = skcipher_request_ctx(req);
	struct buffer_desc src_hook;
	struct device *dev = &pdev->dev;
	unsigned int offset;
	gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
				GFP_KERNEL : GFP_ATOMIC;

@@ -885,6 +902,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
		return -EAGAIN;

	dir = encrypt ? &ctx->encrypt : &ctx->decrypt;
	req_ctx->encrypt = encrypt;

	crypt = get_crypt_desc();
	if (!crypt)
@@ -900,6 +918,10 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)

	BUG_ON(ivsize && !req->iv);
	memcpy(crypt->iv, req->iv, ivsize);
	if (ivsize > 0 && !encrypt) {
		offset = req->cryptlen - ivsize;
		scatterwalk_map_and_copy(req_ctx->iv, req->src, offset, ivsize, 0);
	}
	if (req->src != req->dst) {
		struct buffer_desc dst_hook;
		crypt->mode |= NPE_OP_NOT_IN_PLACE;